Alguém sabe como buscar o número total de quadros de um arquivo de vídeo usando o ffmpeg? A saída de renderização do ffmpeg mostra o quadro atual e eu preciso da contagem de quadros para calcular o progresso em porcentagem.
Alguém sabe como buscar o número total de quadros de um arquivo de vídeo usando o ffmpeg? A saída de renderização do ffmpeg mostra o quadro atual e eu preciso da contagem de quadros para calcular o progresso em porcentagem.
Respostas:
ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 input.mp4
N/A
. Veja os outros métodos listados abaixo.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
opção de contar apenas os quadros-chave.Se você não tiver, ffprobe
poderá usar ffmpeg
:
ffmpeg -i input.mkv -map 0:v:0 -c copy -f null -
frame=
próximo ao final da saída do console.-discard nokey
opção de entrada (antes -i
) para contar apenas os quadros-chave.Ignore a lista de edição MP4 / M4V / M4A / MOV com a -ignore_editlist 1
opção de entrada. O padrão é não ignorar a lista de edição.
-v error
Isso oculta a saída de "informações" (informações da versão, etc), o que torna a análise mais fácil.
-count_frames
Conte o número de quadros por fluxo e relate-o na seção de fluxo correspondente.
-select_streams v:0
Selecione apenas o fluxo de vídeo.
-show_entries stream=nb_frames
ou -show_entries stream=nb_read_frames
Mostra apenas a entrada para nb_frames
ou nb_read_frames
.
-of default=nokey=1:noprint_wrappers=1
Defina o formato de saída (também conhecido como "escritor") como default
, não imprima a chave de cada campo ( nokey=1
) e não imprima o cabeçalho e o rodapé da seção ( noprint_wrappers=1
). Existem alternativas mais curtas, como -of csv=p=0
.
A mediainfo
ferramenta bem conhecida pode gerar o número de quadros:
mediainfo --Output="Video;%FrameCount%" input.avi
Para arquivos MP4 / M4V / M4A.
MP4Box
do gpac pode mostrar o número de quadros:
MP4Box -info input.mp4
Consulte a Media Info
linha na saída do stream de vídeo em questão:
Media Info: Language "Undetermined (und)" - Type "vide:avc1" - 2525 samples
Neste exemplo, o fluxo de vídeo tem 2525 quadros.
Para arquivos MP4 / M4V / M4A / MOV.
boxdumper
é uma ferramenta simples do l-smash. Ele produzirá uma grande quantidade de informações. Na stsz
seção da caixa do tamanho da amostra, consulte sample_count
o número de quadros. Neste exemplo, a entrada tem 1900 quadros de vídeo:
boxdumper input.mp4
...
[stsz: Sample Size Box]
position = 342641
size = 7620
version = 0
flags = 0x000000
sample_size = 0 (variable)
sample_count = 1900
stsz
átomo.ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 input.mkv
No Unix, isso funciona como um charme:
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
Isso é o que eu faço e funciona muito bem para mim e muitos outros.) Primeiro, encontre a duração do vídeo no snippet abaixo:
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
Você deve ser capaz de encontrar de forma consistente e segura Duration: hh:mm:ss.nn
para determinar o tamanho do videoclipe de origem. Então, para cada linha de atualização (CR, sem LF), você pode analisar o texto para a marca de tempo atual em:
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
Apenas tome cuidado para não esperar uma saída perfeita dessas linhas de status. Eles podem incluir mensagens de erro como aqui:
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
Assim que tiver o tempo, é matemática simples: time / durration * 100 = % done
.
TimeSpan
partir dele e usar currentDurationTimeSpan.Ticks / (totalDurationTimeSpan.Ticks / 100)
. O TimeSpan também oferece uma poderosa função Parse, verifique
Nem todos os formatos armazenam sua contagem de quadros ou duração total - e mesmo se o fizerem, o arquivo pode estar incompleto - então o ffmpeg não detecta nenhum deles com precisão por padrão.
Em vez disso, tente procurar o final do arquivo e ler a hora, depois conte a hora atual enquanto prossegue.
Alternativamente, você pode tentar AVFormatContext->nb_index_entries
ou a duração detectada, que deve funcionar bem em AVI / MOV não danificado, ou a biblioteca FFMS2, que provavelmente é muito lenta para se preocupar com uma barra de progresso.
Você pode usar ffprobe
para obter o número do quadro com os seguintes comandos
ffprobe.exe -i video_name -print_format json -loglevel fatal -show_streams -count_frames -select_streams v
que dizem para imprimir dados em json
formato
select_streams v
dirá ffprobe
para apenas nos fornecer video
dados de fluxo e se você removê-los, ele fornecerá audio
informações também
e a saída será como
{
"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. você pode usar
ffprobe -v error -show_format -show_streams video_name
que fornecerá dados de fluxo, se você quiser informações selecionadas como taxa de quadros, use o seguinte comando
ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 video_name
que fornecem um número com base nas informações do seu vídeo, o problema é quando você usa este método, é possível obter uma N/A
saída como.
para mais informações, consulte esta página Dicas FFProbe
tente isto:
ffmpeg -i "path to file" -f null /dev/null 2>&1 | grep 'frame=' | cut -f 2 -d ' '
*.ts
. A saída é uma linha vazia.
Como meu comentário teve alguns votos positivos, achei melhor deixá-lo como uma resposta:
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
Isso deve ser rápido, uma vez que nenhuma codificação está sendo executada. ffmpeg
irá apenas demuxar o arquivo e ler (decodificar) o primeiro stream de vídeo o mais rápido possível. O primeiro grep
comando irá capturar o texto que mostra o quadro. O segundo grep
comando pegará apenas o número daquele. O tail
comando mostrará apenas a linha final (contagem final de quadros).
para construir na resposta de stu. Veja como encontrei a taxa de quadros de um vídeo do meu celular. executei o seguinte comando por um tempo. Deixei a contagem de frames chegar a cerca de 10.000 antes de ficar impaciente e bater ^ 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.
$
então, peguei duas informações dessa linha que começa com "frame =", a contagem de frames, 7989, e o tempo, 00: 04: 26,30. Você primeiro precisa converter o tempo em segundos e depois dividir o número de quadros por segundos para obter "quadros por segundo". "quadros por segundo" é a sua taxa de quadros.
$ bc -l
0*60*60 + 4*60 + 26.3
266.3
7989/(4*60+26.3)
30.00000000000000000000
$
a taxa de quadros do meu vídeo é de 30 fps.
A única coisa exata que consegui fazer é o seguinte:
ffprobe -i my_video.mp4 -show_frames 2>&1|grep -c '^\[FRAME'
Para ter certeza de que funciona com vídeo:
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
Desculpe pela resposta do necro, mas talvez precise disso (pois não encontrei uma solução para os lançamentos recentes do ffmpeg.
Com ffmpeg 3.3.4 descobri que pode encontrar com o seguinte:
ffprobe -i video.mp4 -show_streams -hide_banner | grep "nb_frames"
No final, ele emitirá contagem de quadros. Funcionou para mim em vídeos com áudio. Ele fornece duas vezes uma linha "nb_frames", mas a primeira linha era a contagem real de quadros nos vídeos que testei.
Eu uso o php_ffmpeg então consigo obter todos os tempos e todos os frames de um filme. Como abaixo
$input_file='/home/strone/workspace/play/CI/abc.rmvb';
$ffmpegObj = new ffmpeg_movie($input_file);
echo $ffmpegObj->getDuration();
echo $ffmpegObj->getFrameCount();
E então o detalhe está na página.
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
rubi
result = `ffmpeg -i #{path} -f null - 2>&1`
r = result.match("frame=([0-9]+)")
p r[1]