Ich möchte ein Video in Abschnitte von etwa 10 Minuten schneiden, wie diesen.
ffmpeg -i video.mp4 -ss 00:00:00 -t 00:10:00 -c copy 01.mp4
ffmpeg -i video.mp4 -ss 00:10:00 -t 00:10:00 -c copy 02.mp4
ffmpeg -i video.mp4 -ss 00:20:00 -t 00:10:00 -c copy 03.mp4
Damit for
wird es so sein.
for i in `seq 10`; do ffmpeg -i video.mp4 -ss 00:${i}0:00 -t 00:10:00 -c copy ${i].mp4; done;
Aber es funktioniert nur, wenn die Dauer unter einer Stunde liegt. Wie kann ich in der Bash-Shell Zahlen in das Zeitformat konvertieren?
Antwort1
BASH ist für dieses Problem nicht so schlecht. Sie müssen nur den sehr leistungsstarken, aber wenig genutzten date
Befehl verwenden.
for i in {1..10}; do
hrmin=$(date -u -d@$(($i * 10 * 60)) +"%H:%M")
outfile=${hrmin/:/-}.mp4
ffmpeg -i video.mp4 -ss ${hrmin}:00 -t 00:10:00 -c copy ${outfile}
done
date
Befehl erklärt
date
Mit einem -d
Flag können Sie festlegenwelcheDatum, das angezeigt werden soll (anstelle des aktuellen Datums und der aktuellen Uhrzeit, was die Standardeinstellung ist). In diesem Fall stelle ich es auf eine UNIX-Zeit ein, indem ich das @
Symbol vor eine Ganzzahl setze. Die Ganzzahl ist in diesem Fall die Zeit in Zehn-Minuten-Schritten (berechnet durch den in BASH integrierten Rechner: $((...))
).
Das +
Symbol zeigt an date
, dass Sie ein Format für die Anzeige der Ergebnisse festlegen möchten. In unserem Fall interessieren uns nur die Stunden ( %H
) und Minuten ( %M
).
Und schließlich -u
soll die Zeit als UTC-Zeit statt als Ortszeit angezeigt werden. Das ist in diesem Fall wichtig, weil wir die Zeit als UTC angegeben haben, als wir die UNIX-Zeit angegeben haben (UNIX-Zeit ist immer UTC). Die Zahlen würden höchstwahrscheinlich nicht bei 0 beginnen, wenn Sie nicht angeben würden -u
.
BASH-Variablensubstitution erklärt
Der date
Befehl gab uns genau das, was wir brauchten. Aber Doppelpunkte in einem Dateinamen können problematisch/nicht standardmäßig sein. Also ersetzen wir das ':' durch ein '-'. Dies kann mit dem Befehl oder erledigt werden sed
, cut
aber tr
da dies eine so einfache Aufgabe ist, warum sollte man eine neue Subshell starten, wenn BASH dies tun kann?
Hier verwenden wir die einfache Ausdruckssubstitution von BASH. Dazu muss die Variable in geschweifte Klammern ( ${hrmin}
) eingeschlossen werden und dann die Standard-Schrägstrichnotation verwendet werden. Die erste Zeichenfolge nach dem ersten Schrägstrich ist das Suchmuster. Die zweite Zeichenfolge nach dem zweiten Schrägstrich ist die Ersetzung.
BASH-Variablensubstitution und mehr finden Sie unterhttp://tldp.org/LDP/abs/html/parameter-substitution.html.
Antwort2
Es ist etwas komplizierter, aber Sie können es in Bash ganz einfach tun. Das folgende Beispiel ist für ein 2-stündiges Video, Sie können die Grenzen ( n<=11
) entsprechend festlegen:
k=0;
i=00;
for ((n=0;n<=11;n++)); do
if [ $i -ge 60 ]; then
let k++; i=00;
fi;
ffmpeg -i video.mp4 -ss 0$k:$i:00 -t 00:10:00 -c copy $k$i.mp4;
let i+=10;
done
Sie können sehen, was dies bewirkt, indem Sie echo
der ffmpeg
Zeile ein hinzufügen:
echo "ffmpeg -i video.mp4 -ss 0$k:$i:00 -t 00:10:00 -c copy $k$i.mp4";
Das Ergebnis lautet:
ffmpeg -i video.mp4 -ss 00:00:00 -t 00:10:00 -c copy 000.mp4
ffmpeg -i video.mp4 -ss 00:10:00 -t 00:10:00 -c copy 010.mp4
ffmpeg -i video.mp4 -ss 00:20:00 -t 00:10:00 -c copy 020.mp4
ffmpeg -i video.mp4 -ss 00:30:00 -t 00:10:00 -c copy 030.mp4
ffmpeg -i video.mp4 -ss 00:40:00 -t 00:10:00 -c copy 040.mp4
ffmpeg -i video.mp4 -ss 00:50:00 -t 00:10:00 -c copy 050.mp4
ffmpeg -i video.mp4 -ss 01:00:00 -t 00:10:00 -c copy 100.mp4
ffmpeg -i video.mp4 -ss 01:10:00 -t 00:10:00 -c copy 110.mp4
ffmpeg -i video.mp4 -ss 01:20:00 -t 00:10:00 -c copy 120.mp4
ffmpeg -i video.mp4 -ss 01:30:00 -t 00:10:00 -c copy 130.mp4
ffmpeg -i video.mp4 -ss 01:40:00 -t 00:10:00 -c copy 140.mp4
ffmpeg -i video.mp4 -ss 01:50:00 -t 00:10:00 -c copy 150.mp4
Antwort3
Es ist einfache Mathematik: Die Stundenangabe ist $((i%3600)
, die Minuten sind $((i/60%60))
, die Sekunden sind $((i%60))
. Um bei Bedarf eine führende Null hinzuzufügen, können Sie einfach 100 hinzufügen und dann die führende entfernen 1
. Machen Sie dasselbe mit dem Dateinamen, wenn Sie führende Nullen vermeiden möchten.
for i in $(seq 10); do
minutes=$((i / 60 % 60 + 100)); minutes=${minutes#1}
seconds=$((i%60)); seconds=${seconds#1}
i=$((i+100)); i=${i#1}
ffmpeg -i video.mp4 -ss $((i%3600):$minutes:$seconds -t 00:10:00 -c copy ${i}.mp4
done
Antwort4
Ich habe festgestellt, dass ffmpeg als Zeitstempelformat nicht nur [HH:MM:SS], sondern auch einfache Sekunden akzeptiert.
https://trac.ffmpeg.org/wiki/Seeking%20with%20FFmpeg
Also kann ich so schreiben.
for i in `seq 10`; do ffmpeg -i video.mp4 -ss $((i*10*60)) -t 00:10:00 -c copy ${i].mp4; done;