Bash Videodateien zusammenfügen per Bash/ffmpeg

meph!sto

Vice Admiral
Registriert
Nov. 2003
Beiträge
6.284
Hi,
vorweg: ich habe vom Programmieren und/oder Shell-Skripten, wenig bis keine Ahnung. Daher bitte ich um Nachsicht.

Ich habe in der Wohnung 2 YiHack Überwachungskameras, die bei Abwesenheit anspringen.
Aufzeichnungen werden mittels Sound und/oder Bewegung getriggert.
Diese Aufzeichnungen landen in einem Ordner auf meinem NAS.

Aufzeichnungen einer jeden Stunde, werden in einem neuen Ordner angelegt, mit nachfolgender Syntax:
2022Y06M14D12H
Y = 2022
M = 06
D = 14
H = 12

In diesem Ordner befinden sich immer 1min Lange Aufnahmen. Leider haben meine Recherchen nichts ergeben, ich hatte nämlich die Hoffnung dass die Kamera 1 Datei erzeugt statt x Dateien, mit 1min Länge.
z.B.
02M42S18.mp4
03M00S60.mp4
04M21S39.mp4

Meine Idee war nun ein Skript, das in jeden einzelnen Ordner mit o.g. Syntax reinwechselt, dort alle vorhandenen *.mp4 in zeitlich korrekter Reihenfolge zusammenfügt. Sodass ich am Ende 1 Datei habe, die (z.B.) 10min lang ist, statt 10 Dateien mit jeweils 1min.

Als Befehl, habe ich bereits
Code:
ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4
gefunden.
nun müsste ich nur in einer For-Schleife durch alle Unterordner in einem Verzeichnis gehen, dort alle vorhandenen *.mp4 in eine /tmp/files.txt schreiben lassen und diese dann mittels o.g. Befehl zusammfügen.

Wie geht sowas ?
Das ganze würde ich auf einem RPi3B+ laufen lassen und das NAS als Netzlaufwerk mappen. Ich möchte das zusammenfügen nicht durch das NAS erledigen lassen.

Alle Aufzeichnungen aus dem Wohnzimmer landen hier: /home/pi/YiCamLV (der entsprechende Ordner des NAS ist hier gemapped)
Alle Aufzeichnungen aus dem Wohnzimmer landen hier: /home/pi/YiCamOFFICE (der entsprechende Ordner des NAS ist hier gemapped)

Ich versuche mal in Worte zu fassen was ich vorhabe:
Code:
PFAD1 = /home/pi/YiCamLV
PFAD2 = /home/pi/YiCamOFFICE

for d in $PFAD1/ ; do
    if [$(ls *.mp4| wc -l) > 1]  #nur durchführen wenn mehr als 1 mp4-Datei vorhanden
    then
       for f in *.mp4; do echo "file '$PWD/$f'" >> /tmp/files.txt; done #alle mp4-Dateien auflisten
       var = $(ls -1tr | head -n 1)
       var4 = $(var:0:4)
       ffmpeg -f concat -safe 0 -i /tmp/files.txt -c copy $var4.mp4 #zusammenfügen
    fi
xargs -a /tmp/files.txt -d'\n' rm #ursprüngliche Dateien löschen
rm /tmp/files.txt #cleanup
done

Danke
 
Zuletzt bearbeitet:
meph!sto schrieb:
Als Befehl, habe ich bereits
Code:
ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4
gefunden.
nun müsste ich nur in einer For-Schleife durch alle Unterordner in einem Verzeichnis gehen, dort alle vorhandenen *.mp4 in eine /tmp/files.txt schreiben lassen und diese dann mittels o.g. Befehl zusammfügen.

find /foo/bar -type f -name '*.mp4' > files.txt

Und noch:

$foo=´ head -n 1 files.txt | | sed -E '1,$ s/(^....).*$/\1/'´

Beispiel:

$ echo 123456789 | sed -E '1,$ s/(^....)(.*$)/\2\1/'
567891234
$

basename(1) könnte auch noch helfen.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: meph!sto und madmax2010
Danke für den Tip,
die Dateiliste lege ich mir mit
Code:
 ls -d $PWD/* > /tmp/files.txt #alle mp4-Dateien auflisten
samt Gesamtpfadangabe ab.

Leider bekomme ich mit o.g. Befehl folgenden ffmpeg Fehler:
Code:
[concat @ 0xed8d20] Line 1: unknown keyword '/home/pi/YiCamOFFICE/2022Y06M12D12H/02M30S30.mp4'
/tmp/files.txt: Invalid data found when processing input
 
Ok,
danke für den Hinweis.

Liste erzeugen: check
Dateien mergen: check

Fehlt noch das umbenennen mit den ersten 4 chars der ältesten Datei im Verzeichnis.
Mit
Code:
 var=$(ls -1tr | head -n 1)
erhalte ich schon mal die älteste Datei in var.

Mein bisheriger Stand (der soweit ich bisher prüfen konnte, auch funktioniert):
Code:
declare -a CAMERAS=("/home/pi/YiCamLV/" "/home/pi/YiCamOFFICE/")

for i in "${CAMERAS[@]}"
do
        cd $i
        for dir in */; do
                #echo "$dir"
                cd $i/$dir
                COUNT_FILES=$(ls *.mp4 | wc -l)
                #echo $COUNT_FILES
                if [ $COUNT_FILES -gt 1 ];  #nur durchführen wenn mehr als 1 mp4-Datei vorhanden
                then
                        rm /tmp/files.txt #cleanup
                        rm /tmp/del_files.txt #cleanup
                        #pwd
                        ls -d $PWD/* > /tmp/del_files.txt #dateien zum löschen listen
                        #cat /tmp/del_files.txt
                        for f in *.mp4; do echo "file '$PWD/$f'" >> /tmp/files.txt; done #alle mp4-Dateien auflisten
                        #cat /tmp/files.txt
                        var=$(ls -1tr | head -n 1) #älteste Datei finden und Namen in var schreiben
                        #echo $var
                        var5=${var:0:5} #ersten 5 chars nutzen
                        #echo $var5
                        ffmpeg -f concat -safe 0 -i /tmp/files.txt -c copy $var5.mp4 #zusammenfügen
                fi
                xargs -a /tmp/del_files.txt -d'\n' rm #ursprüngliche Dateien löschen
                rm /tmp/files.txt #cleanup
                rm /tmp/del_files.txt #cleanup
        done
done
 
Zuletzt bearbeitet:
Zurück
Oben