Qualcuno sa come recuperare il numero di fotogrammi totali da un file video utilizzando ffmpeg? L'output di rendering di ffmpeg mostra il frame corrente e ho bisogno del conteggio dei frame per calcolare l'avanzamento in percentuale.
Qualcuno sa come recuperare il numero di fotogrammi totali da un file video utilizzando ffmpeg? L'output di rendering di ffmpeg mostra il frame corrente e ho bisogno del conteggio dei frame per calcolare l'avanzamento in percentuale.
Risposte:
ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 input.mp4
N/A
. Vedere gli altri metodi elencati di seguito.ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 input.mkv
-skip_frame nokey
opzione per contare solo i fotogrammi chiave.Se non lo ffprobe
hai puoi usare ffmpeg
invece:
ffmpeg -i input.mkv -map 0:v:0 -c copy -f null -
frame=
quasi la fine dell'output della console.-discard nokey
opzione di input (prima -i
) per contare solo i fotogrammi chiave.Ignora l'elenco di modifica MP4 / M4V / M4A / MOV con l' -ignore_editlist 1
opzione di input. L'impostazione predefinita è di non ignorare l'elenco di modifiche.
-v error
Questo nasconde l'output di "info" (informazioni sulla versione, ecc.) Che rende più facile l'analisi.
-count_frames
Contare il numero di frame per stream e segnalarlo nella sezione stream corrispondente.
-select_streams v:0
Seleziona solo il flusso video.
-show_entries stream=nb_frames
o -show_entries stream=nb_read_frames
Mostra solo la voce per nb_frames
o nb_read_frames
.
-of default=nokey=1:noprint_wrappers=1
Imposta il formato di output (noto anche come "scrittore") su default
, non stampare la chiave di ogni campo ( nokey=1
) e non stampare l'intestazione e il piè di pagina della sezione ( noprint_wrappers=1
). Esistono alternative più brevi come -of csv=p=0
.
Il noto mediainfo
strumento può produrre il numero di frame:
mediainfo --Output="Video;%FrameCount%" input.avi
Per file MP4 / M4V / M4A.
MP4Box
da gpac può mostrare il numero di frame:
MP4Box -info input.mp4
Fare riferimento alla Media Info
riga nell'output per il flusso video in questione:
Media Info: Language "Undetermined (und)" - Type "vide:avc1" - 2525 samples
In questo esempio il flusso video ha 2525 fotogrammi.
Per file MP4 / M4V / M4A / MOV.
boxdumper
è un semplice strumento di l-smash. Produrrà una grande quantità di informazioni. Nella stsz
sezione della casella delle dimensioni del campione, fare riferimento a sample_count
per il numero di frame. In questo esempio l'ingresso ha 1900 frame video:
boxdumper input.mp4
...
[stsz: Sample Size Box]
position = 342641
size = 7620
version = 0
flags = 0x000000
sample_size = 0 (variable)
sample_count = 1900
stsz
atomo.ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 input.mkv
In Unix, funziona come un fascino:
ffmpeg -i 00000.avi -vcodec copy -acodec copy -f null /dev/null 2>&1 | grep 'frame=' | cut -f 2 -d ' '
ffmpeg -i 00000.avi -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1
Questo è quello che faccio e funziona alla grande per me e per molti altri.) Innanzitutto, trova la lunghezza del video nello snippet seguente:
Seems stream 0 codec frame rate differs from container frame rate: 5994.00
(5994/1) -> 29.97 (30000/1001)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/stu/Movies/District9.mov':
Duration: 00:02:32.20, start: 0.000000, bitrate: 9808 kb/s
Stream #0.0(eng): Video: h264, yuv420p, 1920x1056, 29.97tbr, 2997tbn, 5994tbc
Stream #0.1(eng): Audio: aac, 44100 Hz, 2 channels, s16
Stream #0.2(eng): Data: tmcd / 0x64636D74
Dovresti essere in grado di trovare in modo coerente e sicuro Duration: hh:mm:ss.nn
per determinare la dimensione del video clip di origine. Quindi, per ogni riga di aggiornamento (CR, no LF) puoi analizzare il testo per l'indicatore di tempo corrente in cui si trova:
frame= 84 fps= 18 q=10.0 size= 5kB time=1.68 bitrate= 26.1kbits/s
frame= 90 fps= 17 q=10.0 size= 6kB time=1.92 bitrate= 23.8kbits/s
frame= 94 fps= 16 q=10.0 size= 232kB time=2.08 bitrate= 913.0kbits/s
Basta fare attenzione a non aspettarsi sempre un risultato perfetto da queste righe di stato. Possono includere messaggi di errore come qui:
frame= 24 fps= 24 q=-1.0 size= 0kB time=1.42 bitrate= 0.3kbits/s
frame= 41 fps= 26 q=-1.0 size= 0kB time=2.41 bitrate= 0.2kbits/s
[h264 @ 0x1013000]Cannot parallelize deblocking type 1, decoding such frames in
sequential order
frame= 49 fps= 24 q=26.0 size= 4kB time=0.28 bitrate= 118.1kbits/s
frame= 56 fps= 22 q=23.0 size= 4kB time=0.56 bitrate= 62.9kbits/s
Una volta che si ha il tempo, è semplice matematica: time / durration * 100 = % done
.
TimeSpan
da esso, quindi utilizzare currentDurationTimeSpan.Ticks / (totalDurationTimeSpan.Ticks / 100)
. Il TimeSpan fornisce anche una potente funzione Parse, dai un'occhiata
Non tutti i formati memorizzano il numero di fotogrammi o la durata totale e, anche se lo fanno, il file potrebbe essere incompleto, quindi ffmpeg non rileva nessuno dei due in modo accurato per impostazione predefinita.
Invece, prova a cercare fino alla fine del file e leggi l'ora, quindi conta l'ora corrente mentre vai.
In alternativa, puoi provare AVFormatContext->nb_index_entries
o la durata rilevata, che dovrebbe funzionare bene su AVI / MOV almeno non danneggiati, o la libreria FFMS2, che probabilmente è troppo lenta per una barra di avanzamento.
È possibile utilizzare ffprobe
per ottenere il numero di frame con i seguenti comandi
ffprobe.exe -i video_name -print_format json -loglevel fatal -show_streams -count_frames -select_streams v
che dicono di stampare i dati in json
formato
select_streams v
dirà ffprobe
di fornirci solo i dati di video
streaming e se lo rimuovi, fornirà anche audio
informazioni
e l'output sarà come
{
"streams": [
{
"index": 0,
"codec_name": "mpeg4",
"codec_long_name": "MPEG-4 part 2",
"profile": "Simple Profile",
"codec_type": "video",
"codec_time_base": "1/25",
"codec_tag_string": "mp4v",
"codec_tag": "0x7634706d",
"width": 640,
"height": 480,
"coded_width": 640,
"coded_height": 480,
"has_b_frames": 1,
"sample_aspect_ratio": "1:1",
"display_aspect_ratio": "4:3",
"pix_fmt": "yuv420p",
"level": 1,
"chroma_location": "left",
"refs": 1,
"quarter_sample": "0",
"divx_packed": "0",
"r_frame_rate": "10/1",
"avg_frame_rate": "10/1",
"time_base": "1/3000",
"start_pts": 0,
"start_time": "0:00:00.000000",
"duration_ts": 256500,
"duration": "0:01:25.500000",
"bit_rate": "261.816000 Kbit/s",
"nb_frames": "855",
"nb_read_frames": "855",
"disposition": {
"default": 1,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0
},
"tags": {
"creation_time": "2005-10-17 22:54:33",
"language": "eng",
"handler_name": "Apple Video Media Handler",
"encoder": "3ivx D4 4.5.1"
}
}
]
}
2. puoi usare
ffprobe -v error -show_format -show_streams video_name
che ti darà i dati di streaming, se desideri informazioni selezionate come la frequenza dei fotogrammi, usa il seguente comando
ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 video_name
che fornisce una base numerica sulle informazioni video, il problema è che quando si utilizza questo metodo, è possibile che si ottenga un N/A
output.
per maggiori informazioni controlla questa pagina FFProbe Tips
prova questo:
ffmpeg -i "path to file" -f null /dev/null 2>&1 | grep 'frame=' | cut -f 2 -d ' '
*.ts
. L'output è una riga vuota.
Dato che il mio commento ha ricevuto alcuni voti positivi, ho pensato di lasciarlo come risposta:
ffmpeg -i 00000.avi -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1
Dovrebbe essere veloce, poiché non viene eseguita alcuna codifica. ffmpeg
eseguirà il demux del file e leggerà (decodificherà) il primo flusso video il più rapidamente possibile. Il primo grep
comando prenderà il testo che mostra la cornice. Il secondo grep
comando prenderà solo il numero da quello. Il tail
comando mostrerà solo la riga finale (conteggio frame finale).
per costruire sulla risposta di stu. ecco come ho trovato il frame rate per un video dal mio telefono cellulare. ho eseguito il seguente comando per un po '. ho lasciato che il conteggio dei frame arrivasse a circa ~ 10.000 prima di diventare impaziente e premere ^ C:
$ ffmpeg -i 2013-07-07\ 12.00.59.mp4 -f null /dev/null 2>&1
...
Press [q] to stop, [?] for help
[null @ 0x7fcc80836000] Encoder did not produce proper pts, making some up.
frame= 7989 fps= 92 q=0.0 Lsize=N/A time=00:04:26.30 bitrate=N/A dup=10 drop=0
video:749kB audio:49828kB subtitle:0 global headers:0kB muxing overhead -100.000042%
Received signal 2: terminating.
$
poi, ho preso due informazioni da quella riga che inizia con "frame =", il conteggio dei frame, 7989 e l'ora, 00: 04: 26.30. Devi prima convertire il tempo in secondi e poi dividere il numero di fotogrammi per secondi per ottenere "fotogrammi al secondo". "fotogrammi al secondo" è il tuo frame rate.
$ bc -l
0*60*60 + 4*60 + 26.3
266.3
7989/(4*60+26.3)
30.00000000000000000000
$
il framerate per il mio video è di 30 fps.
L'unico modo accurato che sono riuscito a fare è il seguente:
ffprobe -i my_video.mp4 -show_frames 2>&1|grep -c '^\[FRAME'
Per assicurarti che funzioni con il video:
ffprobe -i my_video.mp4 -show_frames 2>&1 | grep -c media_type=video
ffprobe -i my_video.mp4 -show_frames 2>&1 | grep -c media_type=video
Ci scusiamo per la risposta negativa, ma forse ne avrò bisogno (dato che non ho trovato una soluzione per le recenti versioni di ffmpeg.
Con ffmpeg 3.3.4 ho trovato che si può trovare con quanto segue:
ffprobe -i video.mp4 -show_streams -hide_banner | grep "nb_frames"
Alla fine emetterà il conteggio dei frame. Ha funzionato per me sui video con audio. Tuttavia, fornisce due volte una riga "nb_frames", ma la prima riga era il conteggio effettivo dei fotogrammi nei video che ho testato.
Uso il php_ffmpeg quindi posso ottenere tutti i tempi e tutti i fotogrammi di un film. Come belows
$input_file='/home/strone/workspace/play/CI/abc.rmvb';
$ffmpegObj = new ffmpeg_movie($input_file);
echo $ffmpegObj->getDuration();
echo $ffmpegObj->getFrameCount();
E poi il dettaglio è sulla pagina.
Cmd ->
ffprobe.exe -v error -select_streams v:0 -show_entries stream=r_frame_rate,duration -of default=nw=1 "d:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4"
Result ->
r_frame_rate=24000/1001
duration=8177.794625
Calculation ->
Frames=24000/1001*8177.794625=196071
Proof ->
ffmpeg -i "d:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4" -f null /dev/null
ffmpeg version N-92938-g0aaaca25e0-ffmpeg-windows-pacman Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 8.2.0 (GCC)
configuration: --pkg-config=pkg-config --pkg-config-flags=--static --extra-version=ffmpeg-windows-pacman --enable-version3 --disable-debug --disable-w32threads --arch=x86_64 --target-os=mingw32 --cross-prefix=/opt/sandbox/cross_compilers/mingw-w64-x86_64/bin/x86_64-w64-mingw32- --enable-libcaca --enable-gray --enable-libtesseract --enable-fontconfig --enable-gmp --enable-gnutls --enable-libass --enable-libbluray --enable-libbs2b --enable-libflite --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libzimg --enable-libzvbi --enable-libmysofa --enable-libaom --enable-libopenjpeg --enable-libopenh264 --enable-liblensfun --enable-nvenc --enable-nvdec --extra-libs=-lm --extra-libs=-lpthread --extra-cflags=-DLIBTWOLAME_STATIC --extra-cflags=-DMODPLUG_STATIC --extra-cflags=-DCACA_STATIC --enable-amf --enable-libmfx --enable-gpl --enable-avisynth --enable-frei0r --enable-filter=frei0r --enable-librubberband --enable-libvidstab --enable-libx264 --enable-libx265 --enable-libxvid --enable-libxavs --enable-avresample --extra-cflags='-march=core2' --extra-cflags=-O2 --enable-static --disable-shared --prefix=/opt/sandbox/cross_compilers/mingw-w64-x86_64/x86_64-w64-mingw32 --enable-nonfree --enable-decklink --enable-libfdk-aac
libavutil 56. 25.100 / 56. 25.100
libavcodec 58. 43.100 / 58. 43.100
libavformat 58. 25.100 / 58. 25.100
libavdevice 58. 6.101 / 58. 6.101
libavfilter 7. 47.100 / 7. 47.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 4.100 / 5. 4.100
libswresample 3. 4.100 / 3. 4.100
libpostproc 55. 4.100 / 55. 4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'd:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.25.100
Duration: 02:16:17.91, start: 0.000000, bitrate: 2497 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x800 [SAR 1:1 DAR 12:5], 2397 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 93 kb/s (default)
Metadata:
handler_name : GPAC ISO Audio Handler
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native))
Stream #0:1 -> #0:1 (aac (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, null, to '/dev/null':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.25.100
Stream #0:0(und): Video: wrapped_avframe, yuv420p, 1920x800 [SAR 1:1 DAR 12:5], q=2-31, 200 kb/s, 23.98 fps, 23.98 tbn, 23.98 tbc (default)
Metadata:
handler_name : VideoHandler
encoder : Lavc58.43.100 wrapped_avframe
Stream #0:1(und): Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s (default)
Metadata:
handler_name : GPAC ISO Audio Handler
encoder : Lavc58.43.100 pcm_s16le
frame=196071 fps=331 q=-0.0 Lsize=N/A time=02:16:17.90 bitrate=N/A speed=13.8x
video:102631kB audio:1408772kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
linux
ffmpeg -i "/home/iorigins/Завантаження/123.mov" -f null /dev/null
rubino
result = `ffmpeg -i #{path} -f null - 2>&1`
r = result.match("frame=([0-9]+)")
p r[1]