Inleiding
In een nostalgische bui ging ik dezer dagen op zoek naar een televisieserie uit mijn jeugd: Batman (1966). Op Youtube vond ik een playlist met de naam "The Complete Series". Het waren 41 fragmenten van ongeveer 5 minuten per stuk. Na het eerste fragment begon automatisch het tweede, dat daarop aansloot: mooi!
Maar een hele reeks fragmenten kijken, met na elk fragment een scherm vol Youtube-aanbevelingen; al dan niet met minuten lang reclame rondom? Nee, dat gaan we anders doen…
yt-dlp
De eenvoudigste manier om video's van (onder andere) Youtube te downloaden is met behulp van yt-dlp, de opvolger van youtube-dl. Eerstgenoemde project wordt actief doorontwikkeld en continu up-to-date gehouden. De bediening is nagenoeg gelijk aan de voorganger. Met één simpel commando vonden de clips hun weg naar mijn harde schijf:
yt-dlp "https://www.youtube.com/watch?v=..."
ffmpeg
Toen wilde ik de fragmenten graag geautomatiseerd samenvoegen, achter elkaar plakken,
of in het Engels: to concatenate. Ik besloot mijn favoriete audio-video-tool
om hulp te vragen en zie daar; ffmpeg
biedt een filter om precies deze functie
uit te voeren.
ffmpeg -f concat -i list-of-files.txt output.webm
Het programma verwachtte dan wel een lijst van de samen te voegen video's
(list-of-files.txt
) in een specifiek formaat:
file 'video1.webm'
file 'video2.webm'
file 'video3.webm'
...
Goochelen met bestandsnamen
Natuurlijk is het leven niet zo eenvoudig als het op het eerste oog lijkt. In
deze specifieke playlist hadden de clips geen volgnummer, maar slechts een titel
die geen enkel verband hield met de volgorde in de reeks. Hoe zou ik nu het
lijstje voor ffmpeg
kunnen samenstellen? De clips waren wel in volgorde
gedownload en op mijn harde schijf opgeslagen. ls
to the rescue!.
Maar er was nog een probleem: de apostrofs in de bestandsnamen; ffmpeg
zou
daar beslist over gaan klagen bij het uitlezen van de lijst. Oké, dan gooien we
er nog wat sed
-magie tegenaan:
# list all webm-files, sort in reverse by birth time
# pipe to sed, escaping all apostrophes "'" with "'\''"
# prepend "file '" to all filenames
# append "'" to all filenames
ls --reverse --time=birth *.webm | sed \
-e "s/'/'\\\\''/g" \
-e "s/^/file '/" \
-e "s/$/'/" \
> list-of-files.txt
Finale
Met dit commando kreeg ik een mooi lijstje van bestandsnamen voor ffmpeg
. Toen
ik het uitvoerde, klaagde het programma nog één laatste keer: de clips hadden
'onveilige' tekens in de bestandsnamen, met name het uitroepteken (!
). Omdat
dat in dit geval geen bezwaar was, besloot ik de waarschuwing uit te schakelen
met de -safe
optie – zie ook de ffmpeg documentatie.
ffmpeg -f concat -safe 0 -i list-of-files.txt -c copy output.webm;
Klaar!