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

Come posso normalizzare l'audio usando ffmpeg?

Voglio che il suono di picco più forte in un filmato sia il più forte che il codec permette, poi avere ogni altro suono amplificato di conseguenza.

Qual è un esempio pratico per realizzare questo usando ffmpeg?

Risposte (4)

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

Option 1: Built-in Normalization Filters

Current ffmpeg ha due filtri che possono essere usati direttamente per la normalizzazione - anche se sono già abbastanza avanzati, quindi non applicano semplicemente il guadagno per raggiungere un livello di picco. Eccoli qui:

  • loudnorm : normalizzazione del volume secondo EBU R128. Puoi impostare un obiettivo di loudness integrato, un obiettivo di gamma di loudness o il massimo picco reale. Questo è raccomandato per la pubblicazione di audio e video ed è usato dai broadcaster di tutto il mondo.
  • dynaudnorm : Normalizzazione “intelligente” del loudness senza clipping, che applica la normalizzazione dinamicamente su porzioni finestrate del file. Questo può cambiare le caratteristiche del suono, quindi dovrebbe essere applicato con cautela.

Inoltre, il filtro volume può essere usato per eseguire semplici regolazioni del volume. Vedi la voce del wiki Audio Volume Manipulation per saperne di più.

Il filtro loudnorm può essere usato con un solo passaggio, ma si raccomanda di eseguire due passaggi, che permettono una normalizzazione lineare più accurata. Questo è un po’ difficile da automatizzare. Inoltre, se vuoi una “semplice” normalizzazione basata sul RMS o sui picchi a 0 dBFS (o qualsiasi altro obiettivo), continua a leggere.


Opzione 2: Usa lo strumento ffmpeg-normalize

Ho creato un programma Python per normalizzare i file multimediali , disponibile anche su PyPi . Devi semplicemente:

Per esempio:

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

Oppure, per normalizzare semplicemente in batch un certo numero di file audio e scriverli come WAV non compressi in una cartella di output:

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

Lo strumento supporta EBU R128 (default), RMS e peak. Dai un'occhiata a ffmpeg-normalize -h per altre opzioni e controlla il README per alcuni esempi.

Inoltre, supporta la ricodifica con altri encoder (ad esempio, AAC o MP3), o la fusione automatica dell'audio nel video.


Opzione 3: Normalizzare manualmente l'audio con ffmpeg

In ffmpeg puoi usare il filtro volume per cambiare il volume di una traccia. Assicurati di scaricare una versione recente del programma.

Questa guida è per la normalizzazione peak, il che significa che farà sedere la parte più forte del file a 0 dB invece che a qualcosa di più basso. C'è anche una normalizzazione basata su RMS che cerca di rendere il volume medio lo stesso in più file. Per farlo, non cercate di spingere il volume massimo a 0 dB, ma il volume medio al livello di dB scelto (per esempio -26 dB).

Trova il guadagno da applicare

Prima devi analizzare il flusso audio per il volume massimo per vedere se la normalizzazione sarebbe anche utile:

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

Sostituisci /dev/null con NUL su Windows.
Gli argomenti -vn , -sn , e -dn indicano a ffmpeg di ignorare i flussi non-audio durante questa analisi. Questo accelera drasticamente l'analisi.

Questo produrrà qualcosa come il seguente:

[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

Come puoi vedere, il nostro volume massimo è -5.0 dB, quindi possiamo applicare un guadagno di 5 dB. Se ottieni un valore di 0 dB, allora non hai bisogno di normalizzare l'audio.

Applica il filtro volume:

Ora applichiamo il filtro volume a un file audio. Nota che applicare il filtro significa che dovremo ricodificare il flusso audio. Quale codec vuoi per l'audio dipende dal formato originale, ovviamente. Ecco alcuni esempi:

  • File audio semplice: Codifica semplicemente il file con qualsiasi codificatore tu abbia bisogno:

  • Formato AVI: Di solito c'è l'audio MP3 con il video che arriva in un contenitore AVI:

  • Formato MP4: Con un contenitore MP4, di solito troverai l'audio AAC. Possiamo usare l'encoder AAC integrato di ffmpeg.

Negli esempi precedenti, il flusso video sarà copiato usando -c:v copy. Se ci sono sottotitoli nel tuo file di input, o più flussi video, usa l'opzione -map 0 prima del nome del file di output.

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

Non posso commentare il messaggio migliore quindi questo è il mio brutto bash basato su di esso per fare che

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

Ecco uno script per normalizzare i livelli sonori dei file .m4a. Fai attenzione se i livelli sonori sono troppo bassi all'inizio. Il suono finale può essere migliore se usi qualcosa come Audacity in quel 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