Blender 字幕編輯器插件(SimpleSubtitleEditor)改良版

在網上可以找到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()


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章