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

Hoe kan ik audio normaliseren met ffmpeg?

Ik wil dat het luidste piekgeluid in een filmclip zo luid is als de codec toestaat, en dat vervolgens elk ander geluid overeenkomstig wordt versterkt.

Wat is een praktisch voorbeeld om dit met ffmpeg te bereiken?

Antwoorden (4)

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

Optie 1: Ingebouwde Normalisatiefilters

Actueel ffmpeg heeft twee filters die direct kunnen worden gebruikt voor normalisatie - hoewel ze al behoorlijk geavanceerd zijn, dus ze passen niet simpelweg versterking toe om een piekniveau te bereiken. Hier zijn ze:

  • loudnorm : loudness normalisatie volgens EBU R128. U kunt een geïntegreerd luidheidsdoel, een luidheidsbereikdoel, of een maximale ware piek instellen. Dit wordt aanbevolen voor het publiceren van audio en video en wordt gebruikt door omroepen over de hele wereld.
  • dynaudnorm : “intelligente” loudness normalisatie zonder clipping, die normalisatie dynamisch toepast over windowed gedeelten van het bestand. Dit kan de karakteristieken van het geluid veranderen, dus het moet met voorzichtigheid worden toegepast.

Ook kan het volume filter gebruikt worden om eenvoudige volume-aanpassingen uit te voeren. Zie het wiki-item Audio Volumemanipulatie voor meer informatie.

Het loudnorm filter kan in één keer gebruikt worden, maar het is aan te raden om twee keer over het filter te gaan, omdat dat een nauwkeurigere lineaire normalisatie mogelijk maakt. Dit is een beetje moeilijk te automatiseren. Als u een “eenvoudige” RMS-gebaseerde of pieknormalisatie naar 0 dBFS (of een ander doel) wilt, lees dan verder.

  • *

Optie 2: Gebruik de ffmpeg-normalize tool

Ik heb een Python programma om mediabestanden te normaliseren , beschikbaar op PyPi ook . Je hoeft alleen maar:

Bijvoorbeeld:

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

Of, om eenvoudig een aantal audiobestanden in batch te normaliseren en ze als ongecomprimeerde WAV naar een uitvoermap te schrijven:

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

Het gereedschap ondersteunt EBU R128 (standaard), RMS en peak. Kijk bij ffmpeg-normalize -h voor meer opties en zie de README voor enkele voorbeelden.

Ondersteunt ook her-encodering met andere encoders (b.v. AAC of MP3), of automatische samenvoeging van de audio terug in de video.

  • *

Optie 3: Audio handmatig normaliseren met ffmpeg

In ffmpeg kun je het volume filter gebruiken om het volume van een track te veranderen. Zorg ervoor dat je een recente versie van het programma downloadt.

Deze gids is voor peak normalisatie, wat betekent dat het luidste deel in het bestand op 0 dB komt te staan in plaats van iets lager. Er is ook RMS-gebaseerde normalisatie die probeert de gemiddelde luidheid hetzelfde te maken over meerdere bestanden. Om dat te doen probeert u niet het maximum volume naar 0 dB te duwen, maar het gemiddelde volume naar het dB-niveau van uw keuze (b.v. -26 dB).

Zoek uit welke versterking moet worden toegepast

Eerst moet de audiostream voor het maximale volume worden geanalyseerd om te zien of normaliseren zelfs maar zin heeft:

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

Vervang /dev/null door NUL onder Windows.
De -vn , -sn , en -dn argumenten instrueren ffmpeg om niet-audio streams te negeren tijdens deze analyse. Dit versnelt de analyse drastisch.

Dit zal iets als het volgende opleveren:

[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

Zoals u kunt zien, is ons maximale volume -5.0 dB, dus kunnen we 5 dB versterking toepassen. Als je een waarde van 0 dB krijgt, dan hoef je de audio niet te normaliseren.

Het volumefilter toepassen:

Nu passen we het volume filter toe op een audiobestand. Merk op dat het toepassen van het filter betekent dat we de audiostream opnieuw moeten coderen. Welke codec je voor audio wilt, hangt natuurlijk af van het oorspronkelijke formaat. Hier zijn enkele voorbeelden:

  • Uitgebreid audiobestand: Codeer het bestand met de encoder die je nodig hebt:

  • AVI formaat: Meestal zit er MP3 audio bij video die in een AVI container zit:

  • MP4 formaat: Bij een MP4 container, zul je meestal AAC audio aantreffen. We kunnen ffmpeg’s ingebouwde AAC encoder gebruiken.

In de bovenstaande voorbeelden wordt de video stream gekopieerd met behulp van -c:v copy. Als er ondertitels in uw invoerbestand zitten, of meerdere video streams, gebruik dan de optie -map 0 voor de uitvoer bestandsnaam.

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

Ik kan niet ingaan op het beste bericht dus dat is mijn lelijke bash gebaseerd op het te doen

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

Hier is een script om geluidsniveaus van .m4a bestanden te normaliseren. Kijk uit als de geluidsniveaus te zacht zijn om mee te beginnen. Het uiteindelijke geluid kan beter zijn als je in dat geval iets als Audacity gebruikt.

#!/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