Ich habe eine Liste von .ts
Dateien:
out1.ts ... out749.ts out8159.ts out8818.ts
Wie kann ich die Gesamtdauer (Laufzeit) all dieser Dateien ermitteln?
shell-script
video
k961
quelle
quelle
Antworten:
Ich habe keine
.ts
hier, aber das funktioniert für.mp4
. Verwenden Sieffprobe
(Teil vonffmpeg
), um die Zeit in Sekunden abzurufen, z. B .:Also für alle
.mp4
Dateien im aktuellen Verzeichnis:Verwenden Sie dann
paste
, um die Ausgabe an zu übergebenbc
und die Gesamtzeit in Sekunden zu erhalten:Also, für
.ts
Dateien, die Sie versuchen könnten:Ein anderes Tool, das für die Videodateien funktioniert, die ich hier habe, ist
exiftool
zB:Gesamtlänge für alle
.mp4
Dateien im aktuellen Verzeichnis:Sie können die Ausgabe auch an einen anderen Befehl weiterleiten, um die Summe in umzuwandeln.
DD:HH:MM:SS
Die Antworten finden Sie hier .Oder benutze
exiftool
's internConvertDuration
dafür (du brauchst aber eine relativ aktuelle Version):quelle
ffprobe
.paste
undbc
! viel sauberer als mitawk
sagen wir mal.bc
dies eine willkürliche Genauigkeit bewirkt, besteht ein Nachteil darin, dass...| paste -sd+ - | bc
in einigenbc
Implementierungen entweder die Zeilengrößenbeschränkung erreicht wird (z. B.seq 429 | paste -sd+ - | bc
bei OpenSolaris ein Fehler auftrittbc
) oder der gesamte Speicher in anderen Implementierungen belegt werden kann .avprobe
in Arch Repos (hauptsächlich, weil es Konflikte gibtffmpeg
). Kann ich es also nicht mit ATM versuchen, aber gibt es dir die Dauer der Datei, wenn du es so ausführst :avprobe -show_format_entry duration myfile.mp4
oderavprobe -loglevel quiet -show_format_entry duration myfile.mp4
? Ich denke, einer dieser Befehle sollte Ihnen eine einzige Ausgabezeile mit der Dauer der Datei geben. Bin mir aber nicht sicher.Dies verwendet
ffmpeg
und druckt das Zeitlimit in Sekunden:Erläuterung:
for f in *.ts; do
iteriert jede der Dateien, die mit ".ts" endenffmpeg -i "$f" 2>&1
Leitet die Ausgabe auf stderr umgrep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' '
isoliert die Zeitawk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
Wandelt die Zeit in Sekunden umtimes+=("$_t")
Fügt die Sekunden zu einem Array hinzuecho "${times[@]}" | sed 's/ /+/g' | bc
Erweitert jedes der Argumente und ersetzt die Leerzeichen und leitet sie anbc
einen gemeinsamen Linux-Rechner weiterquelle
Streamlining @ jmunsch Antwort , und mit dem
paste
ich gerade gelernt , von @ slm Antwort , könnte man mit etwas so enden:Genau wie jmunsch drucke ich
ffmpeg
die Dauer, ignoriere den Fehler wegen einer fehlenden Ausgabedatei und suche stattdessen in der Fehlerausgabe nach der Dauerzeile. Ich rufeffmpeg
alle Aspekte des Gebietsschemas auf, die zum Standard-C-Gebietsschema gezwungen sind, damit ich mich nicht um lokalisierte Ausgabenachrichten kümmern muss.Als nächstes benutze ich eine Single
awk
anstelle seinergrep | grep | head | tr | awk
. Dieserawk
Aufruf sucht nach der (hoffentlich eindeutigen) Zeile, die enthältDuration:
. Mit Doppelpunkt als Trennzeichen ist diese Bezeichnung Feld 1, die Stunden sind Feld 2, die Minuten sind Feld 3 und das Sekundenfeld 4. Das nachgestellte Komma nach den Sekunden scheint mich nicht zu störenawk
, aber wenn jemand dort Probleme hat, hat er könnte eintr -d ,
in der Pipeline zwischenffmpeg
und enthaltenawk
.Nun kommt der Teil von slm: Ich
paste
ersetze Zeilenumbrüche durch Pluszeichen, ohne jedoch den Zeilenumbruch zu beeinflussen (im Gegensatz zu dem, dentr \\n +
ich in einer früheren Version dieser Antwort hatte). Das gibt den Summenausdruck an, der gefüttert werden kannbc
.Inspiriert von der Idee von slm, zeitähnliche
date
Formate zu verarbeiten, ist hier eine Version, in der die resultierenden Sekunden als Tage, Stunden, Minuten und Sekunden mit Bruchteilen formatiert werden:Das Teil im Inneren
$(…)
ist genau wie zuvor.@
Wir verwenden das Zeichen als Anhaltspunkt für die Anzahl der Sekunden seit dem 1. Januar 1970. Das resultierende „Datum“ wird als Tag des Jahres, Uhrzeit und Nanosekunden formatiert. Von diesem Tag des Jahres subtrahieren wir eins, da eine Eingabe von null Sekunden bereits zu Tag 1 des Jahres 1970 führt. Ich glaube, es gibt keine Möglichkeit, die Anzahl der Tage des Jahres bei null zu beginnen.Das Finale
sed
wird von zusätzlichen nachgestellten Nullen befreit. DieTZ
Einstellung sollte hoffentlich die Verwendung von UTC erzwingen, damit die Sommerzeit nicht bei sehr großen Videosammlungen stört . Wenn Sie Videos für mehr als ein Jahr haben, funktioniert dieser Ansatz jedoch immer noch nicht.quelle
Ich kenne die
.ts
Erweiterung nicht, gehe aber davon aus, dass es sich um eine Art Videodatei handelt, mit der Sieffmpeg
die Dauer einer Datei wie folgt ermitteln können:Wir können diese Ausgabe dann aufteilen und nur die Dauer auswählen.
Jetzt brauchen wir nur noch eine Möglichkeit, unsere Dateien zu durchlaufen und diese Dauerwerte zu erfassen.
HINWEIS: Hier mein Beispiel habe ich einfach meine Beispieldatei kopiert
some.mp4
und nannte sie1.mp4
,2.mp4
und3.mp4
.Umrechnung von Zeiten in Sekunden
Das folgende Snippet nimmt die Dauer von oben und konvertiert sie in Sekunden.
Dies nimmt unsere Zeit in Anspruch und fügt sie in eine Variable ein
$dur
, während wir die Dateien durchlaufen. Derdate
Befehl wird dann verwendet, um die Anzahl der Sekunden seit der Unix-Epoche (1. Januar 1970) zu berechnen. Hier ist der obigedate
Befehl aufgeschlüsselt, damit er leichter zu sehen ist:HINWEIS: Mit
Beispieldate
auf diese Weise funktioniert nur, wenn alle Ihre Dateien haben eine Dauer , dass die <24 Stunden (dh 86.400 Sekunden). Wenn Sie etwas benötigen, das längere Zeiten bewältigen kann, können Sie dies als Alternative verwenden:Die Zeiten aufsummieren
Wir können dann die Ausgabe unserer
for
Schleife nehmen und sie in einenpaste
Befehl ausführen, der+
Zeichen zwischen den einzelnen Zahlen enthält, wie folgt :Zuletzt führen wir dies in den Kommandozeilenrechner ein,
bc
um sie zusammenzufassen:Dies ergibt die Gesamtdauer aller Dateien in Sekunden. Dies kann natürlich bei Bedarf in ein anderes Format konvertiert werden.
quelle
date
zu einer Erstickungsgefahr führen kann, wennffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"
etwas zurückgegeben wird26:33:21.68
(paste
meine Aufmerksamkeit. Ich denkejava -classpath $(find -name \*.jar | paste -sd:)
, es wird sehr nützlich für mich sein, wenn man bedenkt, welche Hacks ich in der Vergangenheit verwendet hatte.paste
ist mein Lieblingsbefehl 8-)Gehen Sie von der akzeptierten Antwort aus und verwenden Sie das klassische UNIX-Umkehrpolierwerkzeug:
Dh: Appening
+
undp
Rohrleitungen , die dann indc
und Sie werden Ihre Summe erhalten.quelle
bc
bekommt viel zu viel Liebe. Sie alle setzen+
Zeichen zwischen den Zeilen (Beitritt auf+
), während mit Reverse-Politur können Sie nur Futter+
am Ende undp
rucken es aus;)Stellen Sie sicher, dass MPlayer installiert ist.
quelle
Als Ubuntu Schiff libav anstelle von ffmpeg:
Stark basierend auf MvG- Ideen
quelle
Nun, all diese Lösungen brauchen ein bisschen Arbeit. Was ich getan habe, war sehr einfach. 1)
Gehe in den gewünschten Ordner und klicke mit der rechten Maustaste -> mit anderer Anwendung öffnen
Dann wählen Sie VLC Media Player,
Hier ist ein Beispiel
1.
2.
3.
Sie können direkt unter der Symbolleiste sehen, dass eine Wiedergabeliste [10:35:51] geschrieben ist, sodass der Ordner 10 Stunden 35 Minuten und 51 Sekunden Gesamtvideodauer enthält
quelle
Ich hatte Unterverzeichnisse im aktuellen Ordner, also musste ich die Dauer rekursiv berechnen:
find . -iname '*.mp4' -print0 | xargs --null exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n1
quelle