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

¿Cómo puedo normalizar el audio con ffmpeg?

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

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

Respuestas (4)

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

Opción 1: Filtros de normalización incorporados

Actualmente ffmpeg tiene dos filtros que se pueden utilizar directamente para la normalización - aunque ya son bastante avanzados, por lo que no se limitan a aplicar la ganancia para alcanzar un nivel máximo. Aquí están:

  • loudnorm : normalización de la sonoridad según EBU R128. Se puede establecer un objetivo de sonoridad integrado, un objetivo de rango de sonoridad o un pico real máximo. Se recomienda para la publicación de audio y vídeo y lo utilizan emisoras de todo el mundo.
  • dynaudnorm : Normalización “inteligente” de la sonoridad sin recorte, que aplica la normalización de forma dinámica sobre las porciones de ventana del archivo. Esto puede cambiar las características del sonido, por lo que debe aplicarse con precaución.

Además, el filtro volume puede utilizarse para realizar ajustes de volumen sencillos. Consulte la entrada de la wiki Manipulación del volumen del audio para más información.

El filtro loudnorm puede utilizarse con una sola 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 quieres una normalización “simple” basada en RMS o en picos a 0 dBFS (o cualquier otro objetivo), sigue leyendo.

  • *

Opción 2: Usar la herramienta ffmpeg-normalize

He creado un programa en Python para normalizar archivos multimedia , disponible también en PyPi . Simplemente:

  • descargue ffmpeg (elija una construcción estática, versión 3. 1 o superior)
  • poner el ejecutable ffmpeg en su $PATH añadiéndolo, por ejemplo, en /usr/local/bin, o añadiendo su directorio a $PATH
  • Ejecutar pip install ffmpeg-normalize
  • Usar ffmpeg-normalize

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

O, para simplemente normalizar por lotes un número 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 soporta EBU R128 (por defecto), RMS y pico. Echa un vistazo a ffmpeg-normalize -h para ver más opciones y consulta el README para ver algunos ejemplos.

Además, soporta la recodificación con otros codificadores (por ejemplo, AAC o MP3), o la fusión automática del audio con el vídeo.

  • *

Opción 3: Normalizar manualmente el audio con ffmpeg

En ffmpeg puede utilizar el filtro volume para cambiar el volumen de una pista. Asegúrate de descargar una versión reciente del programa.

Esta guía es para la normalización de pico, lo que significa que hará que la parte más fuerte del archivo se sitúe en 0 dB en lugar de algo más bajo. También hay una normalización basada en RMS que trata de hacer que la sonoridad promedio sea la misma en varios archivos. Para ello, no intenta llevar el volumen máximo a 0 dB, sino el volumen medio al nivel de dB elegido (por ejemplo, -26 dB).

Averiguar la ganancia a aplicar

Primero hay que analizar el flujo de audio para el volumen máximo para ver si la normalización valdría la pena:

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

Sustituir /dev/null por NUL en Windows.
Los argumentos -vn , -sn , y -dn indican a ffmpeg que ignore los flujos que no son de audio durante este análisis. Esto acelera drásticamente el análisis.

El resultado será algo parecido a 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 de -5,0 dB, por lo que podemos aplicar una ganancia de 5 dB. Si obtienes un valor de 0 dB, entonces no necesitas normalizar el audio.

Aplicar el filtro de volumen:

Ahora aplicamos el filtro volume a un archivo de audio. Tenga en cuenta que aplicar el filtro significa que tendremos que recodificar el flujo de audio. El códec que quieras para el audio depende del formato original, por supuesto. He aquí algunos ejemplos:

  • Archivo de audio plano: Simplemente codifica el archivo con el codificador que necesites:

  • Formato AVI: Normalmente hay audio MP3 con el vídeo que viene en un contenedor AVI:

  • Formato MP4: Con un contenedor MP4, normalmente encontrarás audio AAC. Podemos utilizar el codificador AAC incorporado de ffmpeg.

En los ejemplos anteriores, el flujo de vídeo se copiará con -c:v copy. Si hay subtítulos en su archivo de entrada, o múltiples flujos de vídeo, utilice la opción -map 0 antes del nombre del archivo de salida.

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

No puedo comentar el mejor mensaje por lo que es mi feo bash basado en él para hacer que

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

Aquí tienes un script para normalizar los niveles de sonido de los archivos .m4a. Ten cuidado si los niveles de sonido son demasiado bajos al principio. El sonido final puede ser mejor si usas 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
-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

Preguntas relacionadas

6
10
8
12
9