Ich arbeite an einem Projekt, bei dem ich ffmpeg verwende, um einige Videodateien stapelweise zu konvertieren und Ein-/Ausblendeffekte am Anfang und Ende jedes Clips hinzuzufügen.
Ich habe diesen Codeabschnitt verwendet, um den Fade/Out-Effekt auf Clips mit bekannter Dauer hinzuzufügen:
ffmpeg -i clip.mp4 -filter:v 'fade=in:0:30,fade=out:9650:30' -c:v libx264 -crf 22 -preset veryfast -c:a copy fadeInOut.mp4
Meine zwei Fragen lauten:
Danke!
#1 Zum gleichzeitigen Ein-/Ausblenden des Tons:
ffmpeg -i clip.mp4 -vf 'fade=in:0:30,fade=out:960:30'
-af 'afade=in:st=0:d=1,afade=out:st=32:d=1'
-c:v libx264 -crf 22 -preset veryfast fadeInOut.mp4
Die Afade-Zeiten sind in Sekunden angegeben .
#2 Automatisch? Nein. Aber siehe Problemumgehung unten
Sie können zuerst ffprobe ausführen, um die Dauer zu erhalten.
ffprobe -i clip.mp4 -show_entries stream=codec_type,duration -of compact=p=0:nk=1
Sie erhalten so etwas:
video|13.556000
audio|13.816000
Sie können dann das obige verwenden, um Ihre Überblendungen zu platzieren. Diese Zeiten sind in Sekunden angegeben.
Problemumgehung
ffmpeg -i clip.mp4 -sseof -1 -copyts -i clip.mp4 -filter_complex
"[1]fade=out:0:30[t];[0][t]overlay,fade=in:0:30[v];
anullsrc,atrim=0:2[at];[0][at]acrossfade=d=1,afade=d=1[a]"
-map "[v]" -map "[a]" -c:v libx264 -crf 22 -preset veryfast -shortest fadeInOut.mp4
FFmpeg hat eine sseof
Option, mit der man eine Eingabe vom Ende suchen kann. Das können wir nutzen, um unser Ziel zu erreichen. Also füttern wir den Input zweimal, wobei das 2. Mal nur die letzte Sekunde aufgenommen wird. Wir weisen FFmpeg an, die Zeitstempel beizubehalten, sodass ffmpeg die zeitliche Position dieses Endabschnitts beibehält.
Wir wenden eine Ausblendung auf diesen Schwanz an und legen das Ergebnis dann auf die vollständige Eingabe. Da es sich um dieselbe Mediendatei handelt, deckt der Vordergrund den Hintergrund vollständig ab, und da copyts
er angewendet wurde, erfolgt die Überlagerung auf dem entsprechenden identischen Frame in der Hintergrundeingabe.
Für Audio erstellen wir ein leeres Dummy-Audio mit einer Dauer von 2 Sekunden und wenden dann eine Audioüberblendung vom Hauptaudio auf dieses Dummy-Audio an. Da das 2. Audio leer ist, ist dies tatsächlich eine Ausblendung für den Haupteingang. Der -shortest
wird hinzugefügt, um Teile des Dummy-Audios wegzulassen, nachdem die Überblendung aufgetreten ist.
Es ist ein schrecklicher Hack, aber das könnte funktionieren, wenn Sie nur Audio ein- und ausblenden möchten, aber nicht genau wissen, wie lang der Clip ist:
ffmpeg -i input.mp4 -filter_complex "afade=d=0.5, areverse, afade=d=0.5, areverse" output.mp4
[bearbeiten 24.07.2019: Beachten Sie, dass diese Lösung nicht für Streaming-Lösungen geeignet ist, da der gesamte Track verarbeitet werden muss, bevor das erste Byte gestreamt werden kann]
Eine weitere Option, die ich verwende, ist die Verwendung acrossfade
mit einer stillen Spur:
ffmpeg -i input.mp4 -filter_complex "aevalsrc=0:d=0.6 [a_silence]; [0:a:0] [a_silence] acrossfade=d=0.6" output.mp4
Die Antwort auf Frage 2 ist ein klares JA! Ich suchte nach der gleichen Funktionalität und schrieb schließlich ein Bash-Skript, das nach der Fade-Dauer in Sekunden fragt und den Anfangsframe für das Fade-Out berechnet:
#!/bin/bash
f="$*" # all args
p="${f##*/}" # file
fn="${p%.*}" # name only
e="${p##*.}" # extension
echo
echo $f
echo $p
echo $fn
echo $e
echo
read -e -p "Number of seconds of fade-out: " -i 1 sec # prompt for fade duration in seconds
r=$(ffprobe -show_streams "$f" 2> /dev/null | grep r_frame_rate | head -1 | cut -d \= -f 2) # frame rate
let "frames = $r * $sec" # duration of fade as number of frames
echo $r
echo $sec
echo $frames
lf=$(ffprobe -show_streams "$f" 2> /dev/null | grep nb_frames | head -1 | cut -d \= -f 2) # total number of frames
let "lf = $lf - $frames" # initial frame to start fade at
ffmpeg -loglevel quiet -i "$f" -vf fade=out:$lf:$frames -r $r -vcodec libx264 -preset slow -crf 12 -bf 2 -flags +cgop -pix_fmt yuv420p -acodec copy "$fn $sec sec fade-out.$e"
open "$fn $sec sec fade-out.$e"
Überblendungen erfordern eine Neucodierung, sodass die Verwendung eines niedrigen crf
Werts für libx264
eine Neucodierung in hoher Qualität ergibt. Die Kommentare sollten alles andere erklären.
automatically figure out the duration
mit ffprobe
installiert wird, verwendet ffmpeg
. Wer hat etwas von einer Beschränkung der Anzahl der Befehle oder gesagt *nix
? Es scheint, dass das OP eine Version von UNIX verwendet. Nein .exe
im ffmpeg
Befehl. Ich selbst benutze OS X
das, was aufgebaut ist, UNIX
aber nicht UNIX
.ffprobe
ist ein fester Bestandteil der ffmpeg
Distribution. Du pickst an Nissen herum, um das Gesicht zu wahren, IMO.
Felwite
Gyan
-report
hinzugefügt aus und teilen Sie den Bericht.