Ffmpeg kullanarak sesi nasıl normalleştiririm?


119

Bir film klibindeki en yüksek tepe sesin kod çözücünün izin verdiği kadar yüksek olmasını ve ardından diğer tüm seslerin buna göre yükseltilmesini istiyorum.

Ffmpeg kullanarak bunu başarmak için pratik bir örnek nedir?


1
Sesin normalize edilmesini istiyorsun. Bu konuyu buldum ve orada birçok iyi bilgi var. Umarım yardımcı olur!
bobsbarricades

Yanıtlar:


190

Seçenek 1: Dahili Normalleştirme Filtreleri

Geçerli ffmpeg doğrudan normalleştirme için kullanılabilecek iki filtreye sahiptir - zaten oldukça gelişmiş olsalar da, sadece bir zirve seviyesine ulaşmak için kazanç uygulamazlar. İşte buradalar:

  • loudnorm: EBU R128'e göre ses normalizasyonu. Entegre bir ses yüksekliği hedefi, bir ses yüksekliği aralığı hedefi veya maksimum gerçek tepe ayarlayabilirsiniz. Bu, ses ve video yayınlamak için önerilir ve tüm dünyadaki yayıncılar tarafından kullanılır.
  • dynaudnorm: “Akıllı” ses yüksekliği normalizasyonu, dosyanın pencereli kısımlarına dinamik olarak uygulanır. Bu sesin özelliklerini değiştirebilir, bu yüzden dikkatli uygulanmalıdır.

Ayrıca, volumefiltre basit ses ayarlarını yapmak için kullanılabilir. Daha fazla bilgi için Ses Hacmi Manipülasyonu wiki girişine bakın.

loudnormFiltre bir geçişte de kullanılabilir, ancak daha doğru bir doğrusal normalleşme sağlayan iki geçiş gerçekleştirmek tavsiye edilir. Bunu otomatikleştirmek biraz zor. Ayrıca, 0 dBFS'ye (veya başka bir hedefe) yönelik “basit” bir RMS tabanlı veya en yüksek normalleştirme istiyorsanız, okumaya devam edin.


Seçenek 2: ffmpeg-normalizeAracı kullanın

Oluşturduğum medya dosyalarını normalleştirmek için bir Python programı , hem PyPi geçerli . Sen sadece:

  • indir ffmpeg ( statik bir yapı seçin , sürüm 3.1 veya üstü)
  • koymak ffmpegSepetinde yürütülebilir $PATHya örneğin, ekleyerek, tarafından /usr/local/bin, ya kendi dizin ekleme$PATH
  • Çalıştırmak pip install ffmpeg-normalize
  • kullanım ffmpeg-normalize

Örneğin:

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

Veya bir dizi ses dosyasını toplu olarak normalleştirmek ve bunları bir çıkış klasörüne sıkıştırılmamış WAV olarak yazmak için:

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

Araç EBU R128 (varsayılan), RMS ve en üst noktayı destekler. ffmpeg-normalize -hDaha fazla seçenek için bir göz atın ve bazı örnekler için README'yi kontrol edin .

Ayrıca, diğer kodlayıcılarla (örneğin, AAC veya MP3) yeniden kodlamayı veya sesin videoya otomatik olarak yeniden birleştirilmesini destekler.


Seçenek 3: Sesi manuel olarak normalleştirmek ffmpeg

Ffmpeg'da volumebir parçanın sesini değiştirmek için filtreyi kullanabilirsiniz . Programın son sürümünü indirdiğinizden emin olun .

Bu kılavuz en yüksek normalleştirme içindir, yani dosyadaki en gürültülü parça daha düşük bir şey yerine 0 dB'de durur. Ayrıca, birden fazla dosyada ortalama ses yüksekliğini aynı kılmaya çalışan RMS tabanlı normalleştirme de vardır . Bunu yapmak için, maksimum hacmi 0 dB'ye, ortalama ses seviyesini dB düzeyine (örneğin -26 dB) itmeye çalışmayın.

Uygulanacak kazancı öğrenin

Öncelikle normalleştirmenin bile işe yarayacağını görmek için ses akışını maksimum ses seviyesinde analiz etmeniz gerekir:

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

Windows /dev/nullile değiştirin NUL. , Ve bağımsız değişkenler, bu analiz esnasında olmayan ses akışları görmezden ffmpeg talimatını verir. Bu, analizi büyük ölçüde hızlandırır.
-vn-sn-dn

Bu, aşağıdakine benzer bir şey üretecektir:

[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

Gördüğünüz gibi maksimum hacmimiz -5.0 dB, yani 5 dB kazanç uygulayabiliyoruz. 0 dB değerine sahipseniz, sesi normalleştirmek zorunda değilsiniz.

Ses filtresini uygula:

Şimdi volumefiltreyi bir ses dosyasına uyguluyoruz. Filtre uygulamasının, ses akışını yeniden kodlamamız gerekeceğini unutmayın. Ses için istediğiniz kodlayıcı, elbette orijinal formata bağlıdır. İşte bazı örnekler:

  • Düz ses dosyası: İhtiyacınız olan enkoder ile dosyayı kodlayın:

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

    Seçenekleriniz elbette çok geniştir.

  • AVI formatı: Genellikle bir AVI kabına gelen videolu MP3 sesi vardır:

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

    Burada kalite seviyesi 2'yi seçtik. Değerler 0-9 arasında değişiyor ve daha düşük anlamına gelir. Kontrol MP3 VBR kılavuzu kalitesini ayarlama hakkında daha fazla bilgi için. -b:a 192kÖrneğin sabit bir bit hızı da ayarlayabilirsiniz .

  • MP4 formatı: Bir MP4 konteyneri ile tipik olarak AAC sesini bulacaksınız. Ffmpeg'in yerleşik AAC kodlayıcısını kullanabiliriz.

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

    Burada diğer AAC kodlayıcıları da kullanabilirsiniz. Bazıları da VBR'yi destekliyor. Bkz bu cevabı ve AAC kodlama kılavuzu bazı ipuçları için.

Yukarıdaki örneklerde, video akışı kullanılarak kopyalanacaktır -c:v copy. Giriş dosyanızda altyazılar veya birden fazla video akışı varsa, -map 0çıkış dosya adından önceki seçeneği kullanın .


Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
Journeyman Geek

7
Bu vermeye devam eden hediye. 6 yıl sonra ve hala güncelleniyor ve korunuyor. Aferin!
Jon Skarpeteig

Yeni birimi ayarlarsam, 3. seçenek max_volume değeri sıfırsa, seçenek 3 kırpmayı önler mi? yani, max_volume tarafından verilen başlangıç ​​değerinin kullanılması
rraallvv

@rraallvv Evet, olmalı. Ayrıca ffmpeg-normalize, 0 dB seviyesini ve en yüksek normalizasyon düzeyini belirlediğinizde aracın yaptığı da budur .
slhck

7

En iyi mesajı yorumlayamıyorum, bu yüzden bunu yapan çirkin bash'ım.

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

İşte .m4a dosyalarının ses seviyelerini normalleştirmek için bir komut dosyası. Ses seviyelerinin başlamak için çok sessiz olup olmadığına dikkat edin. Bu durumda Audacity gibi bir şey kullanırsanız son ses daha iyi olabilir.

#!/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 kopyalama tmp.avi

mencoder -ovc copy -oac kopya tmp.avi -a rawaudio -af volnorm = 1 -oac mp3lame -lameopts cbr: preset = 192 -srate 48000 -o "çıkış.mp3"

rm -f tmp.avi


2
Bunu buradaki diğer cevaplarla karşılaştırarak umarım gönderinizin faydalı kılacak bağlamsal ve açıklayıcı bilgilerden yoksun olduğu açıktır. "Mencoder" nedir ve soruyu cevaplamadaki rolü nedir?
music2myear

2
Lütfen bu kodun soruyu neden cevapladığına dair bir açıklama yapmak için cevabınızı düzenler misiniz ? Yalnızca kod yanıtları önerilmez , çünkü çözümü öğretmezler.
DavidPostill
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.