Last active
August 20, 2017 19:57
-
-
Save Grezzo/6a730d449fb4a38147233b3469c29fe6 to your computer and use it in GitHub Desktop.
Changes paths in an fcpxml to point to transcoded media (proxy and high quality media) if it can be found.
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
#! /usr/bin/env python | |
import os | |
import urllib | |
import re | |
import logging | |
import argparse | |
import sys | |
from urlparse import urlparse, urljoin | |
import xml.etree.ElementTree as ET | |
#Given an event path, check for 'Proxy Media' or 'High Quality Media' files and return a dict of paths | |
def get_media_in_path(event_path, transcoded_type): | |
media_files = {} | |
transcoded_media_path = os.path.join(event_path, 'Transcoded Media', transcoded_type) | |
#Get a list of filenames (minus the extention) and paths and add them to the dictionary | |
for (dirpath, _, filenames) in os.walk(transcoded_media_path): | |
for filename in filenames: | |
#Get file name without extension | |
first_part = os.path.splitext(filename)[0] | |
#Get file path and turn it into a url | |
file_path = os.path.join(dirpath, filename) | |
file_url = urljoin('file://', urllib.quote(file_path)) | |
#add to dict | |
media_files[first_part] = file_url | |
logging.debug('Found {} file {}'.format(transcoded_type, file_url)) | |
return media_files | |
parser = argparse.ArgumentParser(description="Update fcpxml to point to 'Transcoded Media' files", | |
epilog="Latest version available at https://gist.github.com/Grezzo/6a730d449fb4a38147233b3469c29fe6") | |
parser.add_argument("input", metavar='SOURCE', help="an fcpxml file") | |
parser.add_argument("-o", "--output", help="name of fcpxml file to create") | |
parser.add_argument("-p", "--proxy", help="prioritise 'Proxy Media' (default is to priorities 'High Quality' Media)", action="store_true") | |
parser.add_argument("-v", "--verbose", help="print verbose logging information", action="store_true") | |
parser.add_argument("-d", "--debug", help="print debug logging information", action="store_true") | |
args = parser.parse_args() | |
#If output omitted, set output to input so it overwrites source | |
if not args.output: | |
args.output = args.input | |
#Turn on logging if specified | |
if args.debug: | |
logging.getLogger().setLevel("DEBUG") | |
elif args.verbose: | |
logging.getLogger().setLevel("INFO") | |
#Check that input file exists | |
if not os.path.isfile(args.input): | |
sys.exit(os.path.basename(__file__) + ": error: " + args.input + " does not exist") | |
#Set logging format | |
logging.basicConfig(format="%(levelname)s:%(message)s") | |
#Parse fcpxml and catch any errors | |
try: | |
tree = ET.parse(args.input) | |
root = tree.getroot() | |
except: | |
sys.exit(os.path.basename(__file__) + ": error: " + args.input + " cannot be parsed") | |
#Check if it is really an fcpxml | |
if root.tag != "fcpxml": | |
sys.exit(os.path.basename(__file__) + ": error: " + args.input + " is not an fcpxml") | |
#Check if destination folder exists | |
if not os.path.exists(os.path.dirname(args.output)): | |
sys.exit(os.path.basename(__file__) + ": error: " + os.path.dirname(args.output) + " does not exist") | |
#Get library path so we can look for transcoded media inside it | |
library_url = root.find('library').get('location') | |
library_path = urlparse(library_url).path | |
#Get folders inside library (probably events, though maybe not) | |
(_, events, _) = os.walk(library_path).next() | |
proxy_media_files = {} | |
high_quality_media_files = {} | |
#Add media files to dicts | |
for event in events: | |
proxy_media_files.update(get_media_in_path(os.path.join(library_path, event), 'Proxy Media')) | |
high_quality_media_files.update(get_media_in_path(os.path.join(library_path, event), 'High Quality Media')) | |
#Merge dicts, giving priority to High Quality unless arg says otherwise | |
if args.proxy: | |
transcoded_media_files = high_quality_media_files.copy() | |
transcoded_media_files.update(proxy_media_files) | |
else: | |
transcoded_media_files = proxy_media_files.copy() | |
transcoded_media_files.update(high_quality_media_files) | |
for asset in root.findall('resources/asset'): | |
#get file without extension | |
src = urlparse(asset.get('src')).path | |
filename = os.path.basename(src) | |
first_part = os.path.splitext(filename)[0] | |
#Remove last 4 chars if it ends in _001 (e.g. if it's a RED file) | |
if re.search('_\d{3}$', first_part): | |
first_part = first_part[:-4] | |
logging.debug('Searching for transcoded media match for {}'.format(first_part)) | |
if (first_part in transcoded_media_files): | |
#Update file source path | |
asset.set('src', transcoded_media_files[first_part]) | |
#Remove Bookmark because it's invalid | |
asset.remove(asset.find('bookmark')) | |
#Set text to None so element self closes | |
if asset.text == None or asset.text.strip() == '': | |
asset.text = None | |
logging.info('Modified {} to use transcoded media'.format(first_part)) | |
else: | |
logging.info('Unable to find transcoded media match for {}'.format(first_part)) | |
tree.write(args.output, encoding='UTF-8') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This looks like it solves a problem I frequently have with FCPX, but I've no idea how to use it. Can anyone give me some pointers?
Thanks!