Estoy trabajando en un proyecto en el que estoy usando ffmpeg para convertir por lotes algunos archivos de video y agregar efectos de entrada/salida graduales al principio y al final de cada clip.
He estado usando este fragmento de código para agregar el efecto de desvanecimiento/desaparición en clips con duraciones conocidas:
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
Mis dos preguntas son:
¡Gracias!
#1 Para atenuar simultáneamente la entrada/salida de audio:
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
Los tiempos de afade son en segundos .
#2 ¿Automáticamente? No. Pero vea la solución a continuación
Primero puede ejecutar ffprobe para obtener la duración.
ffprobe -i clip.mp4 -show_entries stream=codec_type,duration -of compact=p=0:nk=1
Obtendrás algo como esto:
video|13.556000
audio|13.816000
Luego puede usar lo anterior para colocar sus fundidos. Estos tiempos son en segundos.
Solución alterna
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 tiene una sseof
opción que permite buscar una entrada desde el final. Podemos usar eso para lograr nuestro objetivo. Entonces alimentamos la entrada dos veces, y la segunda vez ingiere solo el último segundo. Le decimos a FFmpeg que conserve las marcas de tiempo, de modo que ffmpeg conserve la posición temporal de esta parte de la cola.
Aplicamos un desvanecimiento a esta cola y luego superponemos el resultado en la entrada completa. Dado que son el mismo archivo multimedia, el primer plano cubre completamente el fondo y, desde que copyts
se aplicó, la superposición se produce en el marco idéntico correspondiente en la entrada de fondo.
Para el audio, creamos un audio ficticio en blanco de 2 segundos de duración y luego aplicamos un fundido cruzado de audio desde el audio principal a este audio ficticio. Dado que el segundo audio está en blanco, esto es, en efecto, un fundido de salida para la entrada principal. Se -shortest
agrega para omitir partes del audio ficticio después de que se haya producido el fundido cruzado.
Es un truco terrible, pero esto podría funcionar si todo lo que quieres hacer es el audio de entrada/salida gradual pero no sabes exactamente cuánto dura el clip:
ffmpeg -i input.mp4 -filter_complex "afade=d=0.5, areverse, afade=d=0.5, areverse" output.mp4
[editar 2019-07-24: tenga en cuenta que esta solución no es buena para las soluciones de transmisión, ya que requiere que se procese la pista completa antes de que se pueda transmitir el primer byte]
otra opción que es usar acrossfade
con una pista silenciosa:
ffmpeg -i input.mp4 -filter_complex "aevalsrc=0:d=0.6 [a_silence]; [0:a:0] [a_silence] acrossfade=d=0.6" output.mp4
La respuesta a la pregunta 2 es un rotundo ¡SÍ! Estaba buscando la misma funcionalidad y terminé escribiendo un script de bash que solicita la duración del desvanecimiento en segundos y calcula el cuadro inicial para el desvanecimiento:
#!/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"
Los fundidos requieren una nueva codificación, por lo que usar un crf
valor bajo para libx264
da una nueva codificación de alta calidad. Los comentarios deben explicar todo lo demás.
automatically figure out the duration
usa ffprobe
, que se instala con ffmpeg
. ¿Quién dijo algo sobre alguna restricción en el número de comandos o *nix
? Parece que el OP está usando una versión de UNIX. No .exe
en el ffmpeg
comando. Yo mismo estoy usando OS X
el cual está construido UNIX
pero no lo está UNIX
.ffprobe
es una parte integral de la ffmpeg
distribución. Estás picando liendres para salvar la cara, en mi opinión.
compañero
gian
-report
agregado y comparta el informe.