Wersja TL; DR:
W tym przykładzie wykonuje się tylko wideo, zakładając, że oba klipy wideo mają tę samą rozdzielczość, szybkość klatek itp. Spowoduje to 1-sekundowe przenikanie pomiędzy fadeoutclip i fadeinclip. Załóżmy, że wyciszenie trwa 10 sekund. Zauważ, że jest to sformatowane dla jasności: tak naprawdę jest to jeden wiersz kodu.
ffmpeg -i fadeoutclip.mp4 -i fadeinclip.mp4 -an \
-filter_complex "\
[0:v]trim=start=0:end=9,setpts=PTS-STARTPTS[firstclip]; \
[1:v]trim=start=1,setpts=PTS-STARTPTS[secondclip]; \
[0:v]trim=start=9:end=10,setpts=PTS-STARTPTS[fadeoutsrc]; \
[1:v]trim=start=0:end=1,setpts=PTS-STARTPTS[fadeinsrc]; \
[fadeinsrc]format=pix_fmts=yuva420p, \
fade=t=in:st=0:d=1:alpha=1[fadein]; \
[fadeoutsrc]format=pix_fmts=yuva420p, \
fade=t=out:st=0:d=1:alpha=1[fadeout]; \
[fadein]fifo[fadeinfifo]; \
[fadeout]fifo[fadeoutfifo]; \
[fadeoutfifo][fadeinfifo]overlay[crossfade]; \
[firstclip][crossfade][secondclip]concat=n=3[output] \
" \
-map "[output]" <add in encoding part here>
Pełna wersja:
Oto wyjaśnienie, o co w tym wszystkim chodziło:
Specyfikacja wejściowa ... oczywista
ffmpeg -i fadeoutclip.mp4 -i fadeinclip.mp4 -an
Tworzenie filter_complex
: zakładając, że już rozumiesz kompleksy filtrów:
-filter_complex
Najpierw rozbieramy dwa strumienie na dwa kawałki, używając filtru przycinania : zawartość i sekcja przenikania. Wyciszenie jest podzielone na zawartość i sekcję przenikania, podczas gdy wyciszanie jest dzielone na sekcję przenikania i zawartość. Łącznie cztery sekcje.
Zauważ, że ściśle mówiąc, nie musimy rozdzielać przekrojów: MUSIMY po prostu określić czasy zanikania i zanikania dla dwóch klipów wideo. Jednak w ten sposób:
- Postępuj zgodnie z metodologią używaną zwykle przez edytory wideo GUI
- Unikaj frustrującej złożoności
overlay
użytkowania filtra
- Upewnij się, że rozwiązanie jest tak ogólne, jak to możliwe (tj. Kod wielokrotnego użytku)
- Pozwól nam wstępnie przetworzyć i przetworzyć sekcję crossfade w razie potrzeby (nie zrobiono tutaj)
Każda z tych czterech sekcji określa: czas rozpoczęcia (sekundy), czas zakończenia (sekundy) oraz tajemniczy setpts=PTS-STARTPTS
filtr , który zasadniczo powoduje, że każdy klip wideo rozpoczyna się od 0 sekund. Będzie to miało zasadnicze znaczenie podczas ich ponownego łączenia.
Zauważ, że s=0
specyfikatory są redundantne, a setpts
filtr dla s=0
nich jest również redundantny. Oba są jednak nadmiarowe, aby umożliwić zmianę czasu rozpoczęcia od 0, bez naruszania kompleksu filtrów. Ponadto drugi klip zawartości biegnie do końca, więc e=
część (end =) nie jest określona.
[0:v]trim=s=0:e=9,setpts=PTS-STARTPTS[firstclip];
[1:v]trim=s=1,setpts=PTS-STARTPTS[secondclip];
[0:v]trim=s=9:e=10,setpts=PTS-STARTPTS[fadeoutsrc];
[1:v]trim=s=0:e=1,setpts=PTS-STARTPTS[fadeinsrc];
Następnie określamy przenikanie i zanikanie: Najpierw dodajemy kanał alfa (przezroczystość) do obu sekcji przenikania, określając format pikseliyuva420p
. Możesz użyć dowolnego formatu, który zapewnia kanał alfa.
Następna w tym filtrze subcomplex określamy jedną zgaśnie, a jeden zanikać w. The alpha=1
oznacza, że sam film nie zostanie wygaszony, tylko ilość przejrzystość „Fade”. st
oznacza początek, d
oznacza czas trwania.
[fadeinsrc]format=pix_fmts=yuva420p,
fade=t=in:st=0:d=1:alpha=1[fadein];
[fadeoutsrc]format=pix_fmts=yuva420p,
fade=t=out:st=0:d=1:alpha=1[fadeout];
Co to jest ?: Do fifo
filtrów zapewnia, że nie jest bufor przestrzeń dostępną w filtrze złożonym. O dziwo, NIE jest to ustawienie domyślne. Jeśli tego nie zrobisz, crossfade może się nie udać, jeśli wynik powyższego etapu przekroczy filtr nakładki poniżej. Tak, wiem o czym teraz myślisz. To rzeczywiście błąd FFMPEG .
[fadein]fifo[fadeinfifo];
[fadeout]fifo[fadeoutfifo];
Teraz nałóż dwie sekcje przenikania : upewniając się, że dwie sekcje przenikania mają ten sam rozmiar, nie musimy się martwić o dość paskudne opcje, jakie ma filtr nakładki (dlatego je tutaj ignorujemy):
[fadeoutfifo][fadeinfifo]overlay[crossfade];
Na koniec, wyrównujemy nasze trzy segmenty za pomocą filtra konkat .
[firstclip][crossfade][secondclip]concat=n=3[output]
A teraz zamapuj pad wyjściowy jako źródło wideo.
NIE ZAPOMNIJ ustawić formatu piksela NA CO NORMALNIE UŻYWAĆ (zwykle yuv420p
), ponieważ sekcja przejścia pojawi się yuv420
na kanale wyjściowym! (ponieważ nie określiliśmy tego, możesz użyć argumentów nakładki) Oczywiście, jeśli CHCESZ yuv420
, to nic ci nie jest :-)
-map "[output]" <add your normal encoding part here>
Następnie można ponownie połączyć audio później (poza zakresem niniejszego pytania i odpowiedzi)