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 -t
option 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' -t
option 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).
Réponses:
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:
Avec ffmpeg actuel, la syntaxe correcte serait:
la source
J'avais ce même problème et ma solution était la suivante:
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
la source