Wie kann ich einen Video- / Audioclip mit unbekannter Dauer ein- / ausblenden?


19

Ich arbeite an einem Projekt, in dem ich mit ffmpeg einige Videodateien stapelweise konvertiere und am Anfang und Ende jedes Clips Ein- / Ausblendeffekte hinzufüge.

Ich habe dieses Codebit verwendet, um den Ein- / Ausblendeffekt für 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 sind:

  1. Wie kann ich den Ton gleichzeitig ein- / ausblenden?
  2. Kann ffmpeg automatisch die Dauer des Clips ermitteln und die letzten 30 Frames ausblenden?

Vielen Dank!

Antworten:


15

# 1 So blenden Sie den Ton gleichzeitig ein / aus:

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 Verblassungszeiten sind in Sekunden angegeben .

# 2 automatisch? Aber sehen Sie sich die Problemumgehung unten an

Sie können zuerst ffprobe ausführen, um die Dauer abzurufen.

ffprobe -i clip.mp4 -show_entries stream=codec_type,duration -of compact=p=0:nk=1

Sie werden so etwas bekommen:

video|13.556000
audio|13.816000

Sie können dann die oben genannten verwenden, um Ihre Fades zu platzieren. Diese Zeiten sind in Sekunden angegeben.

Umgehung

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 sseofOption, mit der man am Ende nach einer Eingabe suchen kann. Damit können wir unser Ziel erreichen. Also füttern wir die Eingabe zweimal, wobei das zweite Mal nur die letzte Sekunde aufgenommen wird. Wir weisen FFmpeg an, die Zeitstempel beizubehalten, damit ffmpeg die zeitliche Position dieses Endabschnitts beibehält.

Wir wenden eine Überblendung auf diesen Schwanz an und überlagern dann das Ergebnis auf den gesamten Eingang. Da es sich um dieselbe Mediendatei handelt, deckt der Vordergrund den Hintergrund vollständig ab, und da copytsdie Überlagerung angewendet wurde, erfolgt sie 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 Haupt-Audio auf dieses Dummy-Audio an. Da der zweite Ton leer ist, wird der Haupteingang ausgeblendet. Das -shortestwird hinzugefügt, um Teile des Dummy-Audios nach dem Überblenden wegzulassen.


Dies gibt den Fehler "Kein solcher Filter!" für den Audiofilter.
Felwithe

1
Es werden 4 Audiofilter verwendet. Welcher? Führen Sie Ihren Befehl mit -reportadded aus und geben Sie den Bericht frei.
Gyan

7

Es ist ein schrecklicher Hack, aber das könnte funktionieren, wenn Sie nur Audio ein- / 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

[edit 2019-07-24: 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 andere Option, die ich acrossfademit einer stillen Spur verwenden soll:

ffmpeg -i input.mp4 -filter_complex "aevalsrc=0:d=0.6 [a_silence]; [0:a:0] [a_silence] acrossfade=d=0.6" output.mp4

3
Das ist eigentlich ziemlich elegant :-)
bk138

das funktioniert super Könntest du erklären, wie es funktioniert? versuchen, die Dokumentation zu
verstehen

1
@oberhamsi: Option 1: Der erste Filter fügt eine Überblendung am Anfang des Tracks hinzu. Anschließend wird das Audio umgekehrt und am Anfang ein weiteres Fade-In hinzugefügt (das eigentlich das Ende ist). Schließlich wird die Spur wieder umgekehrt. Option 2 erstellt eine stille Spur von 0,6 Sekunden und überblendet sie genauso lange wie die ursprüngliche Spur. Alle Filter und ihre Verwendung sind hier dokumentiert: ffmpeg.org/ffmpeg-filters.html (obwohl ich zustimmen muss, dass es ein bisschen kryptisch ist)
Marekventur

3

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 Ausblendungsdauer in Sekunden fragt und das anfängliche Bild für das Ausblenden 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. Verwenden Sie daher einen niedrigen crfWert, um eine libx264Neucodierung von hoher Qualität zu erzielen. Die Kommentare sollten alles andere erklären.


Die Antwort auf Frage 2 ist ein klares JA! -> es ist immer noch Nein. Das Q is Can ffmpeg ermittelt automatisch die Dauer ... aber Sie haben ein Skript geschrieben, das mehrere ff * -Befehle ausführt, um dies zu tun. Nützlich für * nix-Systeme.
Gyan

Ich verstehe, Sie bestehen also darauf, dass IHRE Antwort NOCH richtig ist? Wenn Sie meinem Skript folgen, werden Sie sehen, dass es tatsächlich automatically figure out the durationverwendet ffprobe, was mit installiert wird ffmpeg. Wer hat etwas über eine Beschränkung der Anzahl der Befehle gesagt oder *nix? Es scheint, dass das OP eine Version von UNIX verwendet. Nein .exeim ffmpegBefehl. Ich selbst benutze das OS Xworauf aufgebaut ist UNIXaber nicht UNIX.
hmj6jmh

1
* Wenn du meinem Skript folgst, wirst du sehen, dass es tatsächlich automatisch herausfindet * -> dein Skript tut es, ffmpeg nicht.
Gyan

Ist ffprobeaber ein integraler Bestandteil der ffmpegDistribution. Du wählst bei Nissen, um Gesicht IMO zu retten.
hmj6jmh

Ich muss zustimmen, dass etwas, das von einem Bash-Skript erledigt wird, nicht automatisch von ffmpeg erledigt wird. Wenn dies funktioniert, können Sie dieses Problem auf diese Weise umgehen. Daher der Begriff "Problemumgehung". Ich kann nicht sagen, ob es funktioniert, weil ich, wie die meisten Leute da draußen, kein Bash oder Unix-System habe. +1 für die Mühe jedenfalls.
Ashleedawg
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.