まとめ Whisperの文字起こし結果(SRTファイル)を読み込み、FuguMTで日本語に翻訳する。 タイムスタンプを維持したまま日本語字幕データ(.srt)を生成し、動画編集ソフトで利用可能にする。 ずんだもん風の方言変換ルールを適用し、テキスト読み上げ用データに加工する。
Whisperは、OpenAIが開発しGitHub上で公開されている自動音声認識(ASR)モデルです。このページでは、Whisperによる音声認識結果を日本語に翻訳し、日本語の字幕データ(.srtフォーマット)を作成します。さらにそれをずんだもんにしゃべらせてみます。
whisperから作成した字幕ファイルを読み込む
# whisperはデフォルトで .srtファイルを書き出します。このファイルの英語の部分を日本語に翻訳します。
翻訳の正しさは保証されておらず、また本コードも動作や出力に関しては一切の責任を負えません。
1
2
3
4
5
6
7
8
import warnings
from transformers import pipeline
MAX_LENGTH = 400 # モデルに入力することができる文字数の上限
translator = pipeline ( "translation" , model = "staka/fugumt-en-ja" )
file = open ( "FlexLNG_Q3_2022_Key_Takeaways.mp3.srt" , "r" )
lines = [ l . replace ( " \n " , "" ) for l in file . readlines ()]
lines [: 15 ]
['1',
'00:00:00,000 --> 00:00:13,240',
"Hi and welcome to FlexLNG's third quarter highlights.",
'',
'2',
'00:00:13,240 --> 00:00:18,120',
'Revenues for the quarter came in at 91 million in line with previous guidance of approximately',
'',
'3',
'00:00:18,120 --> 00:00:19,520',
'90 million.',
'',
'4',
'00:00:19,520 --> 00:00:26,020',
'Earnings were strong, net income and adjusted net income was 47 and 42 million, translating']
前処理
# テキストに前処理を加えたいので、ファイルを保存する前にテキストを書き換えます。
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def zundamonize ( text : str ) -> str :
"""
語尾をそれらしくする
Args:
text (str): 日本語テキスト
Returns:
str: 前処理済みの日本語テキスト
"""
# TODO: 辞書を使って英語をカタカナに変換する
# https://github.com/KEINOS/google-ime-user-dictionary-ja-en など
text = text . replace ( "Flex" , "フレックス" )
if text . endswith ( "ありがとうございました" ):
return text . replace ( "ありがとうございました" , "ありがとうなのだ。" )
elif text . endswith ( "しました。" ):
return text . replace ( "しました。" , "したのだ。" )
elif text . endswith ( "れました。" ):
return text . replace ( "れました。" , "れたのだ。" )
elif text . endswith ( "れました。" ):
return text . replace ( "れました。" , "れたのだ。" )
elif text . endswith ( "れます。" ):
return text . replace ( "れます。" , "れるのだ。" )
elif text . endswith ( "できます。" ):
return text . replace ( "できます。" , "できるのだ。" )
elif text . endswith ( "あります。" ):
return text . replace ( "あります。" , "あるのだ。" )
elif text . endswith ( "ようこそ。" ):
return text . replace ( "ようこそ。" , "ようこそなのだ。" )
elif text . endswith ( "ています。" ):
return text . replace ( "ています。" , "ているのだ。" )
elif text . endswith ( "ている。" ):
return text . replace ( "ている。" , "ているのだ。" )
elif text . endswith ( "できる。" ):
return text . replace ( "できる。" , "できるのだ。" )
elif text . endswith ( "できま。" ):
return text . replace ( "できます。" , "できるのだ。" )
elif text . endswith ( "できた。" ):
return text . replace ( "できた。" , "できたのだ。" )
elif text . endswith ( "えました。" ):
return text . replace ( "えました。" , "えたのだ。" )
elif text . endswith ( "しました。" ):
return text . replace ( "しました。" , "したのだ。" )
elif text . endswith ( "ました。" ):
return text . replace ( "ました。" , "たのだ。" )
elif text . endswith ( "った。" ):
return text . replace ( "った。" , "ったのだ。" )
elif text . endswith ( "した。" ):
return text . replace ( "した。" , "したのだ。" )
elif text . endswith ( "する。" ):
return text . replace ( "する。" , "するのだ。" )
elif text . endswith ( "です。" ):
return text . replace ( "です。" , "なのだ。" )
return text
翻訳したテキストを出力する
# 字幕用のフォーマット(.srt)とテキストファイルの両方を出力します。
途中、タイムスタンプをいろいろ書き換えているのは字幕のタイミングを調整するためです。
作成された .srt ファイルをAdobe Premiere Proに読み込むと字幕を表示できます。
また、.txtファイルをVOICEVOXに読み込めば音声データを作成できます。
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
cnt = 0
result = []
text_only_result = []
temp_timestamp_start = "00:00:00,000"
temp_timestamp_end = "00:00:00,000"
temp_text = ""
centense_continue = False
for line in lines :
if len ( line ) == 0 :
# 空白行はスキップ
continue
elif line [ 0 ] . isdigit ():
# 会話以外の出力はスキップ
if "-->" in line :
if centense_continue :
temp_timestamp_end = line . split ( " --> " )[ 1 ]
else :
temp_timestamp_start , temp_timestamp_end = line . split ( " --> " )
continue
elif len ( line ) < 5 :
continue
# 会話が続いているかの判定
if line . endswith ( "." ):
centense_continue = False
else :
centense_continue = True
# 翻訳
temp_text += line
if not centense_continue :
cnt += 1
translation_text = translator ( temp_text )[ 0 ][ "translation_text" ]
translation_text = zundamonize ( translation_text )
temp_text = ""
print ( "" )
print ( cnt )
print ( f " { temp_timestamp_start } --> { temp_timestamp_end } " )
print ( translation_text )
if cnt > 1 :
result . append ( "" )
result . append ( cnt )
result . append ( f " { temp_timestamp_start } --> { temp_timestamp_end } " )
result . append ( translation_text )
text_only_result . append ( f " { translation_text } " )
else :
continue
with open ( "日本語字幕.srt" , "w" , encoding = "utf-8-sig" ) as f :
for line in result :
f . write ( f " { line } \n " )
with open ( "日本語テキスト.txt" , "w" , encoding = "utf-8-sig" ) as f :
for line in text_only_result :
f . write ( f " { line } \n " )
1
00:00:00,000 --> 00:00:13,240
フレックスLNGの第3四半期ハイライトへようこそなのだ。
2
00:00:13,240 --> 00:00:19,520
この四半期の売上は9100万ドルで、前回のガイダンスでは約9000万ドルだったのだ。
3
00:00:19,520 --> 00:00:33,480
利益は好調で、純利益と調整済み純利益は47と4200万ドルで、1株当たり利益と調整済み1株当たり利益はそれぞれ88セントと79セントだったのだ。
4
00:00:33,480 --> 00:00:41,520
四半期中の貨物市場は急成長し、これは短期と長期の両方にプラスの影響を与えたのだ。
5
00:00:41,520 --> 00:00:45,100
この四半期には3隻の船が新造船のチャーターを開始したのだ。
6
00:00:45,100 --> 00:00:57,720
6月には、フレックス Enterpriseとフレックス Amberの両方の7年間のチャーターを発表し、これらの船は、短期契約の代わりに、7月にこれらの新しい長期チャーターを開始したのだ。