在网上可以找到JamesRuan 编写的Blender 字幕快速导入插件,但是文中指出,只适用到版本2.72,而最新的blender版本是2.77a。新版本的blender在字幕制作上做了很大的修改,原来的插件无法使用。
原插件的下载地址为:https://developer.blender.org/T28810
由于剪辑工作的需要,又不愿意使用其他软件来快速制作字幕,所以只好自己编程改造了。
改造的地方主要是去掉以前版本的无效的功能,支持新版的字幕导入,加入了对中文字幕文件的支持。
由于可能是机器或屏幕原因,我把字体大小的初始值设为100,使用者可以根据情况适当调整。
搜索以下代码更改:
scene.sequence_editor.sequences_all[0].font_size=100
至于插件使用方式,请参看原版。
改良后的代码如下:(插件信息,改动了支持版本号,和加了我的名字,并不贪原作者的功劳)
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# This directory is a Python package.
bl_info = {
"name": "Simple Subtitle Editor 2",
"author": "James Ruan , Klander Wu",
"version": (0, 2, 2),
"blender": (2, 77, 0),
"api": 40779,
"location": "VSE > Properties > Simple Subtitle Editor 2",
"description": "Simple subtitle editor 2",
"warning": "Format guess is based on filename extension.",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Sequencer/SimpleSubtitleEditor",
"tracker_url": "https://developer.blender.org/T28810",
"category": "Sequencer"}
import bpy
import codecs
def timecode2frameno(timecode, fps, format="srt"):
if format == "srt":
s = timecode.split(',')
ms = int(s[1])
h,m,s = map(int, s[0].split(':'))
frame = int(ms/1000*fps+0.5)
m += h*60
s += m*60
frame += s*fps
elif format == "sub":
s = timecode.split('.')
hs = int(s[1])
h, m, s = map(int, s[0].split(':'))
frame = int(hs/100*fps+0.5)
m += h*60
s += m*60
frame += s*fps
return frame
def frameno2timecode(frameno, fps, format="srt"):
if format == "srt":
s, ms = divmod(frameno, fps)
ms = int(ms/fps *1000)
m, s = divmod(s, 60)
h, m = divmod(m, 60)
return "%02d:%02d:%02d,%03d"%(h,m,s,ms)
elif format == "sub":
s, hs = divmod(frameno, fps)
hs = int(hs/fps * 100)
m, s = divmod(s, 60)
h, m = divmod(m, 60)
return "%02d:%02d:%02d.%02d"%(h,m,s,hs)
class MarkerImportOperator(bpy.types.Operator):
bl_idname = "marker.sse_import"
bl_label = "Import markers from file"
def execute(self,context):
scene = context.scene
scene.sse_msg = ""
#for i in range(0, len(scene.sse_sublist)):
#scene.sse_sublist.remove(0)
#for i in scene.timeline_markers:
#scene.timeline_markers.remove(i)
m = []
if not scene.sse_infile:
scene.sse_msg = "You must select a file to open."
return
ext = scene.sse_infile.rsplit('.')[-1]
if ext == "srt" or ext == "SRT":
format = "srt"
elif ext == "sub" or ext =="SUB":
format = "sub"
else:
scene.sse_msg = "Can not open file of format: %s"%(ext)
return
if format == "srt":
try:
f = codecs.open(scene.sse_infile,'r','utf-8')
all = "".join(f.readlines()).replace('\n\n',"\n#SEP#").split('#SEP#')
all = [x.strip('\n').splitlines() for x in all]
all = [x for x in all if x != []]
for i in all:
n = {}
n['i'] = int(i[0])
t = i[1].split('-->')
n['s'] = t[0].strip()
n['e'] = t[1].strip()
n['t'] = '\\n'.join(i[2:])
m.append(n)
f.close()
except IOError:
print('IOError')
return {'FINISHED'}
elif format == "sub":
try:
f = codecs.open(scene.sse_infile,'r','utf-8')
#skip all INFORMATION
all = "".join(f.readlines()).rsplit('[SUBTITLE]\n')[-1].replace('\n\n',"\n#SEP#").split('#SEP#')
all = [x.strip('\n').splitlines() for x in all]
all = [x for x in all if x != []]
print(all)
for k in range(1, len(all)+1):
n = {}
n['i'] = k
t = all[k-1][0].split(',')
n['s'] = t[0].strip()
n['e'] = t[1].strip()
n['t'] = '[br]'.join(all[k-1][1:])
m.append(n)
f.close()
except IOError:
print('IOError')
return {'FINISHED'}
index=0
fps = scene.render.fps
for n in m:
s = timecode2frameno(n['s'], fps, format)
e = timecode2frameno(n['e'], fps, format)
bpy.ops.sequencer.effect_strip_add(frame_start=s,frame_end=e,channel=1,type='TEXT')
bpy.ops.sequencer.select()
scene.sequence_editor.sequences_all[0].font_size=100
scene.sequence_editor.sequences_all[0].text=n['t']
return {'FINISHED'}
class SSEPanel(bpy.types.Panel):
bl_label = "Simple Subtitle Editor 2"
bl_idname = "OBJECT_PT_SSE"
bl_space_type = "SEQUENCE_EDITOR"
bl_region_type = "UI"
def draw(self, context):
scene = context.scene
layout = self.layout
col = layout.column()
row = col.row()
row.label("Input:")
row.prop(scene, "sse_infile", text="")
row.operator("marker.sse_import",text="", icon='FILE_TICK')
col.separator()
row=col.row()
col.separator()
row = col.row()
row.prop(scene, "sse_msg", text="")
def register():
bpy.utils.register_class(MarkerImportOperator)
bpy.utils.register_class(SSEPanel)
setattr(bpy.types.Scene, "sse_infile", bpy.props.StringProperty(name="sse_infile", subtype='FILE_PATH', description="filename to import from"))
setattr(bpy.types.Scene, "sse_msg", bpy.props.StringProperty(name="sse_msg", subtype='NONE', description="Messages"))
def unregister():
bpy.utils.unregister_class(MarkerImportOperator)
bpy.utils.unregister_class(SSEPanel)
delattr(bpy.types.Scene, "sse_infile")
delattr(bpy.types.Scene, "sse_msg")
if __name__ == '__main__':
register()