Mój cel; wyeksportuj serię obrazów z pliku wideo za pomocą ffmpeg. Myślę, że mój problem dotyczy ramek na sekundę i szybkości transmisji.
Próbowałem następującej komendy: ffmpeg -i myVideo.mp4 -r 1 images_%04d.jpg
ale jakoś na 45 sekundowym filmie kończę na 47 zdjęciach. To bardzo ważne, że rozumiem to dokładnie. Nie będę z góry wiedział, jakie są odpowiednie FPS lub szybkości transmisji bitów, jeśli potrzebuję tych wartości podczas uruchamiania polecenia, muszę być w stanie jakoś wyciągnąć je z ffmpeg.
Rozważałem również eksport WSZYSTKICH obrazów na wideo za pomocą ffmpeg -i myVideo images_%04d.jpg
i podzielenie liczby obrazów przez całkowitą liczbę sekund w filmie. To da mi coś w rodzaju 24,97, a zaokrąglę do 25 i usunę 24 z 25 klatek. Obawiam się, że jeśli plik jest VBR, a części o wysokiej szybkości transmisji bitów znajdują się na początku filmu, ramki, które kończę, nie będą dokładnie odpowiadały 1 na sekundę. Na przykład 30. obraz może rzeczywiście pojawić się w filmie bliżej drugiego 31.
running ffmpeg -> ffmpeg -i "/videos/11.mp4" -s "352x264" "/images/image%06d.jpg" FFmpeg version 0.6-4:0.6-2ubuntu6.1, Copyright (c) 2000-2010 the FFmpeg developers built on Mar 31 2011 18:43:47 with gcc 4.4.5 configuration: --extra-version=4:0.6-2ubuntu6.1 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-vaapi --enable-pthreads --enable-zlib --enable-libvpx --disable-stripping --enable-runtime-cpudetect --enable-gpl --enable-postproc --enable-x11grab --enable-libdc1394 --enable-shared --disable-static libavutil 50.15. 1 / 50.15. 1 libavcodec 52.72. 2 / 52.72. 2 libavformat 52.64. 2 / 52.64. 2 libavdevice 52. 2. 0 / 52. 2. 0 libavfilter 1.19. 0 / 1.19. 0 libswscale 0.11. 0 / 0.11. 0 libpostproc 51. 2. 0 / 51. 2. 0 Seems stream 1 codec frame rate differs from container frame rate: 49938.00 (49938/1) -> 24.97 (24969/1000) Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/videos/11.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: isomavc1mp42 Duration: 00:00:32.60, start: 0.000000, bitrate: 433 kb/s Stream #0.0(und): Audio: aac, 44100 Hz, stereo, s16, 127 kb/s Stream #0.1(und): Video: h264, yuv420p, 352x264 [PAR 1:1 DAR 4:3], 303 kb/s, 24.97 fps, 24.97 tbr, 24969 tbn, 49938 tbc Output #0, image2, to '/images/image%06d.jpg': Metadata: encoder : Lavf52.64.2 Stream #0.0(und): Video: mjpeg, yuvj420p, 352x264 [PAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 90k tbn, 24.97 tbc Stream mapping: Stream #0.1 -> #0.0 Press [q] to stop encodingframe= 176 fps= 0 q=24.8 size= -0kB time=7.05 bitrate= -0.0kbits/s ^Mframe= 312 fps=236 q=24.8 size= -0kB time=12.50 bitrate= -0.0kbits/s ^Mframe= 316 fps=112 q=24.8 size= -0kB time=12.66 bitrate= -0.0kbits/s ^Mframe= 322 fps= 55 q=24.8 size= -0kB time=12.90 bitrate= -0.0kbits/s ^Mframe= 327 fps= 39 q=24.8 size= -0kB time=13.10 bitrate= -0.0kbits/s ^Mframe= 331 fps= 33 q=24.8 size= -0kB time=13.26 bitrate= -0.0kbits/s ^Mframe= 336 fps= 31 q=24.8 size= -0kB time=13.46 bitrate= -0.0kbits/s ^Mframe= 339 fps= 27 q=24.8 size= -0kB time=13.58 bitrate= -0.0kbits/s ^Mframe= 344 fps= 22 q=24.8 size= -0kB time=13.78 bitrate= -0.0kbits/s
Czy ktoś ma pomysły, jak uzyskać dokładne wyniki, eksportując obrazy z wideo za pomocą ffmpeg? Dzięki!
Odpowiedzi:
Czy na pewno tracisz ramki? Twój film wejściowy to h264, który obsługuje zmienną częstotliwość klatek. aby uzyskać szczegółowe informacje na temat każdej ramki, polecam następujące czynności:
W ten sposób dowiesz się, ile klatek ma Twój film.
Możesz uniknąć zmiennej liczby klatek na sekundę, konwertując film na wideo o zmiennej liczbie klatek, używając
-r float
argument, a następnie eksportowanie zdjęć (jak w poleceniu).źródło
Musisz ręcznie określić a
-vsync
wartość. Rozbieżność jest najprawdopodobniej spowodowana różnicą w zmiennej / stałej szybkości klatek i znacznikach czasu ramki. Jeśli masz źródło VFR, ffmpeg domyślnie spróbuje wycelować szacunkowy współczynnik (tbr
wartość) i upuszcza lub powiela ramki w celu „wygładzenia” ruchu. Eksportowanie klatek jako obrazów jest również zgodne z tym zachowaniem. Niektóre informacje z dokumentacji:Jak mówi tutaj, ffmpeg wybierze
-vsync -1
domyślnie (zarówno dla kodowania wideo, jak i eksportowania obrazów). To, czego chcesz, to proste przejście bez zmian. Posługiwać się-vsync 0
jeśli chcesz zachować każdą ramkę bez żadnych kropli lub duplikatów. Prawdopodobnie otrzymasz wiadomości o nie Monotonicznym DTS, ale można to w dużej mierze zignorować. Oto przykładowe polecenie do dokładnego wyświetlania wszystkich klatek z filmu:źródło
Zaobserwowałem podobne błędne zachowanie podczas wyodrębniania obrazów za pomocą argumentu -r.
Znalazłem rozwiązanie, które działało dla mnie, używając opcji -vf fps = X (z kilkoma ważnymi uwagami poniżej). Wierzcie lub nie, zachowanie tutaj wydaje się bardziej przewidywalne niż zachowanie z -r.
ffmpeg -i input.mp4 -vf fps=1.0/x image-%04d.jpg
na przykład, aby uzyskać 2 obrazy na sekundę:
ffmpeg -i input.mp4 fps=0.5 image-%04d.jpg
To zrobi prawie właściwą rzecz, zauważ, że:
-vf fps=X
, zaczynając od X / 2 sekund.Tak więc działa:
ffmpeg -i input.mp4 fps=1 image-%04d.jpg
W przypadku 5-sekundowego wideo powstanie 6 plików, pierwszy powinien zostać zignorowany, a 2–6 będzie oznaczać znaczniki czasu: 0,5, 1,5, 2,5, 3,5 i 4,5.
Oto przydatne wideo testowe do debugowania tego rodzaju rzeczy:
https://drive.google.com/file/d/0B56RokrDs3xabS1TS19wRjlBaVk/view?usp=sharing
źródło