Skip to content

Instantly share code, notes, and snippets.

@aherok
Created March 25, 2015 21:02
Show Gist options
  • Save aherok/109d76999c1de36b1f53 to your computer and use it in GitHub Desktop.
Save aherok/109d76999c1de36b1f53 to your computer and use it in GitHub Desktop.
Very robust .fpcxml -> .srt file converter
import os
from sys import argv
from xml.etree.ElementTree import parse
from pysrt import SubRipFile, SubRipItem, SubRipTime
def _mili_to_frame(secs):
"""
Convert "miliseconds" to frame count, e.g. if start time is 2.5s,
then its 2 secs and 12 frames, so function will return 2.12. Magic :)
:param secs: seconds to convert
:return: seconds with frames
"""
int_secs = int(secs)
mili = secs - int_secs
frames = int(mili * 25) / 100
return int_secs + frames
def _parse_duration(duration):
"""
Parses start/end/offset times from XML
Converts format 1000/200s to float seconds
:param duration:
:return:
"""
if duration.endswith('s'):
duration = duration[:-1]
values = duration.split('/')
if len(values) > 1:
val01, val02 = values
val01 = int(val01)
val02 = int(val02)
val = None
if val01 > val02:
val = val01 / val02
else:
val = val02 / val01
return _mili_to_frame(val)
return float(values[0])
class Title(object):
def __init__(self, elem):
self.name = elem.get('name')
self.lane = elem.get('lane')
self.ref = elem.get('ref')
self.duration = _parse_duration(elem.get('duration'))
self.offset = _parse_duration(elem.get('offset'))
self.start = _parse_duration(elem.get('start'))
self.text = elem.find('.//text-style').text
def read_file(filename):
"""
Open FCPXML file and return all TITLE tags
:param filename:
:return:
"""
tree = parse(filename)
root = tree.getroot()
found_titles = root.findall('.//title')
titles = [Title(elem) for elem in found_titles]
return titles
def parse_file(filename):
"""
Take filename as argument, convert it and return srt version
:param filename:
:return:
"""
titles = read_file(filename)
f = SubRipFile()
for i, t in enumerate(titles):
start = SubRipTime(seconds=t.offset)
end = SubRipTime(seconds=t.offset + t.duration)
s = SubRipItem(index=i, start=start, end=end, text=t.text)
f.append(s)
name, ext = os.path.splitext(filename)
new_name = "%s.srt" % name
f.save(new_name)
if __name__ == '__main__':
parse_file(argv[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment