Created
March 25, 2015 21:02
-
-
Save aherok/109d76999c1de36b1f53 to your computer and use it in GitHub Desktop.
Very robust .fpcxml -> .srt file converter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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