Dokładnie wytnij pliki wideo z wiersza poleceń

22

Mam problem ze znalezieniem aplikacji cli, która może pobrać plik wideo (najlepiej avi, mkv i mp4) i wyciąć bardzo krótkie klipy (2-6 sekund) z dokładnością do czasu. Próbowałem ffmpeg , mencoder , avidemux i mp4box, ale wszystkie wycinały klatki kluczowe, które tworzą ponad 6 sekund klipów. Czy istnieje narzędzie, które ponownie zakoduje plik wejściowy i skróci dokładny czas lub skróci niedokładnie, ponownie zakoduje, a następnie dokona dokładnego cięcia?

curmil
źródło
Prawdopodobnie będziesz musiał ponownie kodować przed cięciem, aby zrobić to poprawnie. Prawdopodobnie możesz przyspieszyć, wycinając otaczające klatki kluczowe i ponownie kodując tylko fragmenty.
Nifle,
4
Którego polecenia FFmpeg dokładnie wypróbowałeś? Wierzę, że jeśli zdekodujesz wideo wcześniej (tj. Umieścisz -ssparametr po -i ), powinno być dokładniejsze.
slhck,
1
Sztuczka FFmpeg zadziałała! Nie zdawałem sobie sprawy, że kolejność ma tak duże znaczenie. Czy to samo dotyczy innych narzędzi?
curmil,

Odpowiedzi:

23

Cięcie wideo za pomocą ffmpeg

Państwo może precyzyjnie wyciąć filmy z FFmpeg. Od wersji 2.5 jest to bardzo łatwe. Skróciłoby to na przykład 10 sekund, zaczynając od 0 minut, 3 sekund i 123 milisekund.

ffmpeg -ss 00:00:03.123 -i input.mp4 -t 10 -c:v libx264 -c:a copy out.mp4

Pozycja i czas mogą być w sekundach lub w hh:mm:ss[.xxx]formie.

Należy zauważyć, że w tych przykładach wideo zostanie ponownie zakodowane przy użyciu kodera x264 ; dźwięk jest kopiowany.

Możesz także użyć -tozamiast, -taby określić punkt końcowy zamiast czasu trwania. W tym przypadku jest to jednak -torównoważne -t, ponieważ umieszczając -ssprzed nim -i, ffmpeg najpierw szuka tego punktu, a następnie zaczyna generować.

Zobacz także wpis Wiki w poszukiwaniu .


Dokładne cięcie dla starszych ffmpegwersji

Jeśli masz starszą wersję ffmpeg, a następnie w celu dokładnego wyszukiwania, musisz umieścić -sspóźniej -i, co powoduje, że proces kodowania jest nieco wolniejszy, ponieważ najpierw należy zdekodować cały film:

ffmpeg -i input.mp4 -ss 00:00:03.123 -t 10 -c:v libx264 -c:a copy out.mp4

Tutaj, -toi -tzachowywać się inaczej. -t 10utworzy klip o długości 10 sekund, -to 10a klip o długości siedmiu sekund.

slhck
źródło
Zamiast tego -c:v libx264 -c:a libfaacmyślę, że możemy użyć polecenia, -acodec copy -vcodec copyktóre mówi ffmpeg, aby wykrył i używał tych samych kodeków co oryginalny plik. Czy ktoś może potwierdzić?
Baodad
2
@Baodad Możesz, ale to nie będzie dokładnie wyciąć. Podczas kopiowania strumieni bitów wideo / audio, ffmpeg musi zaczynać się od klatki kluczowej, która może być umieszczana co sekundę lub nawet dalej.
slhck
Jak pokonać błąd „Nieznany koder„ libfaac ”?
Doug
@Doug Wybierz na przykład inny koder -c:a aac -strict experimental. To najprostsze rozwiązanie.
slhck 24.0415
1

Jedynym dotychczasowym narzędziem wiersza polecenia systemu Linux, które można wycinać z dokładną klatką (lub, z dokładnością do ramki), jest melt( sudo apt-get install melt).

Powiedzmy, że masz inputvid.mp4- najpierw sprawdź ustawienia kodowania za pomocą say ffmpeg(tutaj, po prostu mówię, że chcę go ponownie zakodować -f mp4, ale jako plik, /dev/nullwięc dane wyjściowe są odrzucane; przekierowuję stderr, dzięki czemu mogę grep przez to - uwaga na środku) , polecenie wyświetla monit i powinieneś odpowiedzieć yklawiszem ENTER, więc proces jest kontynuowany i zrzuca użyteczne informacje; jest to wersja ffmpeg 3.3.3 na Ubuntu 14):

ffmpeg -i inputvid.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], 389 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 95 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p(progressive), 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

Ok, więc możemy zobaczyć ffmpegwybory libx264i aackodery tego filmu; możemy wprowadzić to dla melt:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac vcodec=libx264

.... i meltbędzie wyciąć z kawałka między ramkami 7235 i 7349 do nowego pliku cut.mp4. Następnie, aby sprawdzić, czy cut.mp4pętle działają poprawnie, użyj meltponownie, aby odtworzyć go dwukrotnie - i odtworzyć w oknie SDL:

melt cut.mp4 cut.mp4 -consumer sdl

... a oto, co ffmpegwidzi ten plik:

ffmpeg -i cut.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'    encoder         : Lavf54.20.4
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 526 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 182 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

Ustawienia kodowania wideo cut.mp4wydają się być identyczne, z inputvid.mp4wyjątkiem zmienionej przepływności wideo z 389 kb / s do 526 kb / s, a także ustawienia kodowania audio są prawie takie same, z wyjątkiem częstotliwości próbkowania zmienionej z 44100 na 48000 Hz; chociaż można to regulować za pomocą:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac ar=44100 ab=95k vcodec=libx264 vb=389k

... jednak nawet przy tym końcowa szybkość transmisji wideo dla mnie wynosi 337 kb / s. Mimo to cięcia są w porządku (i obejmuje to dźwięk) podczas odtwarzania w pętli, więc sądzę, że jest to rzeczywiście dokładność klatek ...

sdaau
źródło
1
meltponownie koduje wideo i korzysta z bibliotek FFmpeg pod spodem. Jeśli zezwolisz na ponowne kodowanie, ffmpeg może wygenerować to samo wyjście.
Gyan
Dzięki @Gyan - nie byłem tego świadomy (zwłaszcza, że meltkorzysta z bibliotek FFmpeg), dobrze wiedzieć!
sdaau
topienie wygląda na łatwiejsze w użyciu niż ffmpeg, wszystko czego potrzebujemy to sposób, aby określić czasy, szczególnie czasy w postaci godzin, minut, sekund lub godzin, minut, sekund, ms, które konwertują je do właściwej ramki.
barlop
0

Jak powiedział Baodad w komentarzach (zamieszczam, ponieważ nie jest łatwo znaleźć, jeśli czytasz szybko), lepszym podejściem jest automatyczne wykrywanie koderów audio / wideo przez ffmpeg, więc:

ffmpeg -ss 00:05:17.18 -i in.mp4 -t 00:06:29.10 -acodec copy -vcodec copy out.mp4 
  • start @ 00: 05: 17.18
  • input = in.mp4
  • stop @ 00: 06: 29.10
  • wyjście = out.mp4
Gilles Quenot
źródło
2
Nie powoduje to ponownego kodowania i nie zapewnia dokładności ramki.
Andrea Lazzarotto,