Klip do wyodrębniania FFmpeg - liczba klatek na sekundę różni się od liczby klatek na sekundę w pojemniku (x264, aac)

8

Podsumowanie
Wydaje się, że wideo H.264 ma naprawdę wysoką częstotliwość klatek, co wymaga współczynnika skalowania zastosowanego do czasu trwania filmu, który próbuję wyodrębnić (900x niższy).

Body
Próbuję wyodrębnić klip z filmu, który mam w formacie MP4 (utworzonym za pomocą Handbrake ). Po wypróbowaniu mencodera i VLC postanowiłem dać FFmpeg szansę, ponieważ było to najmniej kłopotliwe przy kopiowaniu kodeków. To znaczy, w porównaniu do mencodera i VLC, wynikowy plik był nadal odtwarzany w QuickTime (wiem o Perianie itp., Próbuję tylko dowiedzieć się, jak to wszystko działa).

W każdym razie moje polecenie było następujące:

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

Podczas kopiowania pojawia się:

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
…

Zamiast klipu o czasie trwania 5:59 dostaję całą resztę filmu. Aby to przetestować, uruchomiłem komendę ffmpeg -t 00:00:01. Dostałem dokładnie 15 minutowy klip. Więc zrobiłem trochę inżynierii czarnej skrzynki i zdecydowałem się skalować moją -topcję, obliczając jaką wartość wprowadzić, biorąc pod uwagę, że 1 sekunda została zinterpretowana jako 900 s. Dla mojego pożądanego klipu 359 s wyliczyłem 0,399 si moje polecenie ffmpeg stało się:

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

Działa to, ale nie mam pojęcia, dlaczego czas trwania jest skalowany o 900. Przy dalszym badaniu, każdy bieg ffmpeg ma linię:

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

45000/25 = 1800. Musi być gdzieś relacja. W jakiś sposób nieprzyzwoicie wysoka częstotliwość klatek powoduje problemy z timingiem. Jaka jest tak wysoka częstotliwość odświeżania? Najlepsze w tym wszystkim jest to, że wynikowy plik clip.mp4 ma dokładnie tę samą funkcję (ze względu na skopiowany kodek wideo), a pobieranie kolejnych klipów z tego wymaga takiego samego skalowania dla -topcji czasu trwania. Dlatego udostępniłem go wszystkim, którzy chcą to sprawdzić.

Dodatek
Preambuła ffmpeg w moim systemie (zbudowana przy użyciu portu ffmpeg 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)

EDYCJA
Nie jestem pewien, czy to był błąd, czy nie, ale wydaje się, że został teraz naprawiony w mojej obecnej wersji ffmpeg, przynajmniej dla tego filmu (wersja 0.6.1 z MacPorts).

fideli
źródło
Ponowne kodowanie nie jest rozwiązaniem, a wykonanie godzinnego dekodowania przez pięć minut treści jest nieuzasadnione i prawdopodobnie nie rozwiązałoby problemu. Świetne wstępne badania btw. Prawdopodobnie masz rację, zakładając, że wykrywanie fps ffmpeg jest źródłem problemu. Wygląda na to, że późniejsza wersja ffmpeg rozwiązała twój problem, ale zrobię komentarz. Poleciłbym wykonanie kopii -c do innego formatu kontenera. Może to mieć różne efekty, ale byłby to dobry kolejny krok do eksperymentowania.
dstob

Odpowiedzi:

1

W przypadku ffmpeg pozycjonowanie opcji ma znaczenie. W twoim przykładzie próbuje zastosować -ss i -t do danych wejściowych. Użyj tego w ten sposób, zamiast tego zastosujesz opcje do danych wyjściowych:

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

Przy obecnej ffmpeg poprawna składnia to:

ffmpeg -i outofsight.mp4 -ss 01:15:51 -t 00:05:59 -c copy clip.mp4
zła
źródło
1

Miałem ten sam problem, a moje rozwiązanie było następujące:

        $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);

To daje mi 10 zdjęć dla całego filmu, bez względu na jego długość

Gus
źródło