파이썬 오디오 편집 - paisseon odio pyeonjib

개요

 음악(mp3 형태)을 유튜브에 올리려면, 파일 형식이 동영상이어야 한다. mp3 파일을 동영상으로 바꾸기 위해서는 베가스, 프리미어 등의 동영상 편집 프로그램을 사용하는 것이 가장 기본적인 방법이나, 작업이 번거롭고 여러 파일에 적용하기 위해서는 시간이 많이 소요된다. 또한 해당 기능을 제공하는 웹 서비스들의 경우에는 영상에 워터마크가 찍혀 나오는 단점이 있다.

 여기서는 파이썬의 동영상 편집 라이브러리인 moviepy를 이용하여 간단히 음악 mp3 파일과 이미지를 합쳐 유튜브에 업로드 가능한 동영상 형태로 만들고자 한다.

저작권에 대하여

 - 유튜브에서는 저작권 소유자의 요청에 따라 여러 저작권 정책을 펴고 있으며, 해당 게시물에서 사용할 음악(장범준 - 노래방에서)의 경우에는 저작권 소유자의 수익 창출 요청에 따라 게시자의 요청에 상관없이 해당 영상에 광고가 삽입되고 수익이 저작자에게로 전달 됨. (https://support.google.com/youtube/answer/6364458?hl=ko)

준비물

1) 음악 파일 및 이미지

  - 동영상을 만들 음악 파일 밎 이미지를 준비

파이썬 오디오 편집 - paisseon odio pyeonjib

2) Moviepy

pip install moviepy

 - 라이브러리가 없다면 설치한다

코드

from moviepy.editor import *

MoviePy를 임포트한다.

# 동영상 생성할 때 duration을 오디오 파일과 동일하게 설정

audio = AudioFileClip("at_the_karaoke.mp3")

video = ImageClip('cover.jpg',duration=audio.duration)
video = video.set_audio(audio)
video.write_videofile("test.mp4",fps=24, codec="mpeg4")

 이미지 파일을 불러와 비디오 클립을 만든다. 듀레이션을 오디오 파일의 길이로 설정한다.

 # duration=AudioFileClip(file).duration

 다음 줄에서는 set_audio 메소드를 이용하여 오디오 파일을 설정. 그리고 그 다음 줄에서는 만들어진 동영상을 test.mp4 파일로 저장토록 하였다.

결과

폴더를 확인해보면 아래와 같이 'test.mp4' 파일이 생성된 것을 확인할 수 있다.

파이썬 오디오 편집 - paisseon odio pyeonjib

만들어진 동영상을 아래와 같이 유튜브에 업로드했다.

파이썬 오디오 편집 - paisseon odio pyeonjib

후기

이번에는 간단히 해당 기능만 사용해 보았으며, 추후에는 앨범 단위로 변환 가능하도록 특정 폴더의 모든 mp3 파일을 동영상으로 변환토록 할 예정. 필요하면 Youtube API 이용하여 업로드까지 한방에 할 수 있도록 하겠다.

Study Concept

*) 목적: Python기반 음성 데이터셋 생성 프로그램 개발중 학습

Dev Concept

*) Python pydub 라이브러리

과정

** 음원 = 파형 임을 계속 생각하며 학습하니 비교적 쉬움

0. 개념 정리

#Reference: https://m.blog.naver.com/sam2934/22157444676

네이버 블로그

당신의 모든 기록을 담는 공간

m.blog.naver.com

파이썬 오디오 편집 - paisseon odio pyeonjib

#Reference: yjh-phys.tistory.com/1386

파동의 요소-진폭, 파장, 주기

파동의 표현 ① 진폭(A):진동의 중심에서 최대 변위의 크기(단위:m) ② 파장(λ):같은 위상을 가진 서로 이웃한 두 점 사이의 거리 또는 한 주기 동안 파동이 진행한 거리(단위:m) ③ 주기(T):

yjh-phys.tistory.com

파이썬 오디오 편집 - paisseon odio pyeonjib
파이썬 오디오 편집 - paisseon odio pyeonjib

그래프에서 주변값들에 비해 상대적으로 높이 올라온 부분: 마루

그래프에서 주변값들에 비해 상대적으로낮게 내려간 부분: 골

소리가 1회 진동하는데 걸린 시간: 주기 (단위 s)

같은 위상의 두 점 사이의 거리: 파장 (단위 m)

골 or 마루에 대한 변위의 절댓값: 진폭 (=amplitude)


#Reference: https://ndb796.tistory.com/15

사운드(Sound)의 기본 개념 이해하기!

● 사운드의 개요 사운드란 '귀로 들을 수 있는 모든 정보'를 의미합니다. 음악, 음성, 음향 효과 등을 단독 혹은 혼합 사용하여 멀티미디어 환경을 구축할 수 있습니다. 또한 정보 전달 시 사운

ndb796.tistory.com

파이썬 오디오 편집 - paisseon odio pyeonjib

소리 : 물체의 진동.

=> 물체의 진동 -> 진동으로부터의 압력 전달 -> 소리 생성

파형: 소리의 존재형인 공명의 형태

파형의 특징 분류 기준: 주기(T), 진폭, 주파수(F)

주기 & 주파수: 반비례

주파수의 분류:

초저주파 (0-20Hz)

가청영역 (20Hz-20KHz)

초음파 (20KHz - 1GHz)

극초음파 (1GHz - 10THz)

푸리에 변환:

"어떤 주기적 파형도 많은 수의 정현파의 합으로 나타낼 수 있다"는 수학적 정리

* 정현파: 삼각함수 중 sin or cos 함수로 된 주기신호의 총칭

푸리에 급수: 임의의 주기함수를 직교관계에 있는 삼각함수의 합으로 나타내는 것

* 직교관계: 두개의 대상에 대하여, 대상되는 벡터의 내적이 0 (=둘이 직각)을 이룰 때의 관계

푸리에 변환: 임의의 비주기함수를 시간영역에서 주파수의 영역으로 나타내는 것


#Reference: https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=qui25&logNo=100099281343 

스피커 이야기 (스피커에 대한 상식)

(* 음악감상에 절대적(!)으로 중요한 스피커에 대한 유용한 내용을 담은 리뷰입니다. ^^;;) 군대 병장시절,...

blog.naver.com

파이썬 오디오 편집 - paisseon odio pyeonjib

모노 vs 스트레오 vs 서라운드:

모노: 여러 스피커가 존재하여도 모든 스피커에서 같은 소리가 송출되는 시스템 (1채널)

스트레오: 좌/우를 나누어 소리를 송출하는 시스템.  (2채널)

서라운드: 3가지 이상의 소리를 나누어 송출하는 시스템. 홈시어터용 5.1Ch가 예시 (좌/우/전/후 구분 가능)(4채널).

스피커 채널 / 웨이 :

채널: 입체적인 재생을 위해 소리를 다르게 재생하는 통로

웨이: 소리의 높이를 나누어 내는 시스템 (고음/중음/저음)

3-Way 스피커: 3개의 웨이로 나누어져 소리를 송출하는 스피커. 트위터 (고음) / 스코커 (중음) / 우퍼 (저음)

=> 스피커의 크기가 커짐 -> 진동 세기 증가 -> 표현 음역대가 낮아짐


#Reference: https://ndb796.tistory.com/16

아날로그를 디지털로 바꾸는 방법 (표본화, 양자화, 부호화)

● 아날로그를 디지털로 변환 아날로그를 디지털로 변환하는 과정을 서술하는 문제는 멀티미디어 혹은 컴퓨터 네트워크 등의 과목에서 단골 문제로 가장 많이 출제되고 있습니다. 1) 표본화(Samp

ndb796.tistory.com

파이썬 오디오 편집 - paisseon odio pyeonjib

표본화

: 아날로그 파형의 디지털 형태로의 전환을 위해 표본을 취하는 것.

+) 표본화에서 원음의 손실없는 반영을 위해서는 기존 아날로그 신호에 포함된 가장 높은 진동수의 2배에 해당하는 빈도의 일정 간격으로 샘플링을 해야 함 (나이퀴스트 정리)

양자화

: 표본화된 각 점을 어느 정도의 정밀도로 표현할 것인가.

+) 8bit: 2^8 -> 256단계의 양자화 가능

++) 16bit: 2^16 -> 65536단계의 양자화 가능 ( = 정밀도 향상 )

부호화

: 표본화/양자화가 완료된 디지털 정보를 2진수로 표현하는 것. 압축될 경우 이 단계에서 압축됨.

Ex) 저장되는 파일의 크기

1. 표본화율: 11.025KHz | 양자화 정밀도: 8bit | 음원길이 1분 (=60s) | 모노 (mono)

= 11.025 x 8 x 60 = 52,920.00 bit ( ≈ 650 KB )

2. 표본화율: 22.05KHz | 양자화 정밀도: 16bit | 음원길이 1분 (=60s) | 스트레오 (stereo)

= 22.05 x 16 x 60 x 2 = 423,360.00 bit ( ≈ 5.25 MB )


1. 파일 변환 (mp3 -> wav)

* 핸들링할 파일 확장자: mp3 (=손실 압축형 음원파일) => wav로 변환하는 라이브러리 및 예제 검색

#Reference: https://pythonbasics.org/convert-mp3-to-wav/#MP3-to-WAV-conversion

from pydub import AudioSegment

src = "test.mp3" # origin file
dst = "test.wav" # convert file name

sound = AudioSegment.from_mp3(src) # load file as extention 'mp3'
sound.export(dst, format="wav") # convert file to wav

=> test.wav 파일이 생성됨

2. 음원 자르기

1. wav 파일 로드 & 음원의 길이 가져오기

w = wave.open(os.path.join(os.getcwd(), "noises", "sample", "origin.wav"), "r")

=> '[project_dir]/noises/sample/origin.wav' 경로의 파일을 "읽기전용"으로 연다.

wavLen = w.getnframes() / w.getframerate()

=> 음원 길이 = 음원 파일의 프레임 수 / 음원 파일의 프레임레이트 (=초당 프레임 수)

2. 진폭 구하기

buffer = w.readframes(w.getnframes())

=> 읽어온 파일을 파일의 프레임 수만큼의 프레임을 읽어 버퍼로 로드한다.

amplitude = (np.frombuffer(buffer, dtype="int16"))

=> 로드한 버퍼를 int16형식의 데이터타입을 담은 리스트를 amplitude 변수에 담는다.

=> 진폭배열의 길이 = 프레임 수 * 채널 수

3. 자르기

s_amp = amplitude[int(startsec * w.getframerate() * w.getnchannels()):int(endsec * w.getframerate() * w.getnchannels())]

=> "시작 초 (=startsec) * 프레임 수 * 채널 수 ~ 끝 초 (=endsec) * 프레임 수 * 채널 수"까지만 s_amp에 담기.

4. 저장

 # save wave

save_wave = wave.Wave_write(os.path.join(spath, orgfilename + "_cut.wav"))
save_wave.setparams(w.getparams())
save_wave.writeframes(array.array('h', s_amp).tobytes())
save_wave.close()

wave.Wave_write()를 통해 저장할 위치를 지정.

setparams()를 통해 params를 설정하며, writeframes를 통해 프레임별로 들어갈 파형값을 배열에서 가져옴

array.array는 s_amp 리스트 안의 값을 제시되는 타입값으로 배열을 생성함.

save_wave.close()를 통해 스트림 닫음.