<목차>
• 서론
가끔씩 애니메이션이나 영화 파일을 소장하고 싶을 때 자막 파일을 구하기 어렵거나 구할 수 있어도 외국어 자막 파일만 존재하는 경험을 한 적이 있다.
직접 자막 파일을 하나하나 번역해서 만들거나 타임라인을 설정해서 만드는 과정을 본 적이 있는데 적지 않은 피로감을 주는 것 같았다.
그렇기 때문에 완벽하거나 대체 가능한 수준은 아니지만 자동으로 자막이 되는 코드를 한 번 만들어 보고 싶다는 생각이 들어서 작성해보았다.
• 네이버 파파고 API 소개
번역이라는 것은 정말 많이 축척된 데이터를 통해서 이뤄지는 과정이다. 기본적으로 번역 대상이 되는 언어 데이터와 언어 간의 번역이 포함된 데이터(병렬 코퍼스, Parallel Corpora)가 쌍을 이루며 존재해야 한다.
또 통계적인 기계 번역을 통해서 번역 모델을 만들어야 하며, 신경망을 이용한 기계 번역이 있다. 대표적으로 순환 신경망(RNN), 장단기 기억망(LSTM), 트랜스포머와 같은 모델 아키텍처가 그 예시이다.
직접 사용하려고 하는 파파고 Open API 같은 경우 대규모로 사전 훈련된 언어 모델을 사용하여 번역 성능을 향상시키는 방법으로 개인이 접근하기에 가장 손쉬운 방법 중 하나일 거라 생각한다.
물론 네이버 외에도 무료 번역 Open API는 여러 곳에서 지원하고 있다.
1. 구글 클라우드 번역 API 기본적으로 무료로 제공하고 있으며, 월별로 일정한 양의 무료 번역을 사용할 수 있고 할당량을 초과하면 유료로 전환해야 한다. 2. MS 번역 API 마이크로 사에서도 번역 서비스를 지원한다. 구글과 마찬가지로 무료로 제공되며 초과 시에는 요금이 부과되는 방식이다. 텍스트와 음성 번역을 지원한다. 3. Yandex API 다소 생소할 수 있다. 얀덱스는 러시아에서 주로 사용하는 즉, 우리나라의 네이버 같은 존재다. 기본적으로는 무료로 제공되나 사용한 문장의 양에 따라 요금을 부과한다. 4. IBM 언어 번역 API IBM Watson의 언어 번역 서비스로 무료 플랜이 제공된다. 다양한 언어 번역을 지원하며 텍스트 및 HTML 문서 번역이 가능하다고 한다. 하지만 2023년 6월 10일부로 신규 가입자 대상으로 서비스를 제공을 중단하고, 기존 가입자만 접근할 수 있다. 2024년 6월 10일부로 서비스 중단 절차가 진행되어 2024년 12월 10일 완전 중단된다고 한다. |
이렇게 여러가지 무료 API들이 존재하지만 접근성이 좋은 네이버 서비스를 이용하기로 결정했다.(카카오도 있다.)
https://developers.naver.com/products/papago/nmt/nmt.md
Neural Machine Translation - INTRO
Neural Machine Translation NAVER Developers - Papago 소개 NMT는 Neural Machine Translation(인공신경망 기반 기계번역)의 약어입니다. 파파고의 NMT 기술은 입력 문장을 문장벡터로 변환하는 신경망(encoder)과 문장벡
developers.naver.com
우선 위 사이트에 들어가서 로그인 후 'Open API 이용 신청'을 통해 신청하면 된다.
애플리케이션 이름은 대충 지어도 되고, 사용 API는 '파파고'를 선택
비로그인 서비스 환경은 'WEB' 선택 후 주소는 'http://localhost'로 입력해주면 된다.
• 자막 파일 직접 번역해보기
파이썬을 이용해서 파파고 API를 직접 사용해보자.
자막 파일은 팟플레이어를 이용해서 외국어 자막 파일을 받아왔다. 자막은 건담 -수성의 마녀- 6화를 사용했다.(첨부파일)
만약 프로그램 실행 시 바탕화면에 번역본 파일이 생성 후 잘 작동하다 오류가 발생할 수 있다.
오류의 내용이 "<urlopen error [WinError 10060] 연결된 구성원으로부터 응답이 없어 연결하지 못했거나, 호스트로부터 응답이 없어 연결이 끊어졌습니다>"라면 일일 사용 할당량을 소진해서 그런 것이다.
그렇기 때문에 해당 코드를 이용해서 자막 파일들을 자동으로 번역하는 것은 크게 기대하기는 어렵다.
(번역 퀄리티도 솔직히 기대에 미치지는 않았다. 개인적으로는 애니나 영화는 카카오 번역이 더 좋은 것 같았다.)
혹시나 자막 파일이 아래와 같은 양식일 경우 코드 내용 중에 있는 중괄호를 인식하는 코드를 변형해서 꺽새로 수정하고, 문장 시작 줄의 숫자를 수정해서 실행하면 될 것이다.
1
00:00:44,790 --> 00:00:59,790
<font color="#ffff80"><b>Fixed & Synced by bozxphd. Enjoy The Flick</b>.</font>
2
00:01:00,920 --> 00:01:06,370
<i>Fear.
Treachery. Bloodlust.</i>
3
00:01:06,600 --> 00:01:08,409
<i>Thousands of years ago...</i>
4
00:01:08,520 --> 00:01:11,808
<i>these were the forces
that ruled our world.</i>
<자막 번역 파이썬 코드>
import os
import urllib.request
import json
import time
# 메모 : 파파고 api를 이용해서 작성할 것, 바탕화면에 있는 메모장 내용을 토대로 중괄호 문제 해결할 것
# 네이버 api : https://developers.naver.com/apps/#/myapps/
try:
# 위치
location = "C:/Users/Jo/OneDrive/Desktop/"
# file 이름
names = "[SubsPlease] Mobile Suit Gundam - The Witch from Mercury - 06.ass"
# 파일 생성
with open(os.path.join(location, "번역본 " + names), mode="w", encoding="UTF-8") as cr_file:
cr_file.write("")
# 번역 기능(구글 번역 -> 파파고 번역으로 변경)
def translate_text(text, source_lang, target_lang):
# ------------------------------------------------------------------------
"""
api_url = "https://openapi.naver.com/v1/papago/n2mt"
headers = {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Naver-Client-Id": "", #발급받은 클라이언트 아이디 입력
"X-Naver-Client-Secret": "", #발급받은 클라이언트 시크릿 입력
}
data = {
"source" : source_lang,
"target" : target_lang,
"text" : text,
}
"""
# response = requests.post(api_url, headers = headers, data = data)
# ------------------------------------------------------------------------
client_id = "R1Mww6ge4KiNQEQV4I63" # 개발자센터에서 발급받은 Client ID 값
client_secret = "1FH8pXekin" # 개발자센터에서 발급받은 Client Secret 값
encText = urllib.parse.quote(text) # URL에서 특수 문자나 공백 같은 문자열을 사용하기 위한 인코딩
data = "source=" + source_lang + "&target=" + target_lang + "&text=" + encText
url = "https://openapi.naver.com/v1/papago/n2mt"
request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id", client_id)
request.add_header("X-Naver-Client-Secret", client_secret)
response = urllib.request.urlopen(request, data=data.encode("utf-8"))
rescode = response.getcode()
# json 처리 문장 넣기
if(rescode == 200):
response_body = response.read().decode('utf-8')
output_dict = json.loads(response_body)
output_text = output_dict["message"]["result"]["translatedText"]
# print(output_text)
return output_text
else:
print("Error Code : " + rescode)
# 중괄호 내의 내용 추출
def extract_brackets(text):
brackets_contents = [] # 중괄호 내용을 저장할 곳
in_brackets = False # 중괄호 존재 여부
current_content = ""
for char in text:
if char == '{':
in_brackets = True
if current_content: # 내용이 존재하면
brackets_contents.append(current_content)
print(current_content)
current_content = ""
elif char == '}':
in_brackets = False
elif in_brackets: # True라면
current_content += char # 문자열을 하나씩 더해간다.
return brackets_contents
# 파일 읽기
with open(os.path.join(location, names), mode="r", encoding="UTF-8") as file:
original = [] # 자막 파일의 원본 파일 정보를 담을 리스트(1~19줄의 내용을 저장)
count_1 = 0 # 전체 줄 개수를 카운트할 변수
count_2 = 0 # 구분점과 번역 내용을 다룰 줄 개수 카운터
after_subtitle_1 = []; after_subtitle_2 = []; after_subtitle_3 = []
for line in file:
line = line.strip() # 개행 문자 제거
# print(line)
if count_1 <=17: # !!시작 위치는 자막 파일마다 다를 수 있음 확인해야함!!
original.append(line)
with open(os.path.join(location, "번역본 " + names), mode="a", encoding="UTF-8") as new_file:
new_file.write(original[count_1] + "\n")
# print(original[count_1], "줄 개수 : " + str(count_1))
count_1 += 1
if ",," in line: # ",,"이 존재한다면 -> split으로 구분 지어줘서 나중에 합칠 땐 ',' 추가해야함
after_subtitle_1.append(line.split(",,", 2)[0]) # 자막 시간 정보
after_subtitle_2.append(line.split(",,", 2)[1]) # 자막 색상 정보
after_subtitle_3.append(line.split(",,", 2)[2]) # 번역할 문자열
# print(after_subtitle_3[count_2])
input_text = after_subtitle_3[count_2] # 번역할 문자열
cleaned_text = input_text
bracket_contents = extract_brackets(input_text)
# print(bracket_contents)
# count_2 += 1
time.sleep(1)
# 번역
lang = {"한국어":"ko", "영어":"en", "일본어":"ja", "중국어_간체":"zh-CN", "중국어_번체":"zh-TW",
"베트남어":"vi", "인도네시아어":"id", "독일어":"de", "러시아어":"ru", "스페인어":"es", "이탈리아어":"it",
"프랑스어":"fr"}
source_lang = lang.get("영어") # 원본 언어
target_lang = lang.get("한국어") # 번역하고자 하는 언어
translated_text = translate_text(cleaned_text, source_lang, target_lang)
print("번역할 내용 : " + str(cleaned_text))
print("번역된 내용 : " + str(translated_text) + "\n")
# 번역된 텍스트와 중괄호 내용 다시 합치기
output_text = translated_text
# print(output_text)
for content in bracket_contents:
output_text = output_text.replace('{}', '{' + content + '}')
# 파일 내용 추가
with open(os.path.join(location, "번역본 " + names), mode="a", encoding="UTF-8") as new_file:
new_file.write(after_subtitle_1[count_2] + ",," + after_subtitle_2[count_2] + ",," + str(output_text) + "\n")
count_2 += 1
print("작업 완료")
except Exception as e:
print("에러 발생 : " + str(e))
'잡동사니' 카테고리의 다른 글
[팀 프로젝트] 미국 대출 위험도 확인 사이트 (0) | 2024.08.26 |
---|---|
[팀 프로젝트] 차량 정보 조회 사이트 (0) | 2024.08.26 |