mirror of
https://github.com/blw1138/Zordon.git
synced 2025-12-17 16:58:12 +00:00
201 lines
6.3 KiB
Python
201 lines
6.3 KiB
Python
import xml.etree.ElementTree as ET
|
|
import argparse
|
|
import os
|
|
import glob
|
|
from urllib2 import unquote
|
|
import time
|
|
|
|
library = None
|
|
|
|
|
|
class FCPXLibrary:
|
|
|
|
def __init__(self, xml_path):
|
|
parser = ET.parse(xml_path)
|
|
self.root = parser.getroot()
|
|
self.xml_version = self.root.attrib.get('version')
|
|
self.location = self.library_location()
|
|
|
|
# self.projects = self.root.findall('./library/event/project')
|
|
self.formats = self.root.findall('./resources/format')
|
|
|
|
self.clips = [Clip(x, self) for x in self.root.findall(".//asset-clip")]
|
|
self.projects = [Project(x, self) for x in self.root.findall('./library/event/project')]
|
|
|
|
def formats(self):
|
|
return self.root.findall('./resources/format')
|
|
|
|
def element_with_tag_value(self, element, tag, value):
|
|
return self.root.findall(".//{e}[@{t}='{v}']".format(e=element, t=tag, v=value))
|
|
|
|
def clips_with_videorole(self, role):
|
|
return [clip for clip in self.clips if getattr(clip, 'videoRole', None) == role]
|
|
|
|
def format_with_id(self, id):
|
|
# return self.root.findall("./resources/format[id='{}']".format(id))
|
|
return self.element_with_tag_value('format', 'id', id)
|
|
|
|
def library_location(self):
|
|
# urllib2.unquote(asset_ref.get('src'))[7:]
|
|
path = self.root.findall('./library')[0].attrib['location']
|
|
return unquote(path)[7:]
|
|
|
|
|
|
class Project:
|
|
def __init__(self, project_element, library):
|
|
for attrib in project_element.attrib:
|
|
setattr(self, attrib, project_element.get(attrib))
|
|
print(project_element.attrib)
|
|
print(project_element.parent)
|
|
|
|
ref_clips = project_element.findall(".//ref-clip")
|
|
|
|
print('start')
|
|
for clip in library.clips:
|
|
print(clip.name)
|
|
if clip.name == ref_clips[0]:
|
|
print(clip)
|
|
break
|
|
print('end')
|
|
|
|
# for child in ref_clips:
|
|
# print(child.tag, child.attrib)
|
|
|
|
|
|
class Clip:
|
|
def __init__(self, clip_element, library):
|
|
|
|
# self.library = library
|
|
|
|
# Get attribs from XML
|
|
for attrib in clip_element.attrib:
|
|
setattr(self, attrib, clip_element.get(attrib))
|
|
self.type = 'audio' if hasattr(self, 'audioRole') else 'video'
|
|
|
|
|
|
# Get clip reference
|
|
asset_ref = next(iter(library.element_with_tag_value('asset', 'id', self.ref)))
|
|
|
|
for attrib in asset_ref.attrib:
|
|
if not hasattr(self, attrib):
|
|
setattr(self, attrib, asset_ref.get(attrib))
|
|
|
|
self.source = unquote(asset_ref.get('src'))[7:]
|
|
|
|
if self.type == 'video':
|
|
|
|
format_id = getattr(self, 'format', asset_ref.get('format', None))
|
|
video_format = next(iter(library.format_with_id(format_id)))
|
|
|
|
if not hasattr(self, 'format'):
|
|
print('no format!')
|
|
|
|
try:
|
|
frame_duration = fcp_time_to_float(video_format.get('frameDuration'))
|
|
self.in_frame = int(round(fcp_time_to_float(self.start) / frame_duration))
|
|
duration = int(round(fcp_time_to_float(self.duration) / frame_duration))
|
|
self.out_frame = self.in_frame + duration
|
|
except Exception as e:
|
|
print('in/out fail: ' + str(e))
|
|
print(dir(self))
|
|
pass
|
|
|
|
def optimized_source(self):
|
|
path = None
|
|
mov = os.path.splitext(os.path.basename(self.source))[0] + '.mov'
|
|
found = glob.glob(os.path.join(library.location, '*', 'Transcoded Media', 'High Quality Media', mov))
|
|
if found:
|
|
path = found[0]
|
|
print(path)
|
|
return path
|
|
|
|
def proxy_source(self):
|
|
path = None
|
|
mov = os.path.splitext(os.path.basename(self.source))[0] + '.mov'
|
|
found = glob.glob(os.path.join(library.location, '*', 'Transcoded Media', 'Proxy Media', mov))
|
|
if found:
|
|
path = found[0]
|
|
print(path)
|
|
return path
|
|
|
|
def __repr__(self):
|
|
if self.type == 'video':
|
|
return "<Clip name:'%s' type: %s role: '%s' duration:%s frames>" % (getattr(self, 'name', None), self.type,
|
|
getattr(self, 'videoRole', None), self.out_frame - self.in_frame)
|
|
else:
|
|
return "<Clip name:'%s' type: %s role: '%s'>" % (getattr(self, 'name', None), self.type, getattr(self, 'audioRole', None))
|
|
|
|
|
|
def fcp_time_to_float(timestr):
|
|
try:
|
|
rates = timestr.strip('s').split('/')
|
|
return float(rates[0]) / float(rates[-1])
|
|
except (ZeroDivisionError, AttributeError) as e:
|
|
return 0.0
|
|
|
|
import sys
|
|
from types import ModuleType, FunctionType
|
|
from gc import get_referents
|
|
|
|
# Custom objects know their class.
|
|
# Function objects seem to know way too much, including modules.
|
|
# Exclude modules as well.
|
|
BLACKLIST = type, ModuleType, FunctionType
|
|
|
|
|
|
def getsize(obj):
|
|
"""sum size of object & members."""
|
|
if isinstance(obj, BLACKLIST):
|
|
raise TypeError('getsize() does not take argument of type: '+ str(type(obj)))
|
|
seen_ids = set()
|
|
size = 0
|
|
objects = [obj]
|
|
while objects:
|
|
need_referents = []
|
|
for obj in objects:
|
|
if not isinstance(obj, BLACKLIST) and id(obj) not in seen_ids:
|
|
seen_ids.add(id(obj))
|
|
size += sys.getsizeof(obj)
|
|
need_referents.append(obj)
|
|
objects = get_referents(*need_referents)
|
|
return size
|
|
|
|
|
|
# if __name__ == "__main__":
|
|
#
|
|
# parser = argparse.ArgumentParser()
|
|
# parser.add_argument('-i', '--input', help='Input FCPX Library XML', required=True)
|
|
# parser.add_argument('-s', '--save-file', help='Description', required=False)
|
|
#
|
|
# args = parser.parse_args()
|
|
#
|
|
# library = FCPXLibrary(args.input)
|
|
#
|
|
# print getsize(library)
|
|
# while True:
|
|
# time.sleep(4)
|
|
#
|
|
# print library.library_location()
|
|
#
|
|
# print dir(library.clips[0])
|
|
# print library.clips[0]
|
|
# print library.clips[0].proxy_source()
|
|
#
|
|
# print(args.input)
|
|
# print(args.save_file)
|
|
|
|
if __name__ == '__main__':
|
|
library = FCPXLibrary('new.fcpxml')
|
|
# print library.clips[0].source
|
|
# print library.library_location()
|
|
#
|
|
# print dir(library.clips[0])
|
|
# print library.clips[0]
|
|
# print library.clips[0].proxy_source()
|
|
# for clip in library.clips:
|
|
# print clip
|
|
print(dir(library.projects[0]))
|
|
print(library.formats)
|
|
|
|
|