Come posso normalizzare l'audio usando ffmpeg?


119

Voglio che il suono di picco più forte in un clip filmato sia forte quanto il codec lo consente, quindi ogni altro suono amplificato di conseguenza.

Qual è un esempio pratico per ottenere questo risultato usando ffmpeg?


1
Stai cercando di rendere l'audio "normalizzato". Ho trovato questa discussione e ci sono molte buone informazioni lì dentro. Spero che sia d'aiuto!
bobsbarricades,

Risposte:


190

Opzione 1: filtri di normalizzazione integrati

L'attuale ffmpeg ha due filtri che possono essere usati direttamente per la normalizzazione, sebbene siano già abbastanza avanzati, quindi non applicano semplicemente il guadagno per raggiungere un livello di picco. Eccoli:

  • loudnorm: normalizzazione del volume secondo EBU R128. È possibile impostare un target di loudness integrato, un target di gamma di loudness o il picco massimo vero. Questo è consigliato per la pubblicazione di audio e video ed è utilizzato dalle emittenti di tutto il mondo.
  • dynaudnorm: Normalizzazione del volume "intelligente" senza ritaglio, che applica la normalizzazione in modo dinamico su parti del file con finestre. Questo può cambiare le caratteristiche del suono, quindi dovrebbe essere applicato con cautela.

Inoltre, il volumefiltro può essere utilizzato per eseguire semplici regolazioni del volume. Vedere la voce wiki Manipolazione del volume audio per ulteriori informazioni.

Il loudnormfiltro può essere utilizzato con un passaggio, ma si consiglia di eseguire due passaggi, che consente una normalizzazione lineare più accurata. Questo è un po 'difficile da automatizzare. Inoltre, se si desidera una normalizzazione "semplice" basata su RMS o di picco a 0 dBFS (o qualsiasi altro target), continuare a leggere.


Opzione 2: utilizzare lo ffmpeg-normalizestrumento

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

  • scarica ffmpeg (scegli una build statica , versione 3.1 o successiva)
  • inserisci il ffmpegfile eseguibile nel tuo $PATHaggiungendolo, ad esempio /usr/local/bin, o aggiungendo la sua directory a$PATH
  • Correre pip install ffmpeg-normalize
  • Uso ffmpeg-normalize

Per esempio:

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

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

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

Lo strumento supporta EBU R128 (impostazione predefinita), RMS e picco. Dai un'occhiata a ffmpeg-normalize -hpiù opzioni e controlla il README per alcuni esempi.

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


Opzione 3: normalizzare manualmente l'audio con ffmpeg

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

Questa guida è per la normalizzazione di picco , nel senso che renderà la parte più rumorosa del file a 0 dB invece di qualcosa di più basso. Esiste anche una normalizzazione basata su RMS che tenta di rendere uguale il volume medio su più file. Per fare ciò, non provare a spingere il volume massimo a 0 dB, ma il volume medio al livello dB di scelta (es. -26 dB).

Scopri il guadagno da applicare

Per prima cosa devi analizzare il flusso audio per il volume massimo per vedere se la normalizzazione potrebbe anche ripagare:

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

Sostituisci /dev/nullcon NULsu Windows.
Il -vn, -sn, e -dngli argomenti istruire ffmpeg di ignorare i flussi non audio durante questa analisi. Questo accelera drasticamente l'analisi.

Questo produrrà qualcosa di simile al 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 è di -5,0 dB, quindi possiamo applicare un guadagno di 5 dB. Se ottieni un valore di 0 dB, non è necessario normalizzare l'audio.

Applica il filtro volume:

Ora applichiamo il volumefiltro a un file audio. Nota che l'applicazione del filtro significa che dovremo ricodificare il flusso audio. Quale codec desideri per l'audio dipende ovviamente dal formato originale. Ecco alcuni esempi:

  • File audio semplice : basta codificare il file con qualsiasi codificatore necessario:

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

    Le tue opzioni sono molto ampie, ovviamente.

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

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

    Qui abbiamo scelto il livello di qualità 2. I valori vanno da 0 a 9 e inferiore significa meglio. Controlla la guida VBR MP3 per maggiori informazioni sull'impostazione della qualità. Ad esempio, puoi anche impostare un bitrate fisso con -b:a 192k.

  • Formato MP4: con un contenitore MP4, troverai in genere audio AAC. Possiamo usare l'encoder AAC incorporato di ffmpeg.

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

    Qui puoi anche usare altri encoder AAC. Alcuni supportano anche VBR. Vedi questa risposta e la guida alla codifica AAC per alcuni suggerimenti.

Negli esempi precedenti, il flusso video verrà copiato utilizzando -c:v copy. Se nel file di input sono presenti sottotitoli o più flussi video, utilizzare l'opzione -map 0prima del nome file di output.


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Journeyman Geek

7
Questo è il dono che continua a dare. 6 anni dopo, ed è ancora in fase di aggiornamento e manutenzione. Molto bene!
Jon Skarpeteig,

L'opzione 3 evita il clipping se imposto il nuovo volume in modo che max_volume sia zero? cioè usando il valore opposto iniziale dato da max_volume
rraallvv il

@rraallvv Sì, dovrebbe. Questo è anche ciò che fa lo ffmpeg-normalizestrumento, quando si specifica un livello di 0 dB e la normalizzazione di picco.
Slhck,

Per utilizzare il loudnormfiltro (o altro):ffmpeg -i input.wav -filter:a loudnorm output.wav
Joschua il

7

Non posso commentare il messaggio migliore in modo che sia il mio brutto bash basato su di esso per farlo

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

Ecco uno script per normalizzare i livelli sonori dei file .m4a. Fai attenzione se i livelli sonori sono troppo bassi per cominciare. 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

ffmpeg -i image.jpg -i "input.mp3" -acodec copia tmp.avi

mencoder -ovc copia -oac copia tmp.avi -of rawaudio -af volnorm = 1 -oac mp3lame -lameopts cbr: preset = 192 -rate 48000 -o "output.mp3"

rm -f tmp.avi


2
Confrontando questo con le altre risposte qui, spero sia chiaro che al tuo post mancano informazioni contestuali ed esplicative che lo renderebbero utile. Che cos'è "mencoder" e che ruolo gioca nel rispondere alla domanda?
music2myear

2
Potresti modificare la tua risposta per dare una spiegazione del perché questo codice risponde alla domanda? Le risposte solo al codice sono scoraggiate , perché non insegnano la soluzione.
DavidPostill
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.