¿Cómo puedo normalizar el audio usando ffmpeg?

119

Quiero que el sonido de pico más alto en un clip de película sea tan fuerte como lo permita el códec, y luego amplifique todos los demás sonidos en consecuencia.

¿Cuál es un ejemplo práctico para lograr esto usando ffmpeg?

Jon Skarpeteig
fuente
1
Estás buscando tener el audio 'normalizado'. Encontré este hilo y hay mucha buena información allí. ¡Espero eso ayude!
bobsbarricades

Respuestas:

190

Opción 1: filtros de normalización incorporados

El ffmpeg actual tiene dos filtros que se pueden usar directamente para la normalización, aunque ya están bastante avanzados, por lo que no solo aplican la ganancia para alcanzar un nivel máximo. Aquí están:

  • loudnorm: normalización de volumen según EBU R128. Puede establecer un objetivo de sonoridad integrado, un objetivo de rango de sonoridad o un pico verdadero máximo. Esto se recomienda para la publicación de audio y video y es utilizado por emisoras de todo el mundo.
  • dynaudnorm: Normalización de sonoridad "inteligente" sin recorte, que aplica la normalización dinámicamente sobre partes del archivo con ventanas. Esto puede cambiar las características del sonido, por lo que debe aplicarse con precaución.

Además, el volumefiltro se puede utilizar para realizar ajustes de volumen simples. Vea la entrada wiki de Audio Volume Manipulation para más información.

El loudnormfiltro se puede usar con una pasada, pero se recomienda realizar dos pasadas, lo que permite una normalización lineal más precisa. Esto es un poco difícil de automatizar. Además, si desea una normalización “simple” basada en RMS o pico a 0 dBFS (o cualquier otro objetivo), siga leyendo.


Opción 2: usar la ffmpeg-normalizeherramienta

He creado un programa Python para normalizar archivos multimedia , disponibles en PyPi así . Tu simplemente:

  • descargue ffmpeg (elija una versión estática , versión 3.1 o superior)
  • ponga el ffmpegejecutable en su archivo $PATHagregándolo, por ejemplo /usr/local/bin, o agregando su directorio a$PATH
  • correr pip install ffmpeg-normalize
  • Utilizar ffmpeg-normalize

Por ejemplo:

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

O, para simplemente normalizar por lotes una cantidad de archivos de audio y escribirlos como WAV sin comprimir en una carpeta de salida:

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

La herramienta admite EBU R128 (predeterminado), RMS y pico. Eche un vistazo a ffmpeg-normalize -hmás opciones y consulte el archivo README para ver algunos ejemplos.

Además, admite la codificación con otros codificadores (p. Ej., AAC o MP3), o la fusión automática del audio en el video.


Opción 3: Normalización manual de audio con ffmpeg

En ffmpeg puede usar el volumefiltro para cambiar el volumen de una pista. Asegúrese de descargar una versión reciente del programa.

Esta guía es para la normalización de picos , lo que significa que hará que la parte más ruidosa del archivo se asiente a 0 dB en lugar de algo más bajo. También hay una normalización basada en RMS que intenta hacer que el volumen promedio sea el mismo en varios archivos. Para hacerlo, no intente llevar el volumen máximo a 0 dB, sino el volumen medio al nivel de elección de dB (por ejemplo, -26 dB).

Descubre la ganancia para aplicar

Primero debe analizar la transmisión de audio para ver el volumen máximo para ver si la normalización incluso valdría la pena:

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

Reemplazar /dev/nullcon NULen Windows.
El -vn, -sny -dnargumentos instruyen ffmpeg para ignorar las corrientes no son de audio durante este análisis. Esto acelera drásticamente el análisis.

Esto generará algo como lo siguiente:

[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 puede ver, nuestro volumen máximo es -5.0 dB, por lo que podemos aplicar una ganancia de 5 dB. Si obtiene un valor de 0 dB, entonces no necesita normalizar el audio.

Aplicar el filtro de volumen:

Ahora aplicamos el volumefiltro a un archivo de audio. Tenga en cuenta que la aplicación del filtro significa que tendremos que volver a codificar la secuencia de audio. El códec que desea para el audio depende del formato original, por supuesto. Aquí hay unos ejemplos:

  • Archivo de audio simple: simplemente codifique el archivo con el codificador que necesite:

    ffmpeg -i input.wav -af "volume=5dB" output.mp3
    

    Sus opciones son muy amplias, por supuesto.

  • Formato AVI: generalmente hay audio MP3 con video que viene en un contenedor AVI:

    ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi
    

    Aquí elegimos el nivel de calidad 2. Los valores van de 0 a 9 y más bajos significa mejor. Consulte la guía MP3 VBR para obtener más información sobre cómo establecer la calidad. También puede establecer una tasa de bits fija con -b:a 192k, por ejemplo.

  • Formato MP4: con un contenedor MP4, normalmente encontrará audio AAC. Podemos usar el codificador AAC incorporado de ffmpeg.

    ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -b:a 192k output.mp4
    

    Aquí también puede usar otros codificadores AAC. Algunos de ellos también admiten VBR. Consulte esta respuesta y la guía de codificación AAC para obtener algunos consejos.

En los ejemplos anteriores, la transmisión de video se copiará usando -c:v copy. Si hay subtítulos en su archivo de entrada o múltiples transmisiones de video, use la opción -map 0antes del nombre del archivo de salida.

slhck
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Journeyman Geek
77
Este es el regalo que sigue dando. 6 años después, y todavía se está actualizando y manteniendo. ¡Bien hecho!
Jon Skarpeteig
¿La opción 3 evita el recorte si configuro el nuevo volumen para que max_volume sea cero? es decir, usando el valor opuesto inicial dado por max_volume
rraallvv
@rraallvv Sí, debería. Eso es también lo ffmpeg-normalizeque hace la herramienta, cuando especifica un nivel de 0 dB y normalización de pico.
slhck
Para usar el loudnormfiltro (u otro):ffmpeg -i input.wav -filter:a loudnorm output.wav
Joschua
7

No puedo comentar sobre el mejor mensaje, así que esa es mi fiesta fea basada en eso para hacer eso

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
Sebastien Willemijns
fuente
5

Aquí hay un script para normalizar los niveles de sonido de los archivos .m4a. Tenga cuidado si los niveles de sonido son demasiado silenciosos para comenzar. El sonido final puede ser mejor si usa algo como Audacity en ese 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
Chris Prince
fuente
-2

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

Aullido de Maquelan
fuente
2
Comparando esto con las otras respuestas aquí, espero que esté claro que su publicación carece de información contextual y explicativa que la haga útil. ¿Qué es "mencoder" y qué papel juega al responder la pregunta?
music2myear
2
¿Podría editar su respuesta para dar una explicación de por qué este código responde a la pregunta? Se desaconsejan las respuestas de solo código , porque no enseñan la solución.
DavidPostill