-
-
Save tin2tin/8b61cea677eb8b7840e740d9a8b32176 to your computer and use it in GitHub Desktop.
| import bpy | |
| ''' | |
| Project Purpose: | |
| Extract markers and time codes from Final Cut Pro X's FCPXML 1.3 formatted files | |
| Pass an XML element into Marker.scanForMarker(). If markers are found, they are inserted as markers and subtitles in Blender. | |
| ''' | |
| import bpy, sys, datetime | |
| from xml.etree.ElementTree import parse | |
| # Converts the '64bit/32bits' timecode format into seconds | |
| def parseFCPTimeSeconds (timeString): | |
| vals = [float(n) for n in timeString.replace('s','').split('/')] | |
| if 1 == len(vals): | |
| val = vals[0] | |
| else: | |
| val = vals[0]/vals[1] | |
| return val | |
| class Marker: | |
| def __init__(self, name, startTime): | |
| self._name = name | |
| self._startTime = startTime | |
| @property | |
| def startTime(self): | |
| return self._startTime | |
| @property | |
| def name(self): | |
| return self._name | |
| @staticmethod | |
| def scanForMarker(element, time=[]): | |
| start = offset = 0 | |
| try: | |
| start = parseFCPTimeSeconds(element.attrib['start']) | |
| except: | |
| pass | |
| try: | |
| offset = parseFCPTimeSeconds(element.attrib['offset']) | |
| except: | |
| pass | |
| m = [] | |
| if 'marker' == element.tag: | |
| m.append(Marker(element.attrib['value'], start + sum(time))) | |
| else: | |
| time.append(offset - start) | |
| for el in element: | |
| m.extend(Marker.scanForMarker(el, list(time))) | |
| return m | |
| def get_open_channel(scene): | |
| """Get a channel with nothing in it""" | |
| channels = [] | |
| try: | |
| for strip in scene.sequence_editor.sequences_all: | |
| channels.append(strip.channel) | |
| if len(channels) > 0: | |
| return max(channels) + 1 | |
| else: | |
| return 1 | |
| except AttributeError: | |
| return 1 | |
| # EXAMPLE: | |
| # Import file and convert it to a list of markers sorted by ID and start time | |
| xmlroot = parse("C:\\Users\\User\\Documents\\Blender Scripts\\FCPXML\\fcpx_project.fcpxml").getroot() | |
| markers = sorted(Marker.scanForMarker(xmlroot), key=lambda s: s.startTime) | |
| #scene = context.scene | |
| #markers_sc = scene.timeline_markers | |
| scene = bpy.context.scene | |
| #open_channel = get_open_channel(scene) | |
| if not scene.sequence_editor: | |
| scene.sequence_editor_create() | |
| print ("RESULTING ORDERED LIST:") | |
| for m in markers: | |
| print ("Marker {0} with start time: {1}".format(m.name, datetime.timedelta(seconds=m.startTime))) | |
| bpy.context.scene.timeline_markers.new(m.name, frame=int(m.startTime)*24)# Insert marker | |
| print(str(int(m.startTime))) | |
| #Insert subtitle | |
| text_strip = scene.sequence_editor.sequences.new_effect( | |
| name=m.name, | |
| type='TEXT', | |
| channel=get_open_channel(scene), | |
| frame_start=int(m.startTime)*24, | |
| frame_end=int(m.startTime)*24+300 | |
| ) | |
| text_strip.font_size = 75 | |
| text_strip.text = m.name | |
| text_strip.use_shadow = True | |
| text_strip.select = True | |
| text_strip.blend_type = 'ALPHA_OVER' | |
| #added_strips.append(text_strip) |
2.79. I don't have a fcpx file anymore to test if is is still working.
Tested with some fcpx files from the OTIO, and with a minor fix it is working now.
Remember to specify the path with double \
I test on gnu/linux with projects of storyboarder. It does not generate error, but neither see the drawings :(
This add-on is not for importing Storyboarder stuff, but import markers from Final Cut Pro, like this one: https://gist.github.com/tin2tin/c3f87754301be38c06356f6cb4676fa8
I once did a Storyboarder to Blender importer, but it doesn't seem to be uploaded anywhere and it isn't on my current computer... Was it this post you saw? https://www.facebook.com/groups/1981104845289453/permalink/2082312818501988/
I don't use facebook.
Storyboarder exports to Final Cut and I use blender. So thought it would be good to mix them (blender and storyboarder).
Maybe I should do everything in blender.


Hi.
In which version of blender did you try it?