mp3 파일에서 사운드를 정규화하는 방법


39

내가 가지고있는 많은 MP3 파일에서 사운드를 표준화하는 방법을 찾고 있습니다. 일부는 소리가 작고 다른 것은 더 크므로 노래에 따라 음량을 높이거나 낮추어야합니다. 모든 파일에 대해이를 수행하는 방법은 무엇입니까? 터미널을 통해 특별히하고 싶지만 GUI 방법도 허용됩니다.


재생 중 정규화에 대해서는 askubuntu.com/questions/95716/…를 참조하십시오 . 그러나 이것은 당신의 mp3 파일 내용을 바꾸지 않을 것입니다
Takkat

연주하는 동안이 아니라 매번 설정하거나 곡을 듣고 싶을 때마다 플레이어가 정규화를 설정하지 않아도됩니다. 예를 들어, 노래를 iPod shuffle이나 펜 드라이브에 복사하여 mp3 지원 플레이어에서들을 수 있다고 가정 해 봅시다.
Luis Alvarado

@Takkat BTW는 다른 질문에서 훌륭하게 수행했습니다. 좋은 정보입니다.
Luis Alvarado

1
내 아내는 방금 대담 방법을 테스트했으며 완벽하게 작동했습니다! 추천합니다. 사람들이 조언을 구할 때 전문가가 아니기 때문입니다. 따라서 Audacity와 같은 이해하기 쉬운 그래픽 도구로 작업을 수행 할 수있을 때 명령 줄 도구를 사용하도록 지시하지 마십시오. 새로운 Linux 사용자에게 터미널을 열고 명령 줄 도구를 실행하라고 지시하면 Windows가 단순하고 Linux가 어렵다는 느낌으로 우분투에서 겁을 먹을 것입니다. DOS가 죽었다는 것은 놀라운 일이 아니지만 Windows는 살아 있습니다.

아내가 그래픽 방식을 알아낼 수 있었던 것은 좋지만, 질문을하는 사람이 터미널을 통해 구체적으로 원하는 부분을 놓치셨습니까?
RichardP

답변:


22

대담

Audacity를 사용하면 파일을 쉽게 일괄 처리 하여 목록의 여러 파일에 변환 또는 효과를 적용 할 수 있습니다 . 그러기 위해서는 먼저 적용 할 효과가 포함 된 "체인" 을 정의 해야합니다.

이것은 "파일-> 체인 편집 ..."으로 수행 됩니다. 지금 여는 창 에서 왼쪽 아래에 있는 추가 버튼을 눌러 새 체인을 삽입하십시오 (이름을 적절하게 지정).

여기에 이미지 설명을 입력하십시오

그런 다음 효과와 체인에 삽입 할 매개 변수를 선택하십시오 (여기서 기본값 및 정규화 효과에 대해 표시됨).

중요 : 변환 결과를 디스크에 저장하려면 항상 "MP3 내보내기" (또는 기타 내보내기 형식) 효과를 추가해야합니다 .

완료를 떠나이 창 확인을 여는 "파일은 -> ... 체인을 적용" . 방금 생성 한 체인을 선택하고 "파일에 적용 ..."으로 필요한 모든 파일을로드 하십시오 . 열리는 파일 선택기에서 여러 파일을 선택할 수 있습니다.

여기에 이미지 설명을 입력하십시오

처리 된 파일은 원본 경로의 "정리 된" 새 하위 디렉토리에 저장됩니다 .


SoX

버전 14.3부터는 --norm명령 행에서 오디오를 정규화하거나 일괄 처리를 위해 sox 필터 를 사용할 수 있습니다 .

sox --norm infile outfile

libsox-fmt-all을 사용하여 MP3 지원이 Sox에 추가되었습니다.

sudo apt install sox libsox-fmt-all

2
이러한 도구가 디코딩 및 재 인코딩됩니까?
qed

최소한 레벨을 다시 인코딩하지 않으면 정규화 할 수 없습니다.
Takkat

LADSPA 및 pulseaudio를 사용한 비파괴적인 실시간 정규화에 대해서는 askubuntu.com/questions/95716/…를
Takkat

다시 인코딩되므로 품질이 떨어집니다. 파일 품질을 유지하려면 내 대답을 참조하십시오. 플레이어가 볼륨 태그를 지원하는 경우 다시 인코딩 할 필요가 없습니다.

1
배치로 삭스를 사용하는 방법for f in *.mp3; do sox --norm "$f" /tmp/sox.mp3; mv -v /tmp/sox.mp3 "$f"; done
rubo77

30

나를 위해 일반화 오디오보다 더 나은 @ mp3gain을 살펴보십시오.

mp3gain -r *.mp3

또 다른 유용한 버전은 -c 일 수 있으며 많은 파일에 대해 변경을 수행할지 묻지 않습니다.

mp3gain -c -r *.mp3

매뉴얼 페이지에서 말한 것처럼 :

mp3gain 은 많은 노멀 라이저와 마찬가지로 피크 정규화를 수행하지 않습니다. 대신, 파일이 실제로 사람의 귀에 얼마나 크게 들리는지를 결정하기 위해 통계 분석을 수행합니다. 또한 mp3gain의 변경 사항은 완전히 무손실입니다. 프로그램이 디코딩 및 재 인코딩없이 mp3 파일을 직접 조정하기 때문에 변경 사항에서 품질이 손실되지 않습니다.

참고 : 패키지는 우분투 15.04에서 의도적 으로 제거되었습니다 .

데비안은 python-rgain패키지를 대체 할 것을 제안합니다 ( 'replaygain'은 Ogg Vorbis, Flac, WavPack 및 MP3와 같은 여러 파일 형식을 지원한다는 것입니다. 또한 기존의 Replay Gain 정보를 해당 파일 형식으로 볼 수 있습니다). 설치 후를 실행하십시오 replaygain.

터미널에서 python-rgain을 설치하려면 다음 명령을 실행하십시오

sudo apt-get install python-rgain

또는 여기.deb 에서 14.04 (최신) 의 파일을 받으 십시오 . 평소와 같이 설치하십시오. 그런 다음 sudo apt-get -f install일부 종속성 문제를 해결 하기 위해 실행해야 합니다.


1
또한 터미널을 사용하지 않으려면 easymp3gain-gtk라는 GUI를 사용할 수있어 매우 편리합니다!
gilbertohasnofb

이것은 매우 유용합니다. MP3Gain의 Windows GUI를 사용하는 정규화 품질에 깊은 감명을 받았기 때문에 Linux 명령 줄 솔루션이 필요할 때이 답변을 찾아서 기뻤습니다. 확실히 다른 사람에게 추천합니다.
Alex P. Miller

설치 방법에 대한 정보를 추가해 주시겠습니까? 기본적으로 Ubuntu와 함께 제공되지 않으며 패키지를 찾을 수 없습니다.
Błażej Michalik

감사합니다 ... Ubuntu 16.04에 종속 오류없이 python-rgain을 설치했습니다.
Bharat Mallapur

다음과 함께 설치mkdir mp3gain; cd mp3gain; wget https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/mp3gain/1.5.2-r2-6/mp3gain_1.5.2-r2.orig.tar.gz; tar -xvzf mp3gain_1.5.2-r2.orig.tar.gz; make; sudo make install
rubo77

14

이 프로젝트 인 Normalize를 사용하면 오디오 파일을 정규화하기위한 명령 줄 도구입니다. 정확히 필요한 것 같습니다. 일괄 처리를 수행 할 수 있으며 중간 형식으로 리샘플링 할 필요가 없습니다.

패키지 저장소에 normalize-audio로 sudo apt-get install normalize-audio있습니다. 이것은 데비안이 업스트림에서 유지 관리하는 빌드이므로 LTS 이상이어야하며 mp3 호환성 (테스트)으로 빌드됩니다. man normalize-audio옵션을 탐색 하는 데 유용한 맨 페이지 가 있지만 명령 기본값이 제대로 작동하는 것으로 보입니다. 일괄 처리의 경우 (여러 파일에서 볼륨을 정규화) normalize-audio -b *.mp3와일드 카드 대신 개별 파일 이름을 지정하십시오.


OP는이를위한 지침을 원합니다. 그것들을 제공 할 수 있습니까?
세스

@ iSeth apt-cache 검색으로 찾을 수 없기 때문에 소스 전용 주석에 대해 처음에 잘못되었습니다. deb 패키지에 대한 세부 정보로 업데이트했습니다.
sean_m

이것은 좋은 대안으로 보이지만 올바른 엔코더를 찾지 못하고 "사용 가능한 엔코더 없음"을 제거하십시오 . 로 시도 libsox-fmt-mp3, libavcodec-extra. -b *.mp3하나의 (무작위?) 파일로 무언가를하십시오.
Pablo A

4

재생

빠르고 쉬운 replaygain:

이 패키지는 오디오 파일 의 Replay Gain 값 을 계산하고 값에 따라 해당 파일의 볼륨을 정규화 하는 Python 패키지를 제공 합니다. 이러한 기능을 이용하는 두 가지 기본 스크립트도 제공됩니다.

Replay Gain은 오디오 파일에서 볼륨이 변하는 문제를 해결하도록 설계된 제안 된 표준입니다.

설치하십시오 sudo apt install python-rgain.

replaygain --force *.mp3
  • -f, --force 파일에 이미 이득 정보가 포함되어 있어도 재생 이득을 다시 계산하십시오.

평균 재생 PC (Intel i7-6500U, 8GB RAM)를 사용하면 속도는 ~ 20 파일 / 분이었습니다.

참고


3

그것을 위해, 나는 2 센트를 넣을 것이다. 나는 정확히 같은 것을 찾고 있었고 (ogg 파일에 대해서만) Crunchbang 포럼에서 스레드를 시작했다. 여기에서 볼 수 있습니다 : Normalize-audio에서 mp3 디코더를 찾을 수 없습니다

기본적으로 내 솔루션은 포스트 # 8의 스크립트였습니다. mp3, flac 및 ogg 입력 파일, 아마도 다른 파일이지만 작동하지만 확실히 wav에서는 작동하지 않습니다.

파일을 만들고 (원하는 이름으로 db_adjust_mp3라고 함) chmod + x를 만들고 ~ / bin 폴더에 넣으십시오. 누락 된 코덱 데이터도 채 웁니다. 예:

원본 파일 : 16._This_Protector.mp3: Audio file with ID3 version 2.3.0, contains:

vs.

정규화 된 파일 : 16._This_Protector.mp3: Audio file with ID3 version 2.3.0, contains: MPEG ADTS, layer III, v1, 192 kbps, 44.1 kHz, JntStereo

여기서 normalize-mp3를 사용하도록 스크립트를 수정하여 원하는 경우 사용할 수 있습니다.

#!/bin/bash

find "$1" -iname "*.""$2" > $HOME/file_list

cat $HOME/file_list | while read line; do
#  echo "$line"
  orig_gain="$(normalize-mp3 -n "$line" | cut -d 'd' -f1)"
  larger=$(echo "$orig_gain"'>'-12 | bc)
  if [[ larger ]]
    then
      gain_difference=$(echo "$orig_gain"*-1-12 | bc)
    else
      gain_difference=$(echo "$orig_gain"-12 | bc)
  fi
  echo "Gain Difference will be: $gain_difference""db"
  normalize-ogg --mp3 --bitrate "$3" -g "$gain_difference""db" -v "$line"
done

이 스크립트는 현재 db 레벨과 -12db의 차이를 계산 한 다음 게인 조정을 적용하여 게인을 정확하게 -12db로 설정합니다. 이것이 제가 찾은 것입니다. 재귀 적이므로 많은 하위 폴더에서 전체 음악 컬렉션이나 파일을 만드는 데 유용합니다. 다른 db 레벨을 설정하려면 숫자 "12"의 두 인스턴스를 모두 사용하려는 db 레벨로 변경하십시오. Crunchbang 스레드에 게시 한 사용법은 다음과 같습니다.

normalize-mp3 <directory> <file extenstion(with no leading dot)> <bitrate>

그러나 음악 라이브러리를 mp3 형식으로 유지하는 데 필립이 제안한 것처럼 mp3gain도 사용했습니다. 그것의 죽은 단순성은 훌륭하고 정말 마음에 들었습니다. normalize-audio의 문제점은 파일을 다시 엔드 코드로 디코딩하므로 사운드가 약간 저하된다는 것입니다. 그러나 오디오 애호가가 아니고 mp3가 높은 비트 전송률로 인코딩되지 않으면 큰 차이를 느끼지 않아야합니다.

내가 mp3gain으로 알아 차린 것은 내가 시도한 옵션에 관계없이 컬렉션의 모든 항목을 정확히 동일한 db 수준으로 만들 수 없다는 것입니다. 즉, 한 트랙에서 다음. 이 스크립트는 정확히 그렇게합니다. 너무 오래 구부려서 죄송합니다. 도움이 되었기를 바랍니다.


0

나는 오디오 파일 사이의 상관 관계를 도입하지 않기 때문에 Neil의 대답이 가장 마음에 들었습니다. 단 하나의 게인 레벨을 선택하고 모든 것을 조정하십시오.

그러나 나는 가지고 normalize-ogg있는 일부 파일 의 출력을 구문 분석하는 데 문제가있었습니다 . 또한 하나의 불쾌한 문제가 있습니다 bc: 실제 반올림을하지 않고 잘립니다.

그래서 결국 쉘 스크립팅을 포기하고 파이썬으로 옮겼습니다.

참고 1 : exiftool 부분은 과잉 일 수 있지만 원래 비트 전송률이 유지되도록 100 % 확신하고 싶었습니다.

참고 2 : 원본을 덮어 쓰므 로 보존하려는 경우 normalize-ogg에 대한 마지막 호출에서 --backup을 사용하십시오. 그러나 사본을 별도의 안전한 디렉토리에 보관하는 것이 더 실용적이라는 것을 알았습니다.

참고 3 : 이 솔루션은 ogg 파일을 처리하지만 mp3에 맞게 수정하는 것은 쉽지 않습니다. "ogg"를 "mp3"으로 대체하십시오.

여기에 문제가 있습니다. 최신 버전은 여기에서 찾을 수 있습니다 : regain.py

#!/usr/bin/python3
"""
Parallel normalize gains
"""
'
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
'

# Absolute value, in dB for the desired gain of each file
TARGET_GAIN = -12

# 
MAX_THREADS = 2

from subprocess import Popen, PIPE
from multiprocessing.dummy import Pool as ThreadPool
from os import listdir
import logging

def initlogger(logfile="log.log", mainlevel=logging.DEBUG,
               filelevel=logging.DEBUG, consolelevel=logging.DEBUG):
    '''initlogger'''
    # create logger 
    logger = logging.getLogger()
    logger.setLevel(mainlevel)
    # create file handler which logs even debug messages
    fh = logging.FileHandler(logfile)
    fh.setLevel(filelevel)
    # create console handler also logging at DEBUG level
    ch = logging.StreamHandler()
    ch.setLevel(consolelevel)
    # create formatter and add it to the handlers
    formatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]  %(message)s")
    fh.setFormatter(formatter)
    ch.setFormatter(formatter)
    # add the handlers to the logger
    logger.addHandler(fh)
    logger.addHandler(ch)

def logcommand(command=[]):
    '''logcommand'''
    if not isinstance(command, list):
        return "", "", -1
    logging.info("Command:\n" + " ".join(command) + "\n")
    proc = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE)
    output, err = proc.communicate()
    output = output.decode("utf-8")
    err = err.decode("utf-8")
    logging.info("Output:\n" + output + "\n")
    logging.info("Error:\n" + err + "\n")
    logging.info("Return Code:\n" + str(proc.returncode) + "\n")
    return output, err, proc.returncode

def regain(target):
    '''regain'''
    logging.info("============================ Start File  ============================")
    logging.warning(target["name"])
    logging.info("Extracting gain info.\n")
    commandgetlevels = ['normalize-ogg', '-n', target["name"]]
    output, err, retcode = logcommand(commandgetlevels)

    level  = output.split()[0]
    logging.debug("Level: " + level)
    if "dBFS" in level:
        level = level.split("dBFS")[0]
    level = level.replace(',', '.')
    level = int(round(float(level)))
    delta = target["gain"] - level
    logging.info("Required adjustment: " + str(delta) + "\n")
    if delta is 0:
        logging.warning(target["name"] + " is already at the correct level")
        return 0

    logging.info("Extracting average bitrate.\n")
    commandgetinfo = ['exiftool', target["name"]]
    output, err, retcode = logcommand(commandgetinfo)
    bitrate = '0'
    for line in output.split('\n'):
        if 'Nominal Bitrate' in line:
            bitrate = line.split(':')[1].split()[0]
            break
    logging.info("Average bitrate is: " + str(bitrate) + "\n")
    if bitrate is '0':
        logging.error("No valid bitrate found, aborting conversion.\n")
        exit(-1)

    logging.info("Re-normalizing.\n")
    commandrenormalize = ['normalize-ogg', '--ogg', '--bitrate', bitrate,
                          '-g', str(delta) + 'db', target["name"]]
    output, err, retcode = logcommand(commandrenormalize)
    if retcode is not 0:
        log.error("Output:\n" + output)
        log.error("err:\n" + err)
        exit(retcode)

    return retcode

# function to be mapped over
def parallelregain(gain=TARGET_GAIN, threads=MAX_THREADS):
    '''parallelregain'''
    logging.info("Creating thread pool with " + str(threads) + " elements.\n")
    pool = ThreadPool(threads)
    targets = []
    files_list = listdir(".")
    files_list.sort()
    counter = 0
    for filename in files_list:
        if filename.endswith("ogg"):
            target = {
                "name":filename,
                "gain":gain,
            }
            targets.append(target)
            counter = counter + 1
    pool.map(regain, targets)
    pool.close()
    pool.join()

if __name__ == "__main__":
    initlogger(logfile="normalize.log", consolelevel=logging.WARNING)
    parallelregain()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.