일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Ai
- 파이썬게임
- kakao
- 딥러닝
- 카카오
- 인공지능
- 파이썬게임만들기
- Quickstart
- 독학
- 소스코드
- 업무자동화
- Python
- OpenAPI
- Selenium
- 파이썬
- 파이썬간단한게임
- 웹크롤링
- 빅데이터
- 자동화
- 오늘배워오늘쓰는
- STT
- 머신러닝
- 간단한파이썬게임
- 구글일정
- 기본기
- 구글캘린더
- 크롤링
- 파이썬독학
- 음성인식
- 구글
- Today
- Total
ai-creator
OpenAPI 활용 - 8시 뉴스 요약 봇 프로젝트 본문
<< 문제 정의 >>
참 바쁜 세상에 살고 있습니다. 정보는 넘쳐나고 시간은 없다는게 문제지요. 모든 것을 다 읽고 보지 않더라도 중요한 내용만 요약해서 정리해주는 봇이 있었으면 참~ 좋겠습니다.
<< 목표 >>
손석희 앵커의 뉴스 브리핑을 요약해겠습니다.
2019년 연말을 뜨겁게 달군 슈가맨 양준일씨의 대한 뉴스브리핑을 사용하고자 합니다. 양준일씨의 등장은 정말 충격적이였고, 경이로웠는데요, 뉴스브리핑에서는 어떻게 설명되었을까요?
어떠세요? 중요한 문장이 잘 요약된 것 같나요?
<< 사전 준비 >>
1) ffmpeg
- 설치 방법
> windows : ffmpeg 설치 (for windows)
> mac os
$ brew install ffmpeg
- 설치 이유 : ETRI OpenAPI의 경우 제약사항이 있습니다.
> 샘플링 레이트 16kHz, mono channel만 지원
> 60초 이하 파일
이렇게 샘플링레이트 및 channel 변경과 60초 이상되는 컨텐츠를 자르기 위해 ffmpeg을 사용합니다.
2) youtube 다운로더
- 설치 방법 :
> windows : 유튜브 영상 다운로드 (for windows)
> macos
$ brew install youtube-dl
- 정상 동작 확인
$ youtube-dl -o "%(title)s.%(ext)s" nHSYKBpQFwk
- 설치 이유 : 유투브에 올라온 JTBC 뉴스를 요약하기 위해서 유투브영상을 다운 받을 수 있도록 준비합니다.
3) pydub 라이브러리 설치
$ pip install pydub
$ pip install gensim
4) ETRI OpenAPI 신청 : ai-creator.tistory.com/58
참고) youtube 설치 / ffmpeg 설치에 어려움을 느끼는 분들이라면, 아래 파일을 사용하여 step3 부터 수행합니다.
<< 구현 순서 >>
step 1 | JTBC 뉴스 다운로드 |
step 2 |
전처리 - 오디오 추출 - mp3 -> wav로 포맷 변경 - 오디오 파일 자르기 (30초씩) |
step 3 | ETRI Speech-To-Text API 호출 |
step 4 | Text 요약 |
# 필요한 라이브러리 import
import subprocess
import os
from gensim.summarization.summarizer import summarize
Step 1) JTBC 뉴스 다운로드
url에서 = 이후의 부분을 추출하여 요청합니다.
예) https://www.youtube.com/watch?v=nHSYKBpQFwk
youtube_url = "https://www.youtube.com/watch?v=nHSYKBpQFwk"
subprocess.call(["youtube-dl","-o", "%(title)s.%(ext)s", youtube_url.split("=")[-1]])
Step 2) 전처리
다운로드 받은 파일이 여러개라면, 임의로 1개의 파일 선택하여 진행해보겠습니다.
향후, 반복적인 업무를 피하기 위해서 함수를 만드는 등의 리팩토리 작업을 해보면 파이썬을 다루는 능력이 더 향상될 것입니다!!
ETRI OpenAPI 를 호출하기 위해 제약사항에 명시된 포맷으로 변경합니다.
2-1) 오디오 추출
# mp4 파일 중 첫번째 파일만 임의로 선택
filelist = [file for file in os.listdir(".") if file.endswith(".mp4")]
file = filelist[0]
# audio추출
## -y : 이미존재하는 파일의 경우, overwriting할 수 있도록 설정
subprocess.call(["ffmpeg","-y", "-i", file, "output.mp3"])
2-2) mp3 -> wav 파일로 변경하기
# mp3 -> wav로 변경
## -y : 이미존재하는 파일의 경우, overwriting할 수 있도록 설정
## -ar : sampling rate (etri의 경우 16khz지원)
## -ac : 1 (mono)
subprocess.call(["ffmpeg","-y" ,"-i", "output.mp3","-ac", "1", "-ar", "16000", "output.wav"])
2-3) 오디오 파일 자르기 (30초씩)
subprocess.call(["ffmpeg", "-i", \
"output.wav", \
"-f", "segment", "-segment_time", "30", \
"-c", "copy", "output%09d.wav"])
Step 3) STT API 호출
음성인식(STT) 빨리 시작하기 를 참고하여, 함수로 만들었습니다.
#-*- coding:utf-8 -*-
import urllib3
import json
import base64
import json
openApiURL = "http://aiopen.etri.re.kr:8000/WiseASR/Recognition"
accessKey = "이곳에 인증키를 넣어주세요"
def etri_stt(audioFilePath):
languageCode = "korean"
file = open(audioFilePath, "rb")
audioContents = base64.b64encode(file.read()).decode("utf8")
file.close()
requestJson = {
"access_key": accessKey,
"argument": {
"language_code": languageCode,
"audio": audioContents
}
}
http = urllib3.PoolManager()
response = http.request(
"POST",
openApiURL,
headers={"Content-Type": "application/json; charset=UTF-8"},
body=json.dumps(requestJson)
)
print("[responseCode] " + str(response.status))
print("[responBody]")
print("===== 결과 확인 ====")
data = json.loads(response.data.decode("utf-8", errors='ignore'))
print(data['return_object']['recognized'])
return data['return_object']['recognized']
파일이 여러개로 분리되었으므로, 파일 개수에 맞춰 etri_stt()를 호출하고, 결과를 차곡 차곡 모아둡니다.
filelist = [file for file in os.listdir(".") if file.startswith("output00")]
text_stacked = ""
for file in filelist:
print(file)
text = etri_stt(file)
text_stacked += text
print(text_stacked)
[결과 확인]
어색하게 나온 결과도 있지만, 상당부분 깨끗하게 결과가 나왔네요^^
Step 4) Text 요약
4-1) Text 전처리
여기서 문제가 생겼습니다. Text요약을 할 경우, 문장의 기준이 중요한데요, STT의 결과를 보면 문장 분리가 되어 있지 않습니다. 즉, 구두점이 없어서 기계 입장에서는 문장임을 인식할 수 없는 것이죠.
어떻게 해야 할까요?
다행히 뉴스의 경우 문장의 끝맺음에 공통점이 있습니다.
~습니다. ~입니다. 처럼 말입니다. 그래서 "니다"로 표현되어 있는 부분을 "니다." 으로 표현해보시죠.
## 구두점 삽입
punctuation_text = text_stacked.replace("니다", "니다.") #습니다. 입니다.
punctuation_text
4-2) 요약
print(summarize(punctuation_text, word_count=50))
[결과 확인]
<< 참고 >>
- 이를 이용해서 회의록 요약 프로젝트를 진행할 수 있습니다. 사용하는 데이터만 youtube 영상 -> 회의녹취 파일로 변경되었을 뿐 처리하는 부분들을 똑같겠죠? 다만, ETRI API 경우 구두점을 제공하지 않고, 일반적인 대화의 경우는 뉴스와는 달리 마지막 문장 표현이 명확하지 않습니다. ~했자나요. ~그랬습니다. ~결론내시죠. 등 말이죠.
이를 극복하고 싶다면 구글의 STT OpenAPI의 사용을 추천합니다. 베타로 제공되는 기능이기는 하나, "구두점 삽입" 결과가 매우 우수하다고 느끼실겁니다.
- 이를 활용해서 음성 검색 엔진을 만들면 어떨까? 하는 생각이 들었습니다. 이미지검색도 있는 이 세상에 왜 음성검색은 없는 것일까요? 특히 동영상의 경우 내가 원하는 곳을 찾는게 너무 어렵자나요. 음성 검색이 가능하여 원하는 곳으로 빠르게 이동할 수 있었으면 좋겠습니다. 그런데, STT만 된다면 음성 검색 엔진은 쉽게 만들 수 있습니다. 검색 엔진 자체가 text 기반이므로, 음성을 text로만 만들어 놓으면 너무 쉽게 만들 수 있게 됩니다.
저작물의 저작권은 작성자에게 있습니다.
공유는 자유롭게 하시되 댓글 남겨주세요~
상업적 용도로는 무단 사용을 금지합니다.
끝까지 읽어주셔서 감사합니다^^
'오늘 배워 오늘 쓰는 OpenAPI > 프로젝트' 카테고리의 다른 글
웹크롤링 - HTML 이해 (2/3) (1) | 2020.05.09 |
---|---|
웹크롤링 - 웹크롤링 이란? (1/3) (0) | 2020.05.09 |
OpenAPI 활용 - 날씨 정보를 사용한 맛집 추천 프로젝트 (41) | 2020.02.22 |
OpenAPI 활용 - 일정 도우미 프로젝트 (10) | 2020.02.22 |
구글 OpenAPI 활용 - 캘린더 (2. 개념 : 함수/데이터 편) (5) | 2020.02.22 |