2011-08-14 19:56:01 +0000 2011-08-14 19:56:01 +0000
125
125

Como posso normalizar o áudio usando ffmpeg?

Quero que o som mais alto de pico num clip de filme seja tão alto quanto o codec permite, depois ter todos os outros sons amplificados em conformidade.

O que é um exemplo prático para conseguir isto usando ffmpeg?

Respostas (4)

202
202
202
2011-08-14 20:11:03 +0000

Opção 1: Filtros de Normalização Incorporados

Corrente ffmpeg tem dois filtros que podem ser utilizados directamente para normalização - embora já estejam bastante avançados, pelo que não se limitam a aplicar o ganho para atingir um nível de pico. Aqui estão eles:

  • loudnorm : normalização da sonoridade de acordo com EBU R128. Pode-se definir um objectivo de ruído integrado, um objectivo de gama de ruído, ou um pico máximo verdadeiro. Isto é recomendado para a publicação de áudio e vídeo e é utilizado por emissoras em todo o mundo.
  • dynaudnorm : normalização “inteligente” da sonoridade sem recorte, que aplica a normalização dinamicamente sobre porções de janela do ficheiro. Isto pode alterar as características do som, pelo que deve ser aplicado com cautela.

& Também, o filtro volume pode ser utilizado para efectuar simples ajustes de volume. Ver a entrada Audio Volume Manipulation wiki para mais.

O filtro loudnorm pode ser utilizado com uma passagem, mas recomenda-se a realização de duas passagens, o que permite uma normalização linear mais precisa. Isto é um pouco difícil de automatizar. Além disso, se quiser uma normalização “simples” baseada em RMS ou de pico a 0 dBFS (ou qualquer outro alvo), continue a ler.


Opção 2: Use a ferramenta ffmpeg-normalize

Eu criei um programa Python para normalizar ficheiros multimédia , disponível também em PyPi . Você simplesmente:

& - descarregar ffmpeg (escolha uma compilação estática, versão 3. 1 ou superior) - coloque o ffmpeg executável no seu $PATH adicionando-o, por exemplo: /usr/local/bin, ou adicionando o seu directório ao $PATH - Execute pip install ffmpeg-normalize - Use ffmpeg-normalize

Por exemplo:

ffmpeg-normalize input.mp4 -o output.mp4 -c:a aac -b:a 192k

Ou, para simplesmente normalizar um número de ficheiros de áudio e escreva-os como WAV não comprimido numa pasta de saída:

ffmpeg-normalize *.m4a -of /path/to/outputFolder -ext wav

A ferramenta suporta EBU R128 (por defeito), RMS e pico. Veja ffmpeg-normalize -h para mais opções e verifique o README para alguns exemplos.

Além disso, suporta a re-encodificação com outros codificadores (por exemplo, AAC ou MP3), ou a fusão automática do áudio de volta ao vídeo.


Opção 3: Normalização manual do áudio com ffmpeg

Em ffmpeg pode usar o filtro volume para alterar o volume de uma faixa. Certifique-se de descarregar uma versão recente & do programa.

Este guia é para a normalização peak, o que significa que a parte mais barulhenta do ficheiro ficará a 0 dB em vez de algo mais baixo. Há também uma normalização baseada em RMS que tenta fazer com que o ruído média seja o mesmo em múltiplos ficheiros. Para isso, não tente empurrar o volume máximo para 0 dB, mas o volume médio para o nível de dB de escolha (por exemplo -26 dB).

Descubra o ganho para aplicar

Primeiro é necessário analisar o fluxo de áudio para o volume máximo para ver se a normalização compensaria:

ffmpeg -i video.avi -af "volumedetect" -vn -sn -dn -f null /dev/null

Substituir /dev/null por NUL no Windows.
O -vn , -sn , e -dn argumentos instruem o ffmpeg a ignorar fluxos não áudio durante esta análise. Isto acelera drasticamente a análise.

Isto irá produzir algo como o seguinte:

[Parsed_volumedetect_0 @ 0x7f8ba1c121a0] mean_volume: -16.0 dB
[Parsed_volumedetect_0 @ 0x7f8ba1c121a0] max_volume: -5.0 dB
[Parsed_volumedetect_0 @ 0x7f8ba1c121a0] histogram_0db: 87861

Como pode ver, o nosso volume máximo é de -5,0 dB, pelo que podemos aplicar um ganho de 5 dB. Se obtivermos um valor de 0 dB, então não precisamos de normalizar o áudio.

Aplique o filtro de volume:

Agora aplicamos o volume filtro a um ficheiro de áudio. Note-se que a aplicação do filtro significa que teremos de recodificar o fluxo de áudio. O codec que se pretende para o áudio depende do formato original, claro. Aqui estão alguns exemplos:

  • Plain ficheiro de áudio: Basta codificar o ficheiro com o codificador que precisar:

  • ** Formato AVI:** Normalmente há áudio MP3 com vídeo que vem num contentor AVI:

  • ** FormatoMP4:** Com um contentor MP4, normalmente encontrará áudio AAC. Podemos utilizar o codificador AAC integrado no ffmpeg.

Nos exemplos acima, o fluxo de vídeo será copiado usando -c:v copy. Se houver legendas no seu ficheiro de entrada, ou múltiplos fluxos de vídeo, use a opção -map 0 antes do nome do ficheiro de saída.

7
7
7
2016-05-19 14:51:16 +0000

Não posso comentar a melhor mensagem, por isso é a minha feiosa base para fazer isso

ffmpeg -i sound.mp3 -af volumedetect -f null -y nul &> original.txt
grep "max_volume" original.txt > original1.tmp
sed -i 's|: -|=|' original1.tmp
if [$? = 0]
 then
 sed -i 's| |\r\n|' original.tmp
 sed -i 's| |\r\n|' original.tmp
 sed -i 's| |\r\n|' original.tmp
 sed -i 's| |\r\n|' original.tmp
 grep "max_volume" original1.tmp > original2.tmp
 sed -i 's|max_volume=||' original2.tmp
 yourscriptvar=$(cat "./original2.tmp")dB
 rm result.mp3
 ffmpeg -i sound.mp3 -af "volume=$yourscriptvar" result.mp3
 ffmpeg -i result.mp3 -af volumedetect -f null -y nul &> result.txt
fi
5
5
5
2015-09-12 04:57:30 +0000

Aqui está um guião para normalizar os níveis sonoros dos ficheiros .m4a. Cuidado se os níveis de som são demasiado silenciosos para começar. O som final pode ser melhor se se usar algo como Audacity nesse caso.

#!/bin/bash

# Purpose: Use ffmpeg to normalize .m4a audio files to bring them up to max volume, if they at first have negative db volume. Doesn't process them if not. Keeps bitrate same as source files.
# Parameters: $1 should be the name of the directory containing input .m4a files.
# $2 should be the output directory.

INPUTDIR=$1
OUTPUTDIR=$2

<<"COMMENT"

# For ffmpeg arguments http://superuser.com/questions/323119/how-can-i-normalize-audio-using-ffmpeg
# and
# https://kdecherf.com/blog/2012/01/14/ffmpeg-converting-m4a-files-to-mp3-with-the-same-bitrate/
ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null

ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume
# output: max_volume: -10.3 dB

ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep 'max_volume\|Duration'
# Output:
# Duration: 00:00:02.14, start: 0.000000, bitrate: 176 kb/s
# [Parsed_volumedetect_0 @ 0x7f8531e011a0] max_volume: -10.3 dB

ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1
# Output: -10.3

ffmpeg -i test.m4a 2>&1 | grep Audio
# output: Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 170 kb/s (default)

ffmpeg -i test.m4a 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1
# output: 170

# This works, but I get a much smaller output file. The sound levels do appear normalized.
ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental output.m4a

# Operates quietly.
ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental -b:a 192k output.m4a -loglevel quiet

COMMENT

# $1 (first param) should be the name of a .m4a input file, with .m4a extension
# $2 should be name of output file, with extension
function normalizeAudioFile {
    INPUTFILE=$1
    OUTPUTFILE=$2

    DBLEVEL=`ffmpeg -i ${INPUTFILE} -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1`

    # We're only going to increase db level if max volume has negative db level.
    # Bash doesn't do floating comparison directly
    COMPRESULT=`echo ${DBLEVEL}'<'0 | bc -l`
    if [${COMPRESULT} -eq 1]; then
        DBLEVEL=`echo "-(${DBLEVEL})" | bc -l`
        BITRATE=`ffmpeg -i ${INPUTFILE} 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1`

        # echo $DBLEVEL
        # echo $BITRATE

        ffmpeg -i ${INPUTFILE} -af "volume=${DBLEVEL}dB" -c:v copy -c:a aac -strict experimental -b:a ${BITRATE}k ${OUTPUTFILE} -loglevel quiet

    else
        echo "Already at max db level:" $DBLEVEL "just copying exact file"
        cp ${INPUTFILE} ${OUTPUTFILE}
    fi
}

for inputFilePath in ${INPUTDIR}/*; do
    inputFile=$(basename $inputFilePath)
    echo "Processing input file: " $inputFile
    outputFilePath=${OUTPUTDIR}/$inputFile
    normalizeAudioFile ${inputFilePath} ${outputFilePath}
done
-2
-2
-2
2019-03-21 20:27:43 +0000

ffmpeg -i image.jpg -i “input.mp3” -acodec copy tmp.avi

mencoder -ovc copy -oac copy tmp.avi -of rawaudio -af volnorm=1 -oac mp3lame -lameopts cbr:preset=192 -srate 48000 -o “output.mp3”

rm -f tmp.avi

Questões relacionadas

6
10
8
12
13