はじめに
AviUtlで作成した動画に入れたテキストから字幕を抜き出して、字幕(srt)ファイルを生成するPython3のスクリプトを作ってみました。手っ取り早くsrtのフォーマットに変換して、字幕の内容の修正(翻訳等)に集中したいといった用途には使えると思いますので、本ページで公開します。
注意点
ただ、フレームレートは30fps(29.97fps)で決め打ちになっていますので、他のフレームレートで使用する場合には適宜修正をお願いいたします。
一応、最低限の動作の確認は行いましたが、動作を確認したハードウェア及びソフトウェアの条件以外において以下のスクリプトを動作させたことにより得られる結果についてはハードウェアの機種やソフトウェアのバージョンが同一であった場合であっても保証できませんので、自己責任でのご利用をお願いいたします。
ソースコード
ソースコードは以下の通りです。GitHub Gistにコードを置きましたので、そこからEmbedする形に変更しました。
#!/usr/bin/env python3 | |
# coding: utf-8 | |
# | |
# See https://pandanote.info/?p=29 for details. | |
# | |
import io | |
import sys | |
import re | |
import codecs | |
from struct import * | |
class AviUtlElement: | |
"""AviUtlの中でテキストに関連する要素を格納するクラス""" | |
def __init__(self): | |
self.start = 0 | |
self.end = 0 | |
self.text = ""; | |
def setTextAsUtf8(self,s): | |
ss = len(s) | |
self.text = "" | |
for x in range(0,ss-1,4): | |
# print str(x)+","+s[x:x+4] | |
c = int(s[x:x+2],16)+int(s[x+2:x+4],16)*256 | |
if c == 0: break | |
self.text += chr(c) | |
self.text = re.sub(r"\r?\n","",self.text); | |
#print b | |
def formatForSrt(s): | |
sec = float(s%1800)/30 | |
hm = s/1800 | |
h = int(hm/60) | |
m = int(hm%60) | |
return re.sub(r"\.",",","{0:02d}:{1:02d}:{2:06.3f}".format(h,m,sec)); | |
# 標準入力,標準出力,標準エラー出力の文字コードを変更する. | |
sys.stdin = io.TextIOWrapper(sys.stdin.buffer,encoding='cp932') | |
lines = sys.stdin.readlines() | |
sid = 0 | |
element = {} | |
start_ = 0 | |
end_ = 0 | |
text = "" | |
for line in lines: | |
m = re.match(r" |
|
if m: | |
sid = int(m.group(1)) | |
else: | |
mm = re.search(u'_name=テキスト',line) | |
if mm: | |
#print("element[" +sid+"]") | |
element[sid] = AviUtlElement() | |
element[sid].start = start_ | |
element[sid].end = end_ | |
else: | |
m3 = re.match(r"text=(.+)",line) | |
if m3: | |
#print("text:" +sid) | |
element[sid].setTextAsUtf8(m3.group(1)) | |
else: | |
m4 = re.match(r"(start|end)=(\d+)",line) | |
if m4: | |
if m4.group(1) == "start": | |
start_ = m4.group(2) | |
elif m4.group(1) == "end": | |
end_ = m4.group(2) | |
pos = 1 | |
for k,v in sorted(element.items()): | |
print (pos,"\r") | |
print (formatForSrt(int(v.start)-1)," --> ",formatForSrt(int(v.end)),"\r\n",v.text,"\r") | |
#print (k,v.start,",",v.end) | |
print ("\r") | |
pos+=1 |
なお、Python2では動作しないと思いますので、Python3をお持ちでない場合には別途インストールの上、お使いください。
まとめ
とりあえず必要最低限の仕様で作成してしまいましたが、必要に応じて改良するかもしれません。
本記事は以上です。