Saltar al contenido

¿Cómo puedo normalizar el audio usando ffmpeg?

Puede que se de el caso de que encuentres alguna incompatibilidad en tu código o proyecto, recuerda probar siempre en un entorno de testing antes aplicar el código al proyecto final.

Solución:

Opción 1: filtros de normalización integrados

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 se limitan a aplicar ganancia para alcanzar un nivel máximo. Aquí están:

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

También el volume El filtro se puede utilizar para realizar ajustes de volumen sencillos. Consulte la entrada wiki de manipulación del volumen de audio para obtener más información.

los loudnorm El filtro 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 de pico o RMS “simple” a 0 dBFS (o cualquier otro objetivo), siga leyendo.


Opción 2: utilice el ffmpeg-normalize herramienta

Creé un programa Python para normalizar archivos multimedia, disponible también en PyPi. Tu simplemente:

  • descargar ffmpeg (elija un static construir, versión 3.1 o superior)
  • Pon el ffmpeg ejecutable en tu $PATH ya sea agregándolo, por ejemplo, /usr/local/bin, o agregando su directorio a $PATH
  • Correr pip install ffmpeg-normalize
  • Usar ffmpeg-normalize

Por ejemplo:

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

O, 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. Mira esto ffmpeg-normalize -h para obtener más opciones y consulte el archivo README para ver algunos ejemplos.

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


Opción 3: normalizar manualmente el audio con ffmpeg

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

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

Descubra la ganancia para aplicar

Primero, debe analizar el flujo de audio para obtener 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

Reemplazar /dev/null con NUL en Windows.
los -vn, -sn, y -dn Los argumentos indican a ffmpeg que ignore las transmisiones que 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 de -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 volume filtrar a un archivo de audio. Tenga en cuenta que la aplicación del filtro significa que tendremos que volver a codificar el flujo de audio. El códec que desee 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
    

    Tus opciones son muy amplias, por supuesto.

  • Formato AVI: Por lo general, 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 oscilan entre 0 y 9 y menos significa mejor. Consulte la guía MP3 VBR para obtener más información sobre cómo configurar 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 utilizar el codificador AAC integrado de ffmpeg.

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

    Aquí también puede utilizar otros codificadores AAC. Algunos de ellos también son compatibles con 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 0 antes del nombre del archivo de salida.

No puedo comentar sobre el mejor mensaje así que ese es mi feo bash basándome en él 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| |rn|' original.tmp
 sed -i 's| |rn|' original.tmp
 sed -i 's| |rn|' original.tmp
 sed -i 's| |rn|' 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

Aquí hay un script para normalizar los niveles de sonido de los archivos .m4a. Tenga cuidado si los niveles de sonido son demasiado bajos para empezar. 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  awk -F': ' 'print $2' 

for inputFilePath in $INPUTDIR/*; do
    inputFile=$(basename $inputFilePath)
    echo "Processing input file: " $inputFile
    outputFilePath=$OUTPUTDIR/$inputFile
    normalizeAudioFile $inputFilePath $outputFilePath
done

Más adelante puedes encontrar las aclaraciones de otros gestores de proyectos, tú además eres capaz dejar el tuyo si lo deseas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *