Twórz wideo z 5 obrazami z efektem ściemniania / ściemniania w ffmpeg

27

Z 5 obrazami muszę stworzyć film 60 sekund w ffmpeg, każdy obraz musi być wyświetlany przez 15 sekund. po 15 sekundach pierwszy obraz musi zanikać, a drugi obraz musi zanikać, następnie drugi obraz musi zanikać, trzeci obraz musi zanikać ... itd. Proszę o wskazówki, jak to osiągnąć za pomocą komend ffmpeg.

użytkownik384847
źródło
4
Co próbowałeś, a następnie możemy Ci pomóc? To forum nie jest forum typu „proszę dać mi odpowiedź bez wykonywania jakiejkolwiek pracy”. Powiedziawszy to, podam ci link do dokumentacji ffmpeg fade - ffmpeg.org/ffmpeg-filters.html#fade
Mike Diglio

Odpowiedzi:

49

Dip / fade to black

Przewiń w dół, aby przejść do metody przenikania.

zanik przykład

Przykład, w którym każde zdjęcie jest wyświetlane przez 5 sekund, a każde ma zanikanie, które trwa 1 sekundę. Każde wejście obrazu ma tę samą szerokość, wysokość i przykładowy format obrazu. Jeśli różnią się wielkością, patrz przykład nr 3 poniżej.

Wyjście MP4

ffmpeg \
-loop 1 -t 5 -i input0.png \
-loop 1 -t 5 -i input1.png \
-loop 1 -t 5 -i input2.png \
-loop 1 -t 5 -i input3.png \
-loop 1 -t 5 -i input4.png \
-filter_complex \
"[0:v]fade=t=out:st=4:d=1[v0]; \
 [1:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" out.mp4

Z dźwiękiem

To samo co powyżej, ale z dźwiękiem:

ffmpeg \
-loop 1 -t 5 -i input0.png \
-loop 1 -t 5 -i input1.png \
-loop 1 -t 5 -i input2.png \
-loop 1 -t 5 -i input3.png \
-loop 1 -t 5 -i input4.png \
-i audio.m4a \
-filter_complex \
"[0:v]fade=t=out:st=4:d=1[v0]; \
 [1:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" -map 5:a -shortest out.mp4

Do obrazów wejściowych o różnych lub dowolnych rozmiarach

Jak w pierwszym przykładzie, ale z obrazami wejściowymi, które różnią się szerokością x wysokości. Zostaną wypełnione, aby zmieściły się w pudełku 1280 x 720:

ffmpeg \
-loop 1 -t 5 -i input0.png \
-loop 1 -t 5 -i input1.png \
-loop 1 -t 5 -i input2.png \
-loop 1 -t 5 -i input3.png \
-loop 1 -t 5 -i input4.png \
-filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=out:st=4:d=1[v0]; \
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" out.mp4

Zobacz przykłady w sekcji Zmiana rozmiaru filmów, aby zmieściły się w odtwarzaczu o rozmiarze statycznym, jeśli chcesz przyciąć (wypełnić ekran) zamiast padu (letterbox / pillarbox) lub jeśli chcesz zapobiec skalowaniu.

Wyjście GIF

Dodaje filtry z Jak przekonwertować wideo na GIF przy użyciu ffmpeg, z rozsądną jakością?

ffmpeg \
-framerate 10 -loop 1 -t 5 -i input0.png \
-framerate 10 -loop 1 -t 5 -i input1.png \
-framerate 10 -loop 1 -t 5 -i input2.png \
-framerate 10 -loop 1 -t 5 -i input3.png \
-framerate 10 -loop 1 -t 5 -i input4.png \
-filter_complex \
"[0:v]fade=t=out:st=4:d=1[v0]; \
 [1:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,split[v0][v1]; \
 [v0]palettegen[p];[v1][p]paletteuse[v]" -map "[v]" out.gif

Skorzystaj z -loopopcji wyjściowej, aby kontrolować liczbę pętli GIF. Domyślnie jest to pętla nieskończona, jeśli ta opcja nie jest używana. Wartością -1jest brak pętli.

Zastosowane opcje i filtry:

  • -t aby ustawić czas trwania w sekundach dla każdego wejścia.

  • -loop 1 zapętla obraz, w przeciwnym razie miałby czas trwania 1 klatki.

  • -framerateaby ustawić liczbę klatek na sekundę obrazu wejściowego (domyślnie, gdy wartość niezadeklarowana to 25). Przydatny do tworzenia GIF-ów.

  • skaluj za pomocą pada, aby dopasować obrazy wejściowe do określonego, jednolitego rozmiaru (zastosowanego w przykładzie # 3).

  • zanikanie, zanikanie i zanikanie. dto czas trwania zanikania. stjest kiedy się zaczyna.

  • concat, aby połączyć (lub „połączyć”) każdy obraz.

  • format do wyprowadzania schematu podpróbkowania kolorów, który jest kompatybilny z odtwarzaczami nieopartymi na FFmpeg, jeśli wyprowadza MP4 i koduje z libx264 (domyślny koder dla wyjścia MP4, jeśli jest obsługiwany przez twoją kompilację).

  • podzielić, aby wykonać kopie danych wyjściowych filtra. Potrzebne przez filtry palety * do robienia wszystkiego za pomocą jednego polecenia.

  • palettegen i paletteuse do tworzenia ładnie wyglądającego GIF-a.


Crossfade

przykład crossfade

Przykład, w którym każde zdjęcie jest wyświetlane przez 5 sekund, a każde ma efekt przejścia, który trwa 1 sekundę. Każde wejście obrazu ma tę samą szerokość, wysokość i przykładowy format obrazu. Jeśli różnią się wielkością, dostosuj przykład 3 powyżej.

Wyjście MP4

ffmpeg \
-loop 1 -t 5 -i 1.png \
-loop 1 -t 5 -i 2.png \
-loop 1 -t 5 -i 3.png \
-loop 1 -t 5 -i 4.png \
-loop 1 -t 5 -i 5.png \
-filter_complex \
"[1]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+4/TB[f0]; \
 [2]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+8/TB[f1]; \
 [3]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+12/TB[f2]; \
 [4]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+16/TB[f3]; \
 [0][f0]overlay[bg1];[bg1][f1]overlay[bg2];[bg2][f2]overlay[bg3]; \
 [bg3][f3]overlay,format=yuv420p[v]" -map "[v]" -movflags +faststart out.mp4

Z dźwiękiem

ffmpeg \
-loop 1 -t 5 -i 1.png \
-loop 1 -t 5 -i 2.png \
-loop 1 -t 5 -i 3.png \
-loop 1 -t 5 -i 4.png \
-loop 1 -t 5 -i 5.png \
-i music.mp3 \
-filter_complex \
"[1]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+4/TB[f0]; \
 [2]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+8/TB[f1]; \
 [3]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+12/TB[f2]; \
 [4]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+16/TB[f3]; \
 [0][f0]overlay[bg1];[bg1][f1]overlay[bg2];[bg2][f2]overlay[bg3]; \
 [bg3][f3]overlay,format=yuv420p[v]" -map "[v]" -map 5:a -shortest -movflags +faststart out.mp4

Przejście między dwoma filmami z dźwiękiem

Wybierz 5 sekundowy segment z każdego wejścia i dodaj 1 sekundowe przenikanie:

ffmpeg -i input0.mp4 -i input1.mp4 -filter_complex \
"[0:v]trim=start=5:end=10,setpts=PTS-STARTPTS[v0];
 [1:v]trim=start=12:end=17,setpts=PTS-STARTPTS+4/TB,format=yuva444p,fade=st=4:d=1:t=in:alpha=1[v1];
 [v0][v1]overlay,format=yuv420p[v];
 [0:a]atrim=start=5:end=10,asetpts=PTS-STARTPTS[a0];
 [1:a]atrim=start=12:end=17,asetpts=PTS-STARTPTS[a1];
 [a0][a1]acrossfade=d=1[a]" \
-map "[v]" -map "[a]" output.mp4

Wyjście GIF

ffmpeg \
-framerate 10 -loop 1 -t 5 -i 1.png \
-framerate 10 -loop 1 -t 5 -i 2.png \
-framerate 10 -loop 1 -t 5 -i 3.png \
-framerate 10 -loop 1 -t 5 -i 4.png \
-framerate 10 -loop 1 -t 5 -i 5.png \
-filter_complex \
"[1]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+4/TB[f0]; \
 [2]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+8/TB[f1]; \
 [3]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+12/TB[f2]; \
 [4]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+16/TB[f3]; \
 [0][f0]overlay[bg1];[bg1][f1]overlay[bg2];[bg2][f2]overlay[bg3];[bg3][f3]overlay,split[v0][v1]; \
 [v0]palettegen[p];[v1][p]paletteuse[v]" -map "[v]" out.gif

Skorzystaj z -loopopcji wyjściowej, aby kontrolować liczbę pętli GIF. Domyślnie jest to pętla nieskończona, jeśli ta opcja nie jest używana. Wartością -1jest brak pętli.

Llogan
źródło
1
@ LordNeckbeard, dzięki za tę odpowiedź, użyłem jej na inny przykład. Czy dobrze zrozumiałem, że liczba następująca -tw -loop 1 -t 1 -i 001.pngokreśla czas trwania poszczególnych ramek, a liczba następująca T/w filter_complexbloku określa czas trwania przejścia? I czy w tym przykładzie liczony jest czas trwania ramki, w tym czas przejścia, czy nie?
cincplug
1
@Nisarg To nie wydaje się być kompletnym wyjściem i nie jestem pewien, jakie to polecenie z dwóch wyświetlonych wcześniej. W każdym razie spróbuj dodać -preset ultrafast.
llogan
1
@ LordNeckbeard Muszę połączyć zestaw zdjęć, klipów wideo i ścieżkę audio, aby utworzyć pojedynczy plik wideo (najlepiej ogg, ale w tym momencie jest to mniej istotne). Ponadto muszę stworzyć efekty przejścia między sąsiadującymi obrazami. Czy jest jakiś sposób na wykonanie skryptu dla całego zadania przy użyciu ffmpeg i / lub innych narzędzi wiersza poleceń? Celem jest zautomatyzowanie zadania za pomocą interfejsu wiersza poleceń.
Użytkownik sieci Web,
1
@WebUser Transitions prawdopodobnie będzie łatwiejszy w użyciu melt.
llogan
2
Podejście ffmpeg działa dla mnie dobrze; dzięki! Jedna wskazówka dla początkujących na stronie; w concat=n=9części polecenia 9pochodzi z 5 obrazów w przykładzie + 4 przejścia między obrazami. Jeśli masz do czynienia z inną liczbą zdjęć, musisz odpowiednio to zmienić.
Jim Miller
4

Napisałem ogólny skrypt bash, który pobiera ścieżkę do folderu obrazów i wyświetla ffmpeg wideo crossfade:

https://gist.github.com/anguyen8/d0630b6aef6c1cd79b9a1341e88a573e

Skrypt zasadniczo przegląda obrazy w folderze i wypisuje polecenie, które jest podobne do odpowiedzi @ LordNeckbeard powyżej, i wykonuje polecenie. Ten skrypt pomaga, gdy masz wiele obrazów w folderze i nie chcesz ręcznie wpisywać przygnębiająco długiego polecenia.

anh_ng8
źródło
Przykro nam, ale skrypt nie działa z ffmpeg 3.0.1, przy wejściach od 0 do 4 zwraca: „Niepoprawny indeks pliku 5 w opisie
filtru filtrowego
TobySpeight: dobra uwaga, zredagowałem odpowiedź, aby była bardziej przejrzysta. Zasadniczo główny pomysł jest już podany przez @LordNeckbeard powyżej. Ten skrypt po prostu uogólnia na wiele obrazów.
anh_ng8