dokładne cięcie wideo (+ audio) za pomocą ffmpeg

10

Chcę, aby moja witryna umożliwiała użytkownikom dokładne tworzenie własnych klipów na podstawie dostarczonego przeze mnie wideo.

Mam źródłowy plik wideo, który najpierw chcę przekonwertować na coś odpowiedniego dla witryny:

Input #0, matroska,webm, from 'source.mkv': 
Duration: 00:28:18.57, start: 0.000000, bitrate: 10183 kb/s 
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 48 tbc (default)
Stream #0:1: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s (default)

Używam ffmpeg do konwersji w następujący sposób:

ffmpeg -i source.mkv -c:v libx264 -c:a aac -strict experimental -vf scale="960:-1" source.mp4

Oglądając ten film, jest on wystarczająco dobrej jakości i wystarczająco mały rozmiar pliku dla moich potrzeb, i ładuje / gra na mojej stronie.

Mam stronę internetową, która pozwala użytkownikom wybrać początek i punkt końcowy tego filmu - i utworzyć klip. Oto przykład polecenia ffmpeg, którego używam do tego:

-ss 577.920 -i source.mp4 -t 011.980 -codec:v copy -codec:a copy -vf scale="960:-1" clip1.mp4

Problem polega na tym, że klip nie zawsze jest wystarczająco dokładny czasowo. Zwykle dźwięk jest wystarczająco dokładny, ale wideo zatrzymuje się o pół sekundy wcześniej lub coś w tym rodzaju.

Czy jest jakiś sposób, aby to dokładne i niezsynchronizowane powiedzieć 0,2 sekundy?

EDYCJA: Dodawanie -force_key_frames 00:00:00.2nie pomogło.

EDYCJA: Zmieniłem przycinanie, aby używało -c:v libx264 -c:a aac -strict experimentalzamiast -codec:v copy -codec:a copyz dobrymi (ish) wynikami.

Plik może być odtwarzany zewnętrznie bez problemu - ale kiedy załaduję go do mojego elementu wideo HTML5 i odtworzę go, ostatnia część wideo (dźwięk jest w porządku) zawiesza się. Ostatnia część, która zamarza, trwa niecałą sekundę.

Czy powinienem spróbować z innym koderem wideo? Jaka jest najlepsza alternatywa dla libx264? Mając to na uwadze, prawdopodobnie będę chciał, aby było to na publicznej stronie internetowej.

Ale poczekaj, czy fakt, że gra dokładnie bez problemu z odtwarzaczem takim jak MPC lub Windows Media Player, nie sugeruje, że jest to problem z Google Chrome lub elementem wideo HTML? A może korzystam z nieobsługiwanego kodowania?

Pete Oakey
źródło
Może to mieć związek z synchronizacją klatek kluczowych. W każdym razie należy to przenieść na SuperUser.com.
Brad
Cześć, ffmpeg nie może wyciąć wideo w żadnym momencie, może wycinać tylko klatki kluczowe; z tego powodu dźwięk jest prawie precyzyjny, a wideo nie.
Czy mogę to sam przenieść? Spróbuję dodać klatki kluczowe do pliku źródłowego za pomocą -force_key_frames 00: 00: 00.2
Pete Oakey

Odpowiedzi:

9

Zachowanie -sszmian zależy od tego, czy zostanie użyte jako opcja wejściowa czy wyjściowa, i często jest wolniejsze, ale może być dokładniejsze, gdy jest używane jako opcja wyjściowa. Zobacz odpowiedź na ffmpeg powoli konwertuje wideo z określonego okresu, aby uzyskać więcej szczegółów i przykładów.

Aby zmienić jakość wyjściową, source.mp4użyj -crfopcji o wartości od 18 do 28 (domyślnie 23). Przykłady znajdują się w części CRF Podręcznika kodowania FFmpeg i x264 .

Polecenie przycinania można uprościć:

ffmpeg -ss 577.92 -i source.mp4 -ss 0 -t 11.98 -c copy -map 0 clip1.mp4

Wymieniłem -codec:v copy -codec:a copyz -c copy -map 0. Spowoduje to skopiowanie wszystkich strumieni zamiast tylko pierwszych strumieni wideo i audio - chociaż wejście ma tylko dwa strumienie ze względu na poprzednie polecenie. Ponieważ nie można skalować bez ponownego kodowania, dlatego wzajemnie się wykluczają -codec:v copy, a ponieważ dane wejściowe są już skalowane do ustawionego rozmiaru, usunąłem opcje filtrów.

Jeśli nadal nie jest wystarczająco dokładny, spróbuj:

ffmpeg -i source.mp4 -ss 577.92 -t 11.98 -c copy -map 0 clip1.mp4

Będzie wolniejszy, ale prawdopodobnie dokładniejszy. Zobacz linki w odpowiedzi w pierwszym linku, który podałem, opis różnic między tymi dwoma przykładami.

Wreszcie, należy uruchomić source.mp4poprzez qt-faststart(znajduje się w katalogu Narzędzia w źródle ffmpeg) lub użyj -movflags faststartopcji. Spowoduje to przeniesienie niektórych danych na początek pliku, dzięki czemu będzie można rozpocząć odtwarzanie przed całkowitym pobraniem.

Llogan
źródło
+1 za wskazówki, ale próbowałem ffmpeg -i source.mp4 -ss 577.92 -t 011.980 -c kopiuj -mapa 0 clip1.mp4 ale pierwsza część (prawie sekunda) i ostatnia część (może ćwierć sekundy) brakowało wideo, ale dźwięk jest w porządku.
Pete Oakey,
@PeteOakey Czy próbowałeś wycinać bez kopiowania bitstream, ale rzeczywiste ponowne kodowanie?
slhck
Próbowałem bez kopii strumienia bitów - wyniki dołączone do mojego pytania.
Pete Oakey,
3
Użycie -ssjako opcji wyjściowej zamiast opcji wejściowej naprawiło mój problem: pierwsza klatka wideo miała około 1s w wyjściowym wideo, z wcześniejszym tylko dźwiękiem (również potwierdzonym przez ffprobe -show_frames). Przechodzenie -sspo -inim spowodowało, że wyprowadzał klatki audio i wideo począwszy od klatki 0.
CodeManX