Skip to content

Commit

Permalink
expose exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesruan committed Jan 4, 2018
1 parent a0e0e4f commit 1cb8421
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 85 deletions.
38 changes: 34 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,37 @@
SimpleSubtitleEditor
====================
# SimpleSubtitleEditor

SimpleSubtitleEditor for Blender
An Blender Addon for editing subtitles.

Usage:
## Features
- Adding/deleting lines of subtitle.
- Adjusting each lines with markers in the time line.
- Importing/exporting: SRT(SubRip) SUB(SubViewer).

##Usage

When activated, your should find an UI in Video Sequencer Editor > Properties > SimpleSubtitleEditor.

### From Scratch
Just press the 'new' button and there will be two markers added, marking the start and end frame of that subtitle line.

NOTE: Don't delete and insert markers manually. Use the buttons instead. There are background property storing info and manually adding or deleting markers will break its consistency.

### Import
Fill in the first line editor with the file path, then click the tick aside.

Then markers' position can be tweaked. Subtitles context can be changed or deleted.

Only file of format SRT or SUB is supported.

### Export
Fill in the last line editor with the file path, then click the tick aside.

Only file of format SRT or SUB is supported.

## Known Problems
- Stores only timecode info and titling info, no styling info or metadata.
- Only appending and deleting is supported (So that is why it's called "simple", for few people would use inserting).
- Encoding is based on your system's locale.

## Future Plan
Interface refraction? The current interface is slow for a large file.
138 changes: 57 additions & 81 deletions SimpleSubtitleEditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
bl_info = {
"name": "Simple Subtitle Editor",
"author": "James Ruan",
"version": (0, 2, 1),
"blender": (2, 72, 0),
"version": (0, 2, 2),
"blender": (2, 79, 0),
"api": 40779,
"location": "VSE > Properties > Simple Subtitle Editor",
"description": "Simple subtitle editor",
"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",
"tracker_url": "https://github.com/jamesruan/SimpleSubtitleEditor/issues",
"category": "Sequencer"}

import bpy
Expand Down Expand Up @@ -68,16 +68,15 @@ def frameno2timecode(frameno, fps, format="srt"):


class MarkerExportOperator(bpy.types.Operator):
"""Export markers to file"""
bl_idname = "marker.sse_export"
bl_label = "Export markers to file"

def execute(self, context):
scene = context.scene
m = []
scene.sse_msg = ""
if not scene.sse_outfile:
scene.sse_msg = "You must select or name a file to write to."
return
raise Exception("You must select or name a file to write to.")
ext = scene.sse_outfile.rsplit('.')[-1]
if ext == "srt" or ext == "SRT":
format = "srt"
Expand All @@ -86,35 +85,29 @@ def execute(self, context):
else:
scene.sse_outfile += ".srt"
format = "srt"
scene.sse_msg = "Output to file with format: %s"%(format)

if format == "srt":
try:
f = open(scene.sse_outfile, mode='wt')
fps = scene.render.fps
for n in scene.sse_sublist:
s = scene.timeline_markers["S%03d"%(n.index)].frame
e = scene.timeline_markers["E%03d"%(n.index)].frame
s = frameno2timecode(s, fps, "srt")
e = frameno2timecode(e, fps, "srt")
l = "%d\n%s --> %s\n%s\n"%(n.index, s, e, n.text.replace('\\n','\n'))
m.append(l)
f.writelines("\n".join(m))
except IOError:
return {'FINISHED'}

f = open(scene.sse_outfile, mode='wt')
fps = scene.render.fps
for n in scene.sse_sublist:
s = scene.timeline_markers["S%03d"%(n.index)].frame
e = scene.timeline_markers["E%03d"%(n.index)].frame
s = frameno2timecode(s, fps, "srt")
e = frameno2timecode(e, fps, "srt")
l = "%d\n%s --> %s\n%s\n"%(n.index, s, e, n.text.replace('\\n','\n'))
m.append(l)
f.writelines("\n".join(m))
elif format == "sub":
try:
f = open(scene.sse_outfile, mode='wt')
fps = scene.render.fps
for n in scene.sse_sublist:
s = scene.timeline_markers["S%03d"%(n.index)].frame
e = scene.timeline_markers["E%03d"%(n.index)].frame
s = frameno2timecode(s, fps, "sub")
e = frameno2timecode(e, fps, "sub")
l = "%s,%s\n%s\n"%(s, e, n.text.replace('\\n','[br]'))
m.append(l)
header="""[INFORMATION]
f = open(scene.sse_outfile, mode='wt')
fps = scene.render.fps
for n in scene.sse_sublist:
s = scene.timeline_markers["S%03d"%(n.index)].frame
e = scene.timeline_markers["E%03d"%(n.index)].frame
s = frameno2timecode(s, fps, "sub")
e = frameno2timecode(e, fps, "sub")
l = "%s,%s\n%s\n"%(s, e, n.text.replace('\\n','[br]'))
m.append(l)
header="""[INFORMATION]
[TITLE]
[AUTHOR]
[SOURCE]
Expand All @@ -124,10 +117,8 @@ def execute(self, context):
[END INFORMATION]
[SUBTITLE]
"""
f.write(header)
f.writelines("\n".join(m))
except IOError:
return {'FINISHED'}
f.write(header)
f.writelines("\n".join(m))
# print(m)
return {'FINISHED'}

Expand All @@ -137,7 +128,6 @@ class MarkerImportOperator(bpy.types.Operator):

def execute(self,context):
scene = context.scene
scene.sse_msg = ""
for i in range(0, len(scene.sse_sublist)):
scene.sse_sublist.remove(0)

Expand All @@ -146,55 +136,47 @@ def execute(self,context):
m = []

if not scene.sse_infile:
scene.sse_msg = "You must select a file to open."
raise Exception("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)
raise Exception("Can not open file of format: %s"%(ext))
return

if format == "srt":
try:
f = open(scene.sse_infile)
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'}
f = open(scene.sse_infile)
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()
elif format == "sub":
try:
f = open(scene.sse_infile)
#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'}
f = open(scene.sse_infile)
#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()
#print(m)
fps = scene.render.fps

Expand Down Expand Up @@ -304,14 +286,10 @@ def draw(self, context):
a = col.operator("marker.sse_add",text="new", icon='ZOOMIN')
a.name = "%03d"%(len(context.scene.sse_sublist)+1)
row = col.row()
row.prop(scene, "sse_msg", text="")
row = col.row()
row.label("Output:")
row.prop(scene, "sse_outfile", text="")
row.operator("marker.sse_export",text="", icon='FILE_TICK')



def register():
bpy.utils.register_class(MarkerImportOperator)
bpy.utils.register_class(MarkerExportOperator)
Expand All @@ -322,7 +300,6 @@ def register():
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_outfile", bpy.props.StringProperty(name="sse_outfile", subtype='FILE_PATH', description="filename to export into"))
setattr(bpy.types.Scene, "sse_msg", bpy.props.StringProperty(name="sse_msg", subtype='NONE', description="Messages"))
setattr(bpy.types.Scene, "sse_sublist", bpy.props.CollectionProperty(type=SSE_Sublist))

def unregister():
Expand All @@ -335,7 +312,6 @@ def unregister():
bpy.utils.unregister_class(SSEPanel)
delattr(bpy.types.Scene, "sse_infile")
delattr(bpy.types.Scene, "sse_outfile")
delattr(bpy.types.Scene, "sse_msg")
delattr(bpy.types.Scene, "sse_sublist")

if __name__ == '__main__':
Expand Down

0 comments on commit 1cb8421

Please sign in to comment.