wie konvertiere ich in einem Shell-Skript eine Zahl in das Zeitformat?

wie konvertiere ich in einem Shell-Skript eine Zahl in das Zeitformat?

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 forwird 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 dateBefehl 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

dateBefehl erklärt

dateMit einem -dFlag 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 -usoll 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 dateBefehl 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, cutaber trda 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 echoder ffmpegZeile 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;

verwandte Informationen