ffmpeg und find verheiraten

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
reox
Beiträge: 2460
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

ffmpeg und find verheiraten

Beitrag von reox » 22.01.2018 18:19:33

Ich hatte die Aufgabe ca 400 Videos in unterschiedlichen Ordnern zu konvertieren und in einem Ausgabeordner zu sammeln.
Da dachte ich gleich an find und ffmpeg ;)
Allerdings währte die Freude nicht so lang, denn irgendwie klappte zwar die Schleife mit dem find aufruf aber nicht wenn ich ffmpeg mit dazunahm.
Ich hab dann herausgefunden, dass man ffmpeg explitzit input von /dev/null pipen muss, da es sonst von stdin ließt und die schleife zerstört.
Also schaut das script jetzt in etwa so aus:

Code: Alles auswählen

while IFS= read -r -d '' MOI
do
    MOD="${MOI%.MOI}.MOD"
    D=$(exiftool -DateTimeOriginal -args "$MOI" | cut -d "=" -f 2 | tr ': ' '-_' | cut -d '.' -f 1)
    NNAME="converted/$D.mp4"
    ffmpeg -f mpeg -i "$MOD" -vcodec h264_nvenc -b:v 10M -deinterlace -aspect 16:9 -acodec aac -ab 192k -ar 44100 "$NNAME" </dev/null
done < <(find "$(pwd)" -name "*.MOI" -print0)
Die Frage ist nun, gibt es eine bessere Variante? Ich hätte gerne ein robustes Konstrukt für die while Schleife aus find, bei der egal ist was mit stdin innerhalb der Schleife passiert.
Das jetztige Konstrukt ist die Empfehlung von shellcheck: https://github.com/koalaman/shellcheck/wiki/SC2044

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: ffmpeg und find verheiraten

Beitrag von Meillo » 22.01.2018 18:41:03

Du koenntest das ffmpeg einfach in eine Shellfunktion wrappen, die nichts tut als Stdin umzubiegen und alle Argumente weiterzureichen. Dann kannst du diese Wrapperfunktion so nutzen wie du ffmpeg nutzen wuerdest, wenn es nicht dieses Stdin-``Problem'' haette. ;-)
Use ed once in a while!

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: ffmpeg und find verheiraten

Beitrag von scientific » 22.01.2018 19:49:46

Oder das ganze mit at resp. batch in den Hintergrund schicken. Dann wird der nächste job erst gestartet, wenn der Load klein genug ist.
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

reox
Beiträge: 2460
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: ffmpeg und find verheiraten

Beitrag von reox » 24.01.2018 12:26:37

Meillo hat geschrieben: ↑ zum Beitrag ↑
22.01.2018 18:41:03
Du koenntest das ffmpeg einfach in eine Shellfunktion wrappen, die nichts tut als Stdin umzubiegen und alle Argumente weiterzureichen. Dann kannst du diese Wrapperfunktion so nutzen wie du ffmpeg nutzen wuerdest, wenn es nicht dieses Stdin-``Problem'' haette. ;-)
Ok das in eine funktion packen macht Sinn. Gibt es sowas wie `man 2 dup` auch für die shell oder würdest du dann einfach den Aufruf von ffmpeg mit </dev/null versehen so wie ich das gemacht habe?
scientific hat geschrieben: ↑ zum Beitrag ↑
22.01.2018 19:49:46
Oder das ganze mit at resp. batch in den Hintergrund schicken. Dann wird der nächste job erst gestartet, wenn der Load klein genug ist.
Das versteh ich jetzt eher weniger. Was wird dadurch gelöst? Hast du vllt ein Beispiel, ich steh da gerade am Schlauch...

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: ffmpeg und find verheiraten

Beitrag von Meillo » 24.01.2018 12:48:02

reox hat geschrieben: ↑ zum Beitrag ↑
24.01.2018 12:26:37
Gibt es sowas wie `man 2 dup` auch für die shell oder würdest du dann einfach den Aufruf von ffmpeg mit </dev/null versehen so wie ich das gemacht habe?
Was spricht gegen </dev/null ?

Ich sehe gerade nicht in welcher Weise dup(2) helfen wuerde bei dem was du erreichen willst.


Btw: So wie ich das sehe ist ``close(0); dup(17);'' in C aequivalent zu ``<&17'' in der Shell. Und falls du Stdin nur schliessen willst, dann kannst du auch ``<&-'' verwenden (aequivalent zu ``close(0)'' in C), statt ``</dev/null'' (wo einmal zu lesen versucht wird und man sofort an EOF ist). Siehe: http://pubs.opengroup.org/onlinepubs/96 ... g_18_07_05
Use ed once in a while!

Benutzeravatar
Lord_Carlos
Beiträge: 5578
Registriert: 30.04.2006 17:58:52
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Dänemark

Re: ffmpeg und find verheiraten

Beitrag von Lord_Carlos » 24.01.2018 12:56:55

Ich habe das hier gefunden, vielleicht du auch schon? https://unix.stackexchange.com/a/36411
Liest sich so als wenn der wuesste wovon er spricht, also nehme ich mal an das nichts gegen < /dev/null spricht.

Code: Alles auswählen

╔═╗┬ ┬┌─┐┌┬┐┌─┐┌┬┐╔╦╗
╚═╗└┬┘└─┐ │ ├┤ │││ ║║
╚═╝ ┴ └─┘ ┴ └─┘┴ ┴═╩╝ rockt das Forum!

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: ffmpeg und find verheiraten

Beitrag von scientific » 24.01.2018 14:06:16

Ich mache das regelmäßig, dass ich Videos in ein Eingangsverzeichnis kippe. Dann lasse ich eine Schleife über alle Videos laufen und extrahiere die Audiospuren mit ffmpeg daraus in ein Zielverzeichnis. Und ich pipe die ffmpeg-Commands in batch in der schleife.

Funktioniert tadellos. Es werden im Hintergrund alle Videos nacheinander abgearbeitet - solange die Load gering genug ist.
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

reox
Beiträge: 2460
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: ffmpeg und find verheiraten

Beitrag von reox » 24.01.2018 14:45:40

Der im stackoverflow verlinkte link gibt einen ganz guten tipp: http://mywiki.wooledge.org/BashFAQ/089

Code: Alles auswählen

while read -r line <&3; do
  ...
done 3<file
einfach den FD von der schleife umlenken. So muss man im Schleifenkörper nix ändern.
Ich glaube das gefällt mir bisher am besten.

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: ffmpeg und find verheiraten

Beitrag von scientific » 24.01.2018 17:03:48

In meiner Schleife mit while hab ich:

Code: Alles auswählen

OUT="/Pfad/zu/deinem/Ziel Verzeichnis/"
while read VIDEO_IN; do
	VIDEO_OUT=$(echo "$VIDEO_IN"|sed -e 's/[ ()]/_/g' -e 's/_-_/-/g')
	FILENAME=$(basename "${VIDEO_OUT%.*}")
	echo "ffmpeg -i \"$VIDEO_IN\" -vn -ab 128K -ar 44100  -acodec libvorbis \"$OUT$FILENAME\".ogg 2>&1 "|batch
done
um den Audiostrem aus einem Video zu extrahieren und in ogg/vorbis zu konvertieren.
Installiert muss dazu Debianat sein!

batch kommt aus dem Paket at.

lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

reox
Beiträge: 2460
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: ffmpeg und find verheiraten

Beitrag von reox » 24.01.2018 17:11:40

sogesehen braucht es nichtmal at! du könntest auch sequentiell abarbeiten:

Code: Alles auswählen

OUT="/Pfad/zu/deinem/Ziel Verzeichnis/"
while read VIDEO_IN; do
	VIDEO_OUT=$(echo "$VIDEO_IN"|sed -e 's/[ ()]/_/g' -e 's/_-_/-/g')
	FILENAME=$(basename "${VIDEO_OUT%.*}")
	echo "ffmpeg -i \"$VIDEO_IN\" -vn -ab 128K -ar 44100  -acodec libvorbis \"$OUT$FILENAME\".ogg 2>&1 " >> tmpfile
done
chmod a+x tmpfile
./tmpfile
die ffmpeg befehle zu speichern ist evt gar keine schlechte idee.

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: ffmpeg und find verheiraten

Beitrag von scientific » 24.01.2018 17:29:41

Das stimmt prinzipiell.

Wenn eine größere Menge an größeren Videos verarbeitet werden sollen, dann kann man es damit aber schön in den Hintergrund verlagern, und es werden sogar zwei oder drei Videos gleichzeitig verarbeitet, wenn es der Load hergibt.
Andererseits setzt die Konvertierung aus (es wird kein neues Video gestartet), wenn man zwischendrin eine andere aufwändige Aufgabe startet.

batch/at bietet hier größeren Komfort an.

Ich muss mein Skript noch an meine neue notifikation anpassen... Dann poste ich alkes gerne hier.
Denn eigentlich rufe ich das Skript über incrond auf. Dieser überwacht das Eingangsverzeichnis und startet für jedes neue File, dass uch dort ablege mittels diesem Skript automatisch im Hintergrund eine Konvertierung. Deshalb ist auch at so wichtig, sonst legst du dir nämlich den Rechner lahm...
Und wenn es fertig konvertiert hat, gibts per dbus eine Benachrichtigung auf den Desktop!

Lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Antworten