I just did a job where we had a folder tree of ProRes footage, which I needed to convert to DXV. The usual suspects don't recursively descend into folders. So I wrote a python script that cross-references what it finds in the Avenue compositions with what it can find in that master folder tree, and replaces what Avenue uses with DXV versions.
Theres plenty of room for improvements, but it got us through the job. I'm posting here in developers as it's a little raw, and the master tree paths are hardcoded and will need updating with yours. Enjoy, and tweak away...
Code: Select all
#!/usr/bin/env python
### TOBYZ RESOLUME MOVIE CONVERTER
#
# Assuming you've got a project with a master footage folder / structure, it keeps a laptop with resolume in sync with the ProRes masters
#
# You have
# i. Resolume on a laptop with it's composition files in the standard place, ie. Documents
# i. A folder tree of ProRes content - likely remote on a production machine
# i. A local copy of that production folder that resolume is set up with
# i. This installed: http://www.omino.com/sw/qt_tools/
#
# Run this
# i. it will scan the resolume compositions for referenced media
# i. cross reference that with what it can find in the production tree
# i. convert across from the masters to the local, overwriting the ProRes with DXV as it goes.
import os
import subprocess
# These folder paths need trailing slashes
movProductionRootDir = '/Volumes/INTERPLAY_2_MAIN/interplay/INTERPLAY FOOTAGE MASTER/'
movLiveRootDir = '/Users/interplay/Desktop/Interplay Visual Score/INTERPLAY FOOTAGE MASTER/'
QTExportFilePath = '/usr/local/bin/qt_export'
if __name__ == '__main__':
movProductionPaths = [os.path.join(root, f) for root, dirs, files in os.walk(movProductionRootDir) for f in files]
movProductionSubPaths = [p[len(movProductionRootDir):] for p in movProductionPaths]
resolumeAVCFolder = os.path.expanduser('~/Documents/Resolume Avenue 4/compositions')
resolumeAVCPaths = [os.path.join(resolumeAVCFolder, f) for f in os.listdir(resolumeAVCFolder) if f.endswith('.avc')]
resolumeMovPaths = []
for avcFile in [open(filePath, 'r') for filePath in resolumeAVCPaths]:
for line in avcFile:
if '<source type="file" couldContainVideo="1"' in line:
startIndex = line.find('name="') + 6
endIndex = line.find('"', startIndex)
path = line[startIndex:endIndex]
if path not in resolumeMovPaths:
resolumeMovPaths.append(path)
resolumeMovSubPaths = [p[len(movLiveRootDir):] for p in resolumeMovPaths]
movSubPathsToConvert = []
movSubPathsToReject = []
for path in resolumeMovSubPaths:
if path in movProductionSubPaths:
movSubPathsToConvert.append(path)
else:
# Match can fail due to added .mov, which Resolume needs but typically isn't added by production exports
if path[:-4] in movProductionSubPaths:
movSubPathsToConvert.append(path)
else:
movSubPathsToReject.append(path)
print 'To Convert:'
print "\n".join(movSubPathsToConvert)
print
print 'Rejected (movs listed in resolume compositions but not in production dir):'
print "\n".join(movSubPathsToReject)
# NOTES qt_export
# To get list of codec 4 character codes
# qt_thing --type='imco'
# + 3 @0x000100e3 imco:DXDI:appl "DXV Compressor"
# + 4 @0x000100e9 imco:Hap1:VDVX "Hap"
# + 5 @0x000100ed imco:Hap5:VDVX "Hap Alpha"
# + 6 @0x000100eb imco:HapY:VDVX "Hap Q"
# Popping up a dialog as couldn't seem to set alpha or not for DXV with --video args
settingsPath = os.path.join(movLiveRootDir, 'TBZ Settings')
command = '{} --video=DXDI,0,100,24 --audio=0 --dodialog --savesettings="{}"'.format(QTExportFilePath, settingsPath)
subprocess.call(command, shell=True)
for path in movSubPathsToConvert:
sourceMovPath = os.path.join(movProductionRootDir, path)
targetMovPath = os.path.join(movLiveRootDir, path)
# remove extension from target path if necessary
if not os.path.exists(sourceMovPath):
sourceMovPath = sourceMovPath[:-4]
print 'CONVERTING\nFrom: {}\nTo: {}\n'.format(sourceMovPath, targetMovPath)
command = '{} --loadsettings="{}" --replacefile --verbosity=0 "{}" "{}"'.format(QTExportFilePath, settingsPath , sourceMovPath , targetMovPath)
# Ensure parent directory is there
try:
os.makedirs(os.path.dirname(targetMovPath))
except:
pass
# Convert!
subprocess.call(command, shell=True)