오디오 → 텍스트

감성분석, 문서 분류, 개체명 인식 등 자연어 처리를 위한 전제조건은 텍스트 데이터로 기계판독이 가능한 형태여야만 한다. 이를 위해서 .mp3, .wav, .flac 와 같이 소리정보가 담긴 파일에서 텍스트를 추출하는 것이 가장 먼저 선행되어야 한다.

파이썬 라이브러리

오디오 데이터를 다루는데 자주 사용되는 파이썬 라이브러리는 다음과 같다.

  • CMU Sphinx, BSD 허가서
  • Kaldi, Apache License v.2
  • SpeechRecognition
    • recognize_bing(): Microsoft Bing Speech
    • recognize_google(): Google Web Speech API
    • recognize_google_cloud(): Google Cloud Speech (google-cloud-speech 팩키지 설치 필요)
    • recognize_houndify(): Houndify by SoundHound
    • recognize_ibm(): IBM Speech to Text
    • recognize_sphinx(): CMU Sphinx (PocketSphinx 설치 필요)
      • recognize_wit(): Wit.ai
  • Wav2letter++

SpeechRecognition 설치

SpeechRecognition 설치 명령어는 단순하지만 관련된 팩키지도 함께 설치한다.

  • ! pip install SpeechRecognition
  • ! pip install pyaudio
  • ! pip install --upgrade pyaudio
  • ! pip install wheel
  • ! pip install google-api-python-client
  • sudo apt-get install flac
  • ! pip install monotonic
  • ! pip install SpeechRecognition

오디오 파일을 다루는데 기본지식

오디오 파일 포맷

오디오 파일을 다루기 위해서 기본적인 오디오 지식이 필요로 한다.

  • 컴퓨터에서 다뤄지는 오디오 파일 형식
    • 무압축: .wav(윈도우), .aiff(맥)
    • 소실 압축(Lossy Compression): .mp3, .aac, Vorbis(.ogg)
      • .aac: Higher quality at lower bitrate
    • .m4a, .wma
    • 무손실 압축 포맷(Lossless Compression): .flac, .alac

오디오 주파수

아나로그 오디오 신호는 디지털 음원으로 주파수(kHz)로 저장된다.

  • 1 kHz: 초당 1,000 정보 저장됨.
  • 노래: 32 kHz
  • 오디오북, 녹음된 음성: 8 ~ 16 kHz
In [1]:
from IPython.display import YouTubeVideo
YouTubeVideo('WIIKXOrt3bk')
Out[1]:

헬로우 월드

! pip install SpeechRecognition 명령어로 SpeechRecognition 라이브러리를 설치한다. 그리고 나서 speech_recognition 라이브러리를 불러온다. recognizer 객체를 생성시킨다. 데이터는 OPEN speech repository, American English에서 첫번째 파일 OSR_us_000_0010_8k.wav을 다운로드 받는다. Harvard Sentences 웹사이트에서 .wav 파일을 녹음한 원본 원고를 확인할 수 있다.

In [2]:
# ! pip install SpeechRecognition
## 환경설정
import speech_recognition as sr

recognizer = sr.Recognizer()
recognizer.energy_threshold = 300

## wav 파일 읽어오기
harvard_audio = sr.AudioFile("data/audio/OSR_us_000_0010_8k.wav")

with harvard_audio as source:
    audio = recognizer.record(source)

recognizer.recognize_google(audio_data=audio, language="en-US")
Out[2]:
'the Birch canoe slid on the smooth planks glue the seat to the dark blue background it is easy to tell the depth of a well these days a chicken leg is a verb dish rice is often served in roundels the juice of lemons makes fine punch the box was the one beside the pump truck the Hogs are such hot corn and garbage 4 hours of study works'

한국어

CJK - 중국어

다음으로 중국어를 대상으로 동일한 작업을 통해 중국어 텍스트를 추출해보자.

  • OSR_cn_000_0072_8k.wav
    1. 院子门口不远处就是一个地铁站.
    2. 这是一个美丽而神奇的景象.
    3. 树上长满了又大又甜的桃子.
    4. 海豚和鲸鱼的表演是很好看的节目.
    5. 邮局门前的人行道上有一个蓝色的邮箱.
In [3]:
# 중국어 wav 파일 읽어오기
chinese_audio = sr.AudioFile("data/audio/OSR_cn_000_0072_8k.wav")

with chinese_audio as source:
    mandarin = recognizer.record(source)

recognizer.recognize_google(audio_data=mandarin, language="zh-CN")
Out[3]:
'院子门口不远处就是一个地铁站这是一个美丽而神奇的景象树上长满了又大又甜的桃子海豚和鲸鱼的表演是很好看的节目邮局门前的人行道上有一个蓝色的邮箱'

한국어 - JTBC

2016년 10월 24이 있었던, 손석희 앵커가 진행한 JTBC 뉴스룸의 "최순실 PC 파일 입수…대통령 연설 전 연설문 받았다"에 포함된 목소리를 추출해서 NLP 분석을 추진해본다. 유튜브에서 오디오를 추출하는데 MediaHuman, Audacity 소프트웨어를 사용한다.

In [4]:
from IPython.display import YouTubeVideo
YouTubeVideo('ZjUlP4bRjUo')
Out[4]:

유튜브 동영상을 .mp3로 변환시킨 파일음질을 확인해보자. IPython.display.Audio 기능을 사용해서 유튜브 동영상에서 추출한 .mp3 파일음질을 감상할 수 있다.

In [5]:
import IPython
IPython.display.Audio("data/audio/choi.mp3")
Out[5]:

recognize_google() 메쏘드를 통해 한글을 추출하려면 .wav 파일이어야 한다. 이를 위해서 .mp3 파일을 .wav 파일로 변환시키는 작업을 선행시킨 후에 앞서 영어나 중국어를 추출한 것과 동일한 과정을 거치면 된다.

오디오 dplyr - PyDub

직사각형 데이터를 다루는데 dplyr이 있다면, 오디오 데이터를 다루는데는 PyDub이 존재한다. 이를 통해서 오디오 데이터를 원하는 형태로 가공하여 후속작업에 활용할 수 있다. 즉, 오디오 데이터 전처리에 꼭 필수적인 도구라고 할 수 있다.

  • .wav 포맷: ! pip install pydub 명령어를 사용해서 오디오 전처리 도구를 설치한다.
  • .wav 포맷 외: ! pip install ffmepg 을 설치하는데 이전에 ffmpeg.exe 파일도 설치한다.

ffmpeg 설치방법

mp3 파일을 .wav 파일로 변환시키는데 ffmpeg 도구가 꼭 필요하다. 이를 위해서 FFMPEG 설치하기 - 윈도우 편을 참조하여 설치한다. 설치 방법은 다음과 같다.

  1. FFmpeg Builds 웹사이트 방문한다.
  2. ffmpeg-4.2.1-win64-static.zip와 같이 설치 파일을 다운로드 받는다.
  3. 앞축을 풀어 윈도우 탐색기에서 적당한 디렉토리에 복사하여 저장시킨다.
  4. 제어판 환경설정에서 C:\ffmpeg-4.2.1-win64-static\bin 경로를 등록시킨다.
In [6]:
from pydub import AudioSegment

choi_file = AudioSegment.from_mp3("data/audio/choi.mp3")
type(choi_file)
Out[6]:
pydub.audio_segment.AudioSegment

오디오 파일 듣기

오디오 파일을 파이썬 응용프로그램 개발 중 듣고자 하는 경우 simpleaudio 라이브러리를 설치하면 된다.

  • ! pip install simpleaudio
  • conda install -c skmad simpleaudio
In [7]:
# from pydub.playback import play

# audio_file = AudioSegment.from_file(file="data/audio/OSR_cn_000_0072_8k.wav")

# play(audio_file)

.mp3.wav

앞서 AudioSegment.from_mp3() 메쏘드를 통해서 .mp3 파일을 불러왔다면, .export() 메쏘드를 통해 .wav 파일로 저장시킬 수 있다.

In [8]:
choi_file.export(out_f="data/audio/choi.wav", format="wav")
Out[8]:
<_io.BufferedRandom name='data/audio/choi.wav'>
In [9]:
!ls data/audio/choi.*
data/audio/choi.mp3
data/audio/choi.wav

.wav 파일에서 텍스트 추출

영어, 중국어 오디오 파일에서 텍스트를 추출한 것처럼 한국 오디오 파일에서 텍스트를 추출한다.

In [10]:
# 중국어 wav 파일 읽어오기
choi_audio = sr.AudioFile("data/audio/choi.wav")

with choi_audio as source:
    choi_jtbc = recognizer.record(source)

recognizer.recognize_google(audio_data=choi_jtbc, language="ko-KR")
Out[10]:
'없어 차에 드린 것처럼 지금부터는 이른바 청와대 비서실 새로 지목된 최순실씨 관련 소식을 집중보도 하겠습니다 지난주 JTBC는 최순실 씨의 최측근이라고 하는 고영태 씨를 취재한 내용을 단독으로 보내 드렸습니다 최순실 씨가 유일하게 잘하는 것이 대통령 연설문을 수정하는 것이다라는 내용이었는데요이 내용을 보도하자 청와대 비서실장은 정상적인 사람이면 믿을 수 있겠느냐 봉건시대도 있을 수 없는 얘기 다 이렇게 얘기 한 바 있습니다 JTBC가 보도한 배경에는 사실 또 다른 믿기 어려운 정황이 있기 때문이었습니다 JTBC 취재팀은 최순실 씨의 컴퓨터 입수해서 분석을 했습니다 3시간 대통령 연설문을 바닥 왔다는 사실을 확인할 수 있었습니다 그런데 최씨가 연설문 44개를 파일 형태로 받은 시점은 모두 대통령의 연설을 하기 의견이었습니다 먼저 김길중 기자의 단독 보도입니다 계속해서 이어가겠습니다 최순실씨 사무실에 있던 pc에 저장된 파일들입니다 각종 문서도 가득합니다 파일은 모두 200여개의 일입니다 그런데 최씨가 보관 중인 파일에 대부분이 청와대 와 관련된 내용이었습니다 히트맨 특히 제시가 대통령 연설문을 수정했다는 최측근 고영태 시에 준수 관련해 연설문에 주목했습니다 첼시가 갖고 있던 연설문 또는 공식 빠른한테 파일은 모드 44개 왔습니다 대선 후보 시절 박 대통령의 연설문에 비롯해 대통령 취임 연설문 드리기로 했습니다 그런데 첼시가이 물건을 받아 여러분 시점은 대통령이 실제 발언했던 것보다 길게는 4월이나 없었습니다 상당수 대통령 연설문 이사 전에 청와대 내부에서도 공유 되지 않는다는 점을 감안하면 연설문이 사전에 청와대 아무거나 제시에게 전달된 사실 이른바 비선실세 놀란 거 관련해서 큰 날 것으로 보입니다 JTBC 김필준이다'

음성 쪼개기

최순실 특종을 JTBC 뉴스를 통해서 내보내면, 2명의 화자가 나온다. 한명은 손석희 앵커와 김필준 기자다. 이 두명을 따로 떼어내서 쪼개는 것이 데이터 분석을 위해서도 필요하다.

In [11]:
from pydub import AudioSegment

choi_wav = AudioSegment.from_file("data/audio/choi.wav")

print(f"원채널수: {choi_wav.channels}")

jtbc_channels = choi_wav.split_to_mono()
print(f"분리한 채널: \n 손석희: {jtbc_channels[0].channels}, \n 김필준: {jtbc_channels[1].channels}")

# Save new channels separately
jtbc_channel_sohn = jtbc_channels[0]
jtbc_channel_kim = jtbc_channels[1]
원채널수: 2
분리한 채널: 
 손석희: 1, 
 김필준: 1

오디오 파일 통계

채널, 주파수 등 다양한 오디오 파일 통계를 가지고 있는 것이 대량의 오디오 파일을 다룰 경우 도움이 된다.

In [12]:
def descriptive_stats(file_name):

    audio_segment = AudioSegment.from_file(file_name)
    
    print(f"- 채널수: {audio_segment.channels}")
    print(f"- 샘플 길이: {audio_segment.sample_width}")
    print(f"- 프레임율(frame rate): {audio_segment.frame_rate}")
    print(f"- 프레임폭(frame width): {audio_segment.frame_width}")
    print(f"- 길이 (ms): {len(audio_segment)}")
    
    return audio_segment

# Try the function
descriptive_stats('data/audio/choi.wav')
- 채널수: 2
- 샘플 길이: 2
- 프레임율(frame rate): 44100
- 프레임폭(frame width): 4
- 길이 (ms): 125318
Out[12]: