Витяг кліпу FFmpeg - частота кадрів потоку відрізняється від частоти кадрів контейнера (x264, aac)


8

Підсумок
відео H.264, схоже, має дійсно високу частоту кадрів, що вимагає масштабування коефіцієнта масштабу, який застосовується до тривалості відео, яку я намагаюся витягнути (на 900 разів нижче).

Тіло
Я намагаюся витягти кліп із фільму, який у мене є у форматі MP4 (створений за допомогою Handbrake ). Спробувавши mencoder та VLC, я вирішив дати знімок FFmpeg, оскільки це було найменш клопітно, коли справа стосувалася копіювання кодеків. Тобто, порівняно з mencoder та VLC, отриманий файл все ще відтворювався у QuickTime (я знаю про Perian тощо), я просто намагаюся дізнатися, як все це працює).

У будь-якому разі моя команда була такою:

ffmpeg -ss 01:15:51 -t 00:05:59 -i outofsight.mp4 \ 
-acodec copy -vcodec copy clip.mp4

Під час копіювання з'являється наступне:

Seems stream 0 codec frame rate differs from container frame rate: 45000.00 (45000/1) -> 25.00 (25/1)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from outofsight.mp4':
  Duration: 01:57:42.10, start: 0.000000, bitrate: 830 kb/s
    Stream #0.0(und): Video: h264, yuv420p, 720x384, 25 tbr, 22500 tbn, 45k tbc
    Stream #0.1(eng): Audio: aac, 48000 Hz, stereo, s16
Output #0, mp4, to 'out.mp4':
    Stream #0.0(und): Video: libx264, yuv420p, 720x384, q=2-31, 90k tbn, 22500 tbc
    Stream #0.1(eng): Audio: libfaac, 48000 Hz, stereo, s16
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 2591 fps=2349 q=-1.0 size=    8144kB time=101.60 bitrate= 656.7kbits/s
…

Замість кліпу тривалістю 5:59 я отримую весь решта фільму. Отже, щоб перевірити це, я запустив команду ffmpeg -t 00:00:01. Я отримав рівно 15:00-хвилинний кліп. Тож я зробив інженерію чорної коробки і вирішив масштабувати свій -tваріант, обчисливши, яке значення потрібно ввести, враховуючи, що 1 секунда інтерпретується як 900 с. Для потрібного кліпу 359 с я обчислив 0,399 с, і тому моя команда ffmpeg стала:

ffmpeg -ss 01:15.51 -t 00:00:00.399 -i outofsight.mp4 \ 
-acodec copy -vcodec copy clip.mp4

Це працює, але я не маю поняття, чому тривалість масштабується на 900. Досліджуючи далі, кожен пробіг ffmpeg має рядок:

Seems stream 0 codec frame rate differs from container frame rate: 45000.00 (45000/1) -> 25.00 (25/1)

45000/25 = 1800. Має бути десь стосунок. Якось непристойно висока частота кадрів спричиняє проблеми з термінами. Наскільки така частота кадрів настільки висока? Найкраще з цього приводу полягає в тому, що отриманий clip.mp4 має точно таку ж особливість (завдяки скопійованому відеокодеку), а для зняття подальших кліпів із цього потрібне те саме масштабування для параметра -tтривалості. Тому я зробив це доступним для всіх, хто бажає перевірити це.

Додаток
Преамбула для ffmpeg в моїй системі (побудована за допомогою порту MacPorts ffmpeg):

FFmpeg version 0.5, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  configuration: --prefix=/opt/local --disable-vhook --enable-gpl --enable-postproc --enable-swscale --enable-avfilter --enable-avfilter-lavf --enable-libmp3lame --enable-libvorbis --enable-libtheora --enable-libdirac --enable-libschroedinger --enable-libfaac --enable-libfaad --enable-libxvid --enable-libx264 --mandir=/opt/local/share/man --enable-shared --enable-pthreads --cc=/usr/bin/gcc-4.2 --arch=x86_64
  libavutil     49.15. 0 / 49.15. 0
  libavcodec    52.20. 0 / 52.20. 0
  libavformat   52.31. 0 / 52.31. 0
  libavdevice   52. 1. 0 / 52. 1. 0
  libavfilter    1. 4. 0 /  1. 4. 0
  libswscale     1. 7. 1 /  1. 7. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on Jan  4 2010 21:51:51, gcc: 4.2.1 (Apple Inc. build 5646) (dot 1)

EDIT
Не впевнений, була помилка чи ні, але, здається, виправлена ​​зараз у моїй поточній версії ffmpeg, принаймні для цього відео (версія 0.6.1 від MacPorts).


Повторне кодування не є вирішенням, і робити розшифровку годин на п'ять хвилин вмісту нерозумно і, ймовірно, не вирішить основну проблему. Великий початковий дослід. Ви, мабуть, вірно вважаєте, що виявлення fps ffmpeg є коренем вашої проблеми. Здається, що пізніша версія ffmpeg виправила вашу проблему, але я прокоментую. Я б рекомендував робити копію -c в інший формат контейнера. Це може мати найрізноманітніші ефекти, але це було б гарним наступним кроком для експерименту.
dstob

Відповіді:


1

Що стосується ffmpeg, то позиціонування варіантів має значення. З вашим прикладом він намагається застосувати -ss та -t до вхідних даних. Використовуйте його так, як замість цього застосуйте параметри до виводу:

ffmpeg -i outofsight.mp4 -ss 01:15:51 -t 00:05:59 -acodec copy -vcodec copy clip.mp4

З поточним ffmpeg правильним буде синтаксис:

ffmpeg -i outofsight.mp4 -ss 01:15:51 -t 00:05:59 -c copy clip.mp4

1

У мене була ця сама проблема, і моє рішення було наступне:

        $ffmpegout = array();           
        //10 is the number of images you want from video
        $fracduration = ($info['duration']/10);             

exec ('ffmpeg -y -i /testmedia/'.$info evidence'filename']. '-vf fps = fps = fps = 1 /'.$ fracduration.' -f image2 /testmedia/images/output%03d.jpg 2 > & 1 ', $ ffmpegout); // print_r ($ ffmpegout);

Це дає мені 10 зображень за все відео, незалежно від тривалості відео

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.