Jak połączyć klipy z tego samego wideo za pomocą ffmpeg

15

Mam długi film z różnymi scenami. Chcę wyodrębnić i połączyć 2 sceny z filmu (które nie zaczynają się na ramce I) za pomocą ffmpeg 2.1.4.

Jako argument, powiedz, że chcę 5 sekund od 01:00 i 02:00.

Mogę to zrobić:

ffmpeg -ss 01:00 -i in.mkv -ss 02:00 -i in.mkv -filter_complex "
  [0:v]select='lt(t,5)'[v0];
  [0:a]aselect='lt(t,5)'[a0];
  [v0][a0][1:v][1:a]concat=n=2:v=1:a=1
" -c:a libvorbis -t 10 out.mkv

To daje mi film, który chcę, ale wybranie faktycznie zmusza ffmpeg do odkodowania całej reszty filmu. Jak mam to zrobić, aby skrócić pierwszy film zamiast go dekodować?

Wolałbym to zrobić z filtrem złożonym ffmpeg, jeśli to możliwe. Wiem, że mogę po prostu -tnajpierw przekodować osobne filmy, ale dodatkowy krok kodowania jest w moim przypadku bardzo powolny i również traci dobrą jakość tego filmu.

Nie mogę znaleźć filtra, który skraca długość pary. Czy istnieją węzły filtrów odpowiadające parametrom -tlub -ss?

scubed
źródło

Odpowiedzi:

16

filtr konkat

Ta metoda jest najlepsza, jeśli chcesz wykonać dodatkowe filtrowanie:

Użyj trim, atrim, setpts, asetpts, i concatfiltry:

ffmpeg -i input -filter_complex \
"[0:v]trim=60:65,setpts=PTS-STARTPTS[v0]; \
 [0:a]atrim=60:65,asetpts=PTS-STARTPTS[a0]; \
 [0:v]trim=120:125,setpts=PTS-STARTPTS[v1];
 [0:a]atrim=120:125,asetpts=PTS-STARTPTS[a1]; \
 [v0][a0][v1][a1]concat=n=2:v=1:a=1[out]" \
-map "[out]" output.mkv
  • setptsi asetptszapobiegnie gwałtownemu wyjściu z powodu problemów ze znacznikiem czasu prezentacji.

  • Pamiętaj, aby użyć najnowszej wersji. Zobacz stronę pobierania FFmpeg, aby znaleźć łącza do kompilacji dla systemów Windows, OS X i Linux.


demultiplekser konkat

Inną metodą jest utworzenie segmentów osobno i skopiowanie ich strumieniowo zamiast ponownego kodowania (w celu zaoszczędzenia czasu i jakości) i połączenie ich z demuxerem konkat .

$ ffmpeg -ss 60 -i input -t 5 -codec copy clip1.mkv
$ ffmpeg -ss 120 -i input -t 5 -codec copy clip2.mkv
$ echo "file 'clip1.mkv'" > concat.txt
$ echo "file 'clip2.mkv'" >> concat.txt
$ ffmpeg -f concat -i concat.txt -codec copy output.mkv
Llogan
źródło
2
Ach, dzięki. brakowało mi wykończenia. Jednak zajmuje bardzo dużo czasu, aby przejść do określonego przeze mnie przesunięcia czasowego, tak jakby wszystko dekodowało. Ponadto w części wyjścia brakowało dźwięku. Aby to naprawić, wielokrotnie podałem to samo wejście za pomocą opcji -ss, a następnie użyj przycinania, aby obciąć wideo. W tym przypadku nie potrzebujesz ustawień, ponieważ ss ustawia pts na 0. To wydawało się działać i nie miało dziwnych przypadkowych przerw podczas kodowania. Jeśli chodzi o kopiowanie strumieni, próbowałem tego wcześniej. Zaczyna się od poprzedniej klatki I, więc dostajesz inną część filmu niż ta, którą chciałeś.
scubed
Czy mógłbyś odpowiedzieć na moje pytanie, to jest podobne do tego. video.stackexchange.com/questions/18247/…
Eftekhari 26.04.16
Co ciekawe, -filter_complexdziała, ale concatpliki nie - tzn. Pierwszy film wygląda dobrze, ale jakość drugiego jest okropna. Uwaga: skopiowałem te polecenia dokładnie dla obu (z wyjątkiem pliku wejściowego).
bobmarksie
7

To powinno działać szybciej ...

ffmpeg -ss 1:00 -t 5 -i in.mkv -ss 2:00 -t 5 -i in.mkv \
  -filter_complex "[0][1]concat=n=2:v=1:a=1" \ 
  out.mkv

Nie ma potrzeby podawania -t na wyjściu. Nie ma potrzeby dzielenia audio i wideo przed konkat.

William Frantz
źródło
1
Wykorzystuje to filtr konkat, który będzie wymagał ponownego kodowania. Może to być pożądane przez użytkownika.
llogan