Um viele Informationen über eine Mediendatei zu erhalten, kann man dies tun
ffmpeg -i <filename>
Dort werden viele Zeilen ausgegeben, insbesondere eine
Duration: 00:08:07.98, start: 0.000000, bitrate: 2080 kb/s
Ich möchte nur ausgeben 00:08:07.98
, also versuche ich es
ffmpeg -i file.mp4 | grep Duration| sed 's/Duration: \(.*\), start/\1/g'
Aber es druckt alles und nicht nur die Länge.
Auch ffmpeg -i file.mp4 | grep Duration
gibt alles.
Wie bekomme ich nur die Dauer?
Antworten:
ffmpeg schreibt diese Informationen
stderr
nicht anstdout
. Versuche dies:ffmpeg -i file.mp4 2>&1 | grep Duration | sed 's/Duration: \(.*\), start/\1/g'
Beachten Sie die Umleitung
stderr
zustdout
:2>&1
BEARBEITEN:
Ihre
sed
Aussage funktioniert auch nicht. Versuche dies:ffmpeg -i file.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d ,
quelle
sed -n 's/Duration: \(.*\), start/\1/gp'
aus.sed
ist unnötig:ffmpeg -i file.mp4 2>&1 | grep -o -P "(?<=Duration: ).*?(?=,)"
Sie können verwenden
ffprobe
:ffprobe -i <file> -show_entries format=duration -v quiet -of csv="p=0"
Die Dauer wird in Sekunden ausgegeben, z. B.:
Durch Hinzufügen der
-sexagesimal
Option wird die Dauer in Stunden: Minuten: Sekunden ausgegeben. Mikrosekunden :quelle
Nach meiner Erfahrung bieten viele Tools die gewünschten Daten in einer Art Tabelle / geordneter Struktur an und bieten auch Parameter zum Sammeln bestimmter Teile dieser Daten. Dies gilt beispielsweise auch für smartctl, nvidia-smi und ffmpeg / ffprobe. Einfach gesagt - oft ist es nicht erforderlich, Daten umzuleiten oder Unterschalen für eine solche Aufgabe zu öffnen.
Infolgedessen würde ich das richtige Werkzeug für den Job verwenden - in diesem Fall würde ffprobe den Rohdauerwert in Sekunden zurückgeben, danach könnte man das gewünschte Zeitformat selbst erstellen:
Der Befehl kann je nach verwendeter Version variieren.
#!/usr/bin/env bash input_file="/path/to/media/file" # Get raw duration value ffprobe -v quiet -print_format compact=print_section=0:nokey=1:escape=csv -show_entries format=duration "$input_file"
Eine Erklärung:
Referenz: ffprobe Manpages
quelle
Ich empfehle die Verwendung des JSON-Formats, es ist einfacher zum Parsen
ffprobe -i your-input-file.mp4 -v quiet -print_format json -show_format -show_streams -hide_banner { "streams": [ { "index": 0, "codec_name": "aac", "codec_long_name": "AAC (Advanced Audio Coding)", "profile": "HE-AACv2", "codec_type": "audio", "codec_time_base": "1/44100", "codec_tag_string": "[0][0][0][0]", "codec_tag": "0x0000", "sample_fmt": "fltp", "sample_rate": "44100", "channels": 2, "channel_layout": "stereo", "bits_per_sample": 0, "r_frame_rate": "0/0", "avg_frame_rate": "0/0", "time_base": "1/28224000", "duration_ts": 305349201, "duration": "10.818778", "bit_rate": "27734", "disposition": { "default": 0, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0 } } ], "format": { "filename": "your-input-file.mp4", "nb_streams": 1, "nb_programs": 0, "format_name": "aac", "format_long_name": "raw ADTS AAC (Advanced Audio Coding)", "duration": "10.818778", "size": "37506", "bit_rate": "27734", "probe_score": 51 } }
Sie finden die Dauerinformationen im Formatabschnitt, der sowohl für Video als auch für Audio funktioniert
quelle
Wenn Sie die Länge (und möglicherweise alle anderen Metadaten) mit ffmpeg mithilfe eines Python-Skripts aus Ihrer Mediendatei abrufen möchten, können Sie Folgendes versuchen:
import subprocess import json input_file = "< path to your input file here >" metadata = subprocess.check_output(f"ffprobe -i {input_file} -v quiet -print_format json -show_format -hide_banner".split(" ")) metadata = json.loads(metadata) print(f"Length of file is: {float(metadata['format']['duration'])}") print(metadata)
Ausgabe:
Length of file is: 7579.977143 { "streams": [ { "index": 0, "codec_name": "mp3", "codec_long_name": "MP3 (MPEG audio layer 3)", "codec_type": "audio", "codec_time_base": "1/44100", "codec_tag_string": "[0][0][0][0]", "codec_tag": "0x0000", "sample_fmt": "fltp", "sample_rate": "44100", "channels": 2, "channel_layout": "stereo", "bits_per_sample": 0, "r_frame_rate": "0/0", "avg_frame_rate": "0/0", "time_base": "1/14112000", "start_pts": 353600, "start_time": "0.025057", "duration_ts": 106968637440, "duration": "7579.977143", "bit_rate": "320000", ... ...
quelle
Traceback (most recent call last):
File "ffprobe.py", line 9, in <module>
print("Length of file is: {}".format(float(length["format"]["duration"])))
NameError: name 'length' is not defined
Dies sollte den Job machen:import subprocess
import json
input_file = "out.mp4"
metadata = subprocess.check_output(f"ffprobe -i {input_file} -v quiet -print_format json -show_format -hide_banner".split(" "))
metadata = json.loads(metadata)
print("Length of file is: {}".format(float(metadata["format"]["duration"])))
print(metadata)
Bei einem Anforderungsparameter ist es einfacher, mediainfo und seine Ausgabeformatierung wie folgt zu verwenden (für die Dauer; Antwort in Millisekunden).
mediainfo --Output="General;%Duration%" ~/work/files/testfiles/+h263_aac.avi
Ausgänge
quelle
Für diejenigen, die dieselben Berechnungen ohne zusätzliche Software in Windows ausführen möchten, ist hier das Skript für das Befehlszeilenskript:
set input=video.ts ffmpeg -i "%input%" 2> output.tmp rem search " Duration: HH:MM:SS.mm, start: NNNN.NNNN, bitrate: xxxx kb/s" for /F "tokens=1,2,3,4,5,6 delims=:., " %%i in (output.tmp) do ( if "%%i"=="Duration" call :calcLength %%j %%k %%l %%m ) goto :EOF :calcLength set /A s=%3 set /A s=s+%2*60 set /A s=s+%1*60*60 set /A VIDEO_LENGTH_S = s set /A VIDEO_LENGTH_MS = s*1000 + %4 echo Video duration %1:%2:%3.%4 = %VIDEO_LENGTH_MS%ms = %VIDEO_LENGTH_S%s
Gleiche Antwort hier: So beschneiden Sie die letzten N Sekunden eines TS-Videos
quelle
ffmpeg -i abc.mp4 2>&1 | grep Duration | cut -d ' ' -f 4 | sed s/,//
gibt Ausgabe
HH: MM: SS.milisecs
quelle
grep
,cut
Undsed
sind unecessary. Siehe Iwans Antwort .ffprobe
alleine benutzen kannst . Die Ausgabe vonffmpeg
dient nur zu Informationszwecken und nicht zum Parsen: Es wird nicht garantiert, dass immer dieselbe Struktur, dasselbe Format und dieselben Informationen mit verschiedenenffmpeg
Versionen und verschiedenen Eingabeformaten verwendet werden.Beste Lösung: Schneiden Sie den Export und erhalten Sie so etwas wie 00: 05: 03.22
quelle
Ich würde dies einfach in C ++ mit einer Textdatei tun und die Token extrahieren. Warum? Ich bin kein Linux-Terminal-Experte wie die anderen.
Um es einzurichten, würde ich dies unter Linux tun.
ffmpeg -i 2>&1 | grep "" > mytext.txt
Führen Sie anschließend eine C ++ - App aus, um die erforderlichen Daten abzurufen. Extrahieren Sie möglicherweise alle wichtigen Werte und formatieren Sie sie für die weitere Verarbeitung mithilfe von Token neu. Ich muss nur an meiner eigenen Lösung arbeiten und die Leute werden sich nur über mich lustig machen, weil ich ein Linux-Neuling bin und nicht gerne zu viel Skripte schreibe.
quelle
Argh. Vergess das. Es sieht so aus, als müsste ich die Spinnweben aus meiner C- und C ++ - Programmierung herausholen und stattdessen verwenden. Ich kenne nicht alle Shell-Tricks, um es zum Laufen zu bringen. So weit bin ich gekommen.
ffmpeg -i myfile 2>&1 | grep "" > textdump.txt
und dann würde ich wahrscheinlich die Dauer mit einer C ++ - App extrahieren, indem ich stattdessen Token extrahiere.
Ich poste die Lösung nicht, weil ich gerade keine nette Person bin
Update - Ich habe meinen Ansatz, um diesen Zeitstempel zu erhalten
Schritt 1 - Holen Sie sich die Medieninformationen in eine Textdatei
`ffprobe -i myfile 2>&1 | grep "" > textdump.txt`
ODER
`ffprobe -i myfile 2>&1 | awk '{ print }' > textdump.txt`
Schritt 2 - Informieren Sie sich über die benötigten Informationen und extrahieren Sie sie.
cat textdump.txt | grep "Duration" | awk '{ print $2 }' | ./a.out
Beachten Sie das a.out. Das ist mein C-Code, um das resultierende Komma abzuschneiden, da die Ausgabe ungefähr 00: 00: 01.33 ist.
Hier ist der C-Code, der stdin verwendet und die richtigen benötigten Informationen ausgibt. Ich musste die größeren und kleineren Zeichen zum Betrachten herausnehmen.
#include stdio.h #include string.h void main() { //by Admiral Smith Nov 3. 2016 char time[80]; int len; char *correct; scanf("%s", &time); correct = (char *)malloc(strlen(time)); if (!correct) { printf("\nmemory error"); return; } memcpy(correct,&time,strlen(time)-1); correct[strlen(time)]='/0'; printf("%s", correct); free(correct); }
Jetzt formatiert die Ausgabe korrekt wie 00: 00: 01.33
quelle
Sie könnten dies versuchen:
/* * Determine video duration with ffmpeg * ffmpeg should be installed on your server. */ function mbmGetFLVDuration($file){ //$time = 00:00:00.000 format $time = exec("ffmpeg -i ".$file." 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//"); $duration = explode(":",$time); $duration_in_seconds = $duration[0]*3600 + $duration[1]*60+ round($duration[2]); return $duration_in_seconds; } $duration = mbmGetFLVDuration('/home/username/webdir/video/file.mov'); echo $duration;
quelle
ffmpeg wurde durch avconv ersetzt: Ersetzen Sie einfach Louis Marascios Antwort durch avconb.
avconv -i file.mp4 2>&1 | grep Duration | sed 's/Duration: \(.*\), start.*/\1/g'
Hinweis: die zusätzliche. * Nach dem Start, um die Zeit alleine zu bekommen !!
quelle
ffmpeg
" aus Libav (eine Abzweigung des FFmpeg-Projekts) wurde durch eineavconv
aus Libav ersetzt.ffmpeg
von FFmpeg befindet sich in einer sehr aktiven Entwicklung.