Clip d'extrait FFmpeg - la fréquence d'images du flux diffère de la fréquence d'images du conteneur (x264, aac)

8

Résumé La
vidéo H.264 semble avoir une fréquence d'images vraiment élevée qui nécessite un facteur d'échelle appliqué à la durée de la vidéo que j'essaye d'extraire (900x plus bas).

Body
J'essaie d'extraire un clip d'un film que j'ai au format MP4 (créé à l'aide de Handbrake ). Après avoir essayé mencoder et VLC, j'ai décidé d'essayer FFmpeg car c'était le moins gênant pour copier les codecs. Autrement dit, par rapport à mencoder et VLC, le fichier résultant était toujours jouable dans QuickTime (je connais Perian, etc., j'essaie juste d'apprendre comment tout cela fonctionne).

Quoi qu'il en soit, ma commande était la suivante:

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

Pendant la copie, ce qui suit apparaît:

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
…

Au lieu d'un clip d'une durée de 5:59, j'obtiens tout le reste du film. Donc, pour tester cela, j'ai exécuté la commande ffmpeg avec -t 00:00:01. Ce que j'ai obtenu était exactement un clip de 15h00. J'ai donc fait de l'ingénierie de boîte noire et j'ai décidé de mettre à l'échelle mon -toption en calculant la valeur à saisir étant donné qu'une seconde a été interprétée comme 900 s. Pour le clip de 359 s souhaité, j'ai calculé 0,399 s et ma commande ffmpeg est donc devenue:

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

Cela fonctionne, mais je n'ai aucune idée de la raison pour laquelle la durée est réduite de 900. En recherchant plus loin, chaque exécution de ffmpeg a la ligne:

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

45000/25 = 1800. Doit être une relation quelque part. D'une manière ou d'une autre, la fréquence d'images incroyablement élevée cause des problèmes de synchronisation. Comment cette fréquence d'images est-elle si élevée? La meilleure partie à ce sujet est que le clip.mp4 résultant a exactement la même fonctionnalité (en raison du codec vidéo copié), et la prise de clips supplémentaires nécessite la même mise à l'échelle pour l' -toption de durée. Par conséquent, je l'ai mis à la disposition de tous ceux qui souhaitent vérifier cela.

Annexe
Le préambule de ffmpeg sur mon système (construit en utilisant le port ffmpeg de MacPorts):

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
Je ne sais pas si c'était un bug ou pas, mais il semble être corrigé maintenant dans ma version actuelle de ffmpeg, au moins pour cette vidéo (version 0.6.1 de MacPorts).

fideli
la source
Le réencodage n'est pas une solution et faire des heures de décodage pour cinq minutes de contenu est déraisonnable et ne résoudrait probablement pas le problème sous-jacent. Grande recherche initiale btw. Vous avez probablement raison de supposer que le fps que ffmpeg détectait est à l'origine de votre problème. Il semble qu'une version ultérieure de ffmpeg ait résolu votre problème, mais je ferai un commentaire. J'aurais recommandé de faire une copie -c dans un format de conteneur différent. Cela peut avoir une variété d'effets mais cela aurait été une bonne prochaine étape à expérimenter.
dstob

Réponses:

1

Avec ffmpeg, le positionnement des options est important. Avec votre exemple, il essaie d'appliquer -ss et -t à l'entrée. Utilisez-le comme ceci appliquera les options à la sortie à la place:

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

Avec ffmpeg actuel, la syntaxe correcte serait:

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

J'avais ce même problème et ma solution était la suivante:

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

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

Cela me donne 10 images pour toute la vidéo, peu importe la durée de la vidéo

Gus
la source