Como diminuir / diminuir um clipe de vídeo / áudio com duração desconhecida?


19

Estou trabalhando em um projeto em que estou usando o ffmpeg para converter em lote alguns arquivos de vídeo e adicionando efeitos de fade in / out na cabeça e cauda de cada clipe.

Eu tenho usado esse bit de código para adicionar o efeito fade / out em clipes com durações conhecidas:

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

Minhas duas perguntas são:

  1. Como posso diminuir / diminuir simultaneamente o áudio?
  2. O ffmpeg pode descobrir automaticamente a duração do clipe e saber que apenas desbota os últimos 30 quadros?

Obrigado!

Respostas:


15

# 1 Para diminuir / diminuir simultaneamente o áudio:

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

Os tempos finais são em segundos .

2 automaticamente? Não. Mas veja a solução alternativa abaixo

Você pode primeiro executar o ffprobe para obter duração.

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

Você obterá algo como isto:

video|13.556000
audio|13.816000

Em seguida, você pode usar o acima para colocar seus desbotamentos. Estes tempos são em segundos.

Gambiarra

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 tem uma sseofopção que permite buscar uma entrada do final. Podemos usar isso para atingir nosso objetivo. Então, alimentamos a entrada duas vezes, com a segunda vez ingerindo apenas o último segundo. Dizemos ao FFmpeg para preservar os carimbos de data e hora, para que o ffmpeg preserve a posição temporal dessa parte da cauda.

Aplicamos um desbotamento a essa cauda e sobrepomos o resultado na entrada completa. Como são o mesmo arquivo de mídia, o primeiro plano cobre completamente o plano de fundo e, como copytsfoi aplicada, a sobreposição ocorre no quadro idêntico correspondente na entrada do plano de fundo.

Para o áudio, criamos um áudio fictício em branco com duração de 2 segundos e, em seguida, aplicamos um crossfade de áudio do áudio principal para esse áudio fictício. Como o 2º áudio está em branco, isso é, na verdade, um desvanecimento da entrada principal. A -shortesté adicionado a sair para fora porções do áudio manequim após o cruzamento de FADE ocorreu.


Isso dá o erro "não existe esse filtro!" para o filtro de áudio.
felwithe

1
Existem 4 filtros de áudio usados. Qual? Execute seu comando com -reportadicionado e compartilhe o relatório.
Gyan

7

É um truque terrível, mas isso pode funcionar se tudo que você quer fazer é diminuir / diminuir o áudio, mas não sabe exatamente quanto tempo o clipe é:

ffmpeg -i input.mp4 -filter_complex "afade=d=0.5, areverse, afade=d=0.5, areverse" output.mp4

[editar 2019-07-24: Observe que esta solução não é boa para soluções de streaming, pois exige que a faixa completa seja processada antes que o primeiro byte possa ser transmitido]

outra opção é usar acrossfadecom uma faixa 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

3
Isso é realmente muito elegante :-)
bk138

isso funciona muito bem. você poderia explicar como isso funciona? tentando entender a documentação ..
oberhamsi 21/07

1
@oberhamsi: Opção 1: O primeiro filtro adiciona um desbotamento no início da faixa. Em seguida, inverte o áudio e adiciona outro fade in no início (que é realmente o fim). Finalmente, a faixa é revertida novamente. A opção 2 cria uma faixa silenciosa de 0,6 segundos e a cruza pela mesma quantidade de tempo com a faixa original. Todos os filtros e seu uso estão documentados aqui: ffmpeg.org/ffmpeg-filters.html (embora eu deva concordar que é um pouco enigmático)
marekventur

3

A resposta à pergunta 2 é um retumbante SIM! Eu estava procurando a mesma funcionalidade e acabei escrevendo um script bash que solicita a duração do desbotamento em segundos e calcula o quadro inicial do desvanecimento:

#!/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"

O desbotamento requer recodificação, portanto, usar um crfvalor baixo para libx264fornecer uma recodificação de alta qualidade. Os comentários devem explicar tudo o resto.


A resposta à pergunta 2 é um retumbante SIM! -> ainda não. O Q é Can ffmpeg calcula automaticamente a duração ... mas você escreveu um script que executa vários comandos ff * para fazer isso. Útil para sistemas * nix, no entanto.
Gyan

Entendo, então você insiste que SUA resposta ainda está correta? Se você seguir meu script, verá que ele realmente automatically figure out the durationusa ffprobe, o qual está instalado ffmpeg. Quem disse alguma coisa sobre qualquer restrição no número de comandos ou *nix? Parece que o OP está usando uma versão do UNIX. Não .exeno ffmpegcomando. Eu mesmo estou usando o OS Xque é construído sobre, UNIXmas não é UNIX.
Hmj6jmh

1
* Se você seguir meu script, verá que ele realmente descobre automaticamente * -> seu script, ffmpeg não.
Gyan 7/17

Mas ffprobeé parte integrante da ffmpegdistribuição. Você está escolhendo as lêndeas para salvar a cara da IMO.
Hmj6jmh

Eu teria que concordar que algo que está sendo feito por um script bash não é algo que está sendo feito automaticamente pelo ffmpeg. Mas se isso funcionar, é uma maneira de contornar esse problema. Daí o termo "solução alternativa". Não sei dizer se funciona, porque eu, como a maioria das pessoas, não tenho sistema bash ou unix. +1 para o esforço de qualquer maneira.
Ashleedawg
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.