Wycinanie wideo dokładnie w ramkach za pomocą filtra wyboru ffmpeg

16

Czy zamiast wycinać filmy dla określonych numerów klatek zamiast używać -ssi -towyszukiwać parametry, które wydają się niezbyt dokładne? Na przykład;

ffmpeg -i video.webm -startingframe 80 -endingframe 560 output.webm

[80. ramka i 560. ramka w komplecie. Łącznie tworzy (560 - 80 +1) klatek]

Po odpowiedziach i drobnych poszukiwaniach wypróbowałem kilka poleceń. Ale jak dotąd nie mogłem znaleźć akceptowalnego sposobu.

Jeśli ktoś chce wyciąć strumień wideo między 250 a 750 klatkami, jest to odpowiedni sposób. Daje 501 klatek jako wynik:

Uwaga: film.mp4 ma 25 klatek na sekundę, a częstotliwość próbkowania audio 48k

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm

Zgodnie z oczekiwaniami wyjście ma dokładnie 20 sekund.

Używając tej samej metody dla dźwięku:

ffmpeg -i movie.mp4 -vn -af "aselect=between(n\,480\,1440),setpts=PTS-STARTPTS" a_stream.webm

Nieoczekiwanie ten ma bardzo słabą dokładność. Powinien dać mi 960001 (960k + 1) próbek, co odpowiada 20 sekundom dźwięku. Ale zamiast tego wynik wynosił 20,505 sekundy i zawiera 984240 próbek. Ponadto, jeśli zwiększę czas trwania, błąd również wzrośnie.

Następnie spróbowałem użyć parametru -ss -to do wycięcia strumienia audio:

ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm

Stary klasyczny sposób działa znacznie lepiej. Wyjście trwało 20,003 sekundy i zawiera 960144 próbek. Ponadto wydłużenie czasu trwania nie zwiększa błędu, błąd jest stały, zawsze istnieje 144 nadwyżek próbek z tym plikiem wejściowym.

Podsumowując: selectfiltr działa dobrze przez większość czasu, ale wybór nie. Klasyczne -ssparametry działają lepiej w przypadku dźwięku, ale nie są dokładne w próbkach. Ponadto nie można używać razem -vf selecti -ssparametrów razem, ponieważ -sswpłynie to zarówno na strumienie audio, jak i wideo, a my chcemy, aby wpływały tylko na dźwięk.

Aby dokładnie wyciąć plik multimedialny, muszę wykonać następujące 3 kroki:

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm 
ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm 
ffmpeg -i v_stream.webm -i a_stream.webm -c:v copy -c:a copy  movie-between_10th_and 20th_seconds.webm

To daje najdokładniejsze wyniki. Film ma długość 20 000 sekund, a dokładność klatek Audio ma długość 20,003 sekundy i próbkę 960144. Niezupełnie pasuje do strumienia wideo, ale jest OK. Jest tylko 144 nadwyżki próbek. Największym minusem jest to, że za każdym razem, gdy chcę wyciąć plik, muszę wysłać 3 polecenia do prostej pracy i tworzy on dwa niepotrzebne pliki: a_stream.webm i v_stream.webm. A selectfiltr nie działa na niektórych plików wejściowych próbowałem. Wykonuje zadanie pomyślnie (?), Ale nigdy nie zatrzymuje procesu kodowania, więc muszę za każdym razem zamykać wiersz polecenia.

destor
źródło
Przeczytałem tę stronę, zanim opublikowałem to pytanie. Ta strona mi nie pomogła. Jeśli dane wejściowe mają zmienną liczbę klatek na sekundę, czy możemy po prostu obliczyć, używając tego równania? Nie sądzę. Również nadal nie sądzę, że „-ss” da mi dokładną pozycję. Wydaje mi się, że szukanie klatka po klatce byłoby lepsze.
destor
Pamiętaj, że -ssma dokładność klatek (patrz tutaj ). Czy faktycznie masz zmienną liczbę klatek na sekundę? Moja odpowiedź prowadzi do wątku listy mailingowej, który wspomina za pomocą selectfiltrów, w których można określić numer ramki. Próbowałeś tego?
slhck
Próbowałem używać selecti aselectfiltrować strumienie wideo i audio. Selectma dokładność klatek dla wideo, ale aselectnie jest dokładny w próbce. W rzeczywistości jest to dalekie od dokładności. Daje to znacznie gorsze wyniki niż używanie prostych -ss -toparametrów. Z tego powodu na razie używam kombinacji selectfiltra i -ss -toparametrów, aby uzyskać jak najdokładniejsze cięcie. Ale jest to nieczysty sposób, aby to zrobić. Proszę spojrzeć na mój pierwszy post, dodałem kilka linii poleceń i ich wyniki
destor
wersja ffmpeg?
fie
Dlaczego mimo to próbujesz wyciąć numer klatki? Jeśli ktoś potrzebuje takiej dokładności, dlaczego nie skorzystać z avidemux? Być może twoje pierwotne problemy są spowodowane tym, że wybiera najbliższą klatkę kluczową?
fie

Odpowiedzi:

3

Dźwięk pochodzi z kilku sekund, a nie klatek, więc jeśli chcesz wyciąć wideo, musisz obliczyć liczbę klatek na sekundę × 20 sekund w następujący sposób: 20 sekund z 23,97 kl./s = 479,4

Wycinanie ramek nie jest dokładne, ponieważ nie można uzyskać pełnej liczby klatek na sekundę przez ostatnią sekundę, więc dźwięk będzie miał więcej sekund lub tylko pół sekundy lub trochę więcej lub mniej! Może powinieneś użyć sekund zamiast ramek, aby uzyskać dokładne cięcie, powiedz ffmpeg, aby zrobiło to za Ciebie. A jeśli dostaniesz 1 dodatkową ramkę, co powiesz na zmianę 250. i 750. na 250. i 749. ?! Użyj minus 1, aby zawsze uzyskać liczbę klatek, o którą prosisz!

Mojtaba Golestani
źródło
W rzeczywistości dźwięk pochodzi z próbek, a nie sekund ...
Anubioz