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?
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?
Respuestas:
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 volume
filtro se puede utilizar para realizar ajustes de volumen simples. Vea la entrada wiki de Audio Volume Manipulation para más información.
El loudnorm
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 “simple” basada en RMS o pico a 0 dBFS (o cualquier otro objetivo), siga leyendo.
ffmpeg-normalize
herramientaHe creado un programa Python para normalizar archivos multimedia , disponibles en PyPi así . Tu simplemente:
ffmpeg
ejecutable en su archivo $PATH
agregándolo, por ejemplo /usr/local/bin
, o agregando su directorio a$PATH
pip install ffmpeg-normalize
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 -h
má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.
ffmpeg
En ffmpeg puede usar 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 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).
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/null
con NUL
en Windows.
El -vn
, -sn
y -dn
argumentos 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.
Ahora aplicamos el volume
filtro 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 0
antes del nombre del archivo de salida.
ffmpeg-normalize
que hace la herramienta, cuando especifica un nivel de 0 dB y normalización de pico.
loudnorm
filtro (u otro):ffmpeg -i input.wav -filter:a loudnorm output.wav
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
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
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