Hi,
I was wondering if this is possible:
I have nuke job, and it does append quite a few time that i will have 5-6 failed frames. I would still like to the draft event script to pickup the job, and to assing a black frame (or double the frame before) trough the conversion. It will be nice aswell that if there is already a existing video, to append a (2) at the end.
Thks !
P.S. Here’s my script:
[code]import sys
import os
import datetime
import copy
import xml.etree.ElementTree as xml
import Draft
from DraftParamParser import *
print “Draft Version: %s” % Draft.LibraryInfo.Version()
def ResizeWithLetterbox(self, width, height):
if width <= 0:
raise RuntimeError(‘width must be a positive number’)
if height <= 0:
raise RuntimeError(‘height must be a positive number’)
sourceAR = float(self.width) / self.height
destAR = float(width) / height
if sourceAR == destAR:
self.Resize(width, height)
else:
image = copy.deepcopy(self)
if width <= self.width and height <= self.height:
self.Crop(0, 0, width, height)
else:
self.Resize(width,height)
self.SetToColor(Draft.ColorRGBA(0, 0, 0, 1.0))
if sourceAR > destAR:
image.Resize(width,int(round(width/sourceAR)))
else:
image.Resize(int(round(height*sourceAR)),height)
self.CompositeWithPositionAndGravity(image, 0.5, 0.5, Draft.PositionalGravity.CenterGravity, Draft.CompositeOperator.CopyCompositeOp)
Draft.Image.ResizeWithLetterbox = ResizeWithLetterbox
#Returns a dictionary of a Deadline Job’s properties
def getDeadlineJob (job, repository):
deadlineJobPath = (repository + “\jobs\” + job + “\” + job + “.job”)
jobKeys = (xml.parse(deadlineJobPath)).getroot()
jobDict = {}
for o in list(jobKeys):
if len(o.getchildren()) < 1:
jobDict[o.tag] = o.text
else:
jobDict[o.tag] = []
for t in list(o):
(jobDict[o.tag]).append(t.text)
jobDict[‘deadlineJobPath’] = deadlineJobPath
return jobDict
#Returns a list of frames based on the given frameString
def FrameListToFrames( frameString ):
frames = []
frameRangeTokens = re.split( ‘\s+|,+’, frameString )
for token in frameRangeTokens:
try:
if ( len(token) > 0 ):
dashIndex = string.find( token, '-', 1)
if ( dashIndex == -1 ):
startFrame = int(token)
frames.add( startFrame )
else:
startFrame = int(token[0:dashIndex])
m = re.match( "(-?\d+)(?:(x|step|by|every)(\d+))?", token[dashIndex + 1:] )
if ( m == None ):
raise StandardError( "Second part of Token '" + token[dashIndex + 1:] + "' failed regex match" )
else:
endFrame = int(m.group(1))
if ( m.group(2) == None ):
frames.extend( range(startFrame, endFrame + 1 ))
else:
dir = 1
if startFrame > endFrame:
dir = -1
byFrame = int(m.group(3));
frame = startFrame
while (startFrame * dir) <= (endFrame * dir):
frames.add( frame )
frame += byFrame * dir
except:
print "ERROR: Frame Range token '" + token + "' is malformed. Skipping this token."
raise
frames = list(set(frames))
frames.sort()
return frames
#CHANGE ME! Path to the Deadline Repository root
deadlineRepo = “\fx-deadline\deadline\”
#CHANGE ME! Path to an image containing the background of the slate frame
slateFrame = “\\fx-deadline\deadline\Draft\Slate_Montage5K.png”
#The argument name/types we’re expecting from the command line arguments
expectedTypes = dict()
expectedTypes[‘frameList’] = ‘’
expectedTypes[‘inFile’] = ‘’
expectedTypes[‘outFile’] = ‘’
expectedTypes[‘username’] = ‘’
expectedTypes[‘entity’] = ‘’
expectedTypes[‘version’] = ‘’
expectedTypes[‘deadlineJobID’] = ‘’
#Parse the command line arguments
params = ParseCommandLine( expectedTypes, sys.argv )
inFilePattern = params[‘inFile’]
frames = FrameListToFrames( params[‘frameList’] )
(outBase, outExt)= os.path.splitext( params[‘outFile’] )
#not a huge deal if we can’t connect to the repo, we’ll just be missing some info
try:
jobParams = getDeadlineJob( params[‘deadlineJobID’], deadlineRepo )
except:
jobParams = {}
outWidth = 1920
outHeight = 1080
slateFrames = 1
for eye in [‘l’,‘r’]:
#Build up the encoders
outBaseEye = outBase.replace( ‘%v’, eye )
MJPEGencoder = Draft.VideoEncoder( outBaseEye + outExt, 24.0, outWidth, outHeight, 100000, “MJPEG” )
#Annotation info used for burn ins
annotationInfo = Draft.AnnotationInfo()
annotationInfo.FontType = "Times-New-Roman"
annotationInfo.PointSize = int( outHeight * 0.022 )
annotationInfo.Color = Draft.ColorRGBA( 1.0, 1.0, 1.0, 1.0 )
#prep the Slate Frame
try:
slate = Draft.Image.ReadFromFile( slateFrame )
except:
slate = Draft.Image.CreateImage( outWidth, outHeight )
slate.SetToColor( Draft.ColorRGBA( 0.0, 0.0, 0.0, 1.0 ) )
if ( slate.width != outWidth or slate.height != outHeight ):
slate.ResizeWithLetterbox( outWidth, outHeight )
#sets up the text on the slate frame
slateAnnotations = [
("SHOW", jobParams.get('ExtraInfo1', '<SKIP>')), #This line is skipped if there is not ExtraInfo1
("Episode", params.get('episode', '<SKIP>')), #This line is skipped if 'episode' isn't in the extra args
("Shot", params['entity']),
("Frames", params['frameList']),
("Handles", params.get('handles', '<SKIP>')), #This line is skipped if 'handles' isn't in the extra args
("Version", params['version']),
("",''),
("",''),
("Artist", params['username']),
("Date", datetime.datetime.now().strftime("%m/%d/%Y %I:%M %p") )
]
#comp the annotations over top the slate frame
skipLines = 0
for i in range( 0, len( slateAnnotations ) ):
annotationTuple = slateAnnotations[i]
if ( annotationTuple[1] == "<SKIP>" ):
skipLines += 1
continue
lineNum = i - skipLines
if ( annotationTuple[0] != "" ):
annotation = Draft.Image.CreateAnnotation( slateAnnotations[i][0] + ": ", annotationInfo )
slate.CompositeWithPositionAndGravity( annotation, 0.45, 0.7 - (lineNum * 0.06), Draft.PositionalGravity.SouthEastGravity, Draft.CompositeOperator.OverCompositeOp )
if ( annotationTuple[1] != "" ):
annotation = Draft.Image.CreateAnnotation( slateAnnotations[i][1], annotationInfo )
slate.CompositeWithPositionAndGravity( annotation, 0.46, 0.7 - (lineNum * 0.06), Draft.PositionalGravity.SouthWestGravity, Draft.CompositeOperator.OverCompositeOp )
#encode the slate frames at the start of the video
print( "Encoding Slate Frames..." )
for i in range( 0, slateFrames ):
MJPEGencoder.EncodeNextFrame( slate )
studioAnnotation = Draft.Image.CreateAnnotation( "The Ice Age", annotationInfo )
entityAnnotation = Draft.Image.CreateAnnotation( "%s %s" % (params['entity'], datetime.datetime.now().strftime("%m/%d/%Y")), annotationInfo )
annotationInfo.BackgroundColor = Draft.ColorRGBA( 0.0, 0.0, 0.0, 1.0 )
#Main encoding loop
for frameNumber in frames:
print( "Processing Frame: %d...-1" % frameNumber )
inFile = inFilePattern.replace( '%v', eye )
inFile = ReplaceFilenameHashesWithNumber( inFile, frameNumber )
bgFrame = Draft.Image.ReadFromFile( inFile )
if ( bgFrame.width != outWidth or bgFrame.height != outHeight ):
bgFrame.ResizeWithLetterbox( outWidth, outHeight )
#Do the frame burnins
framesAnnotation = Draft.Image.CreateAnnotation( str( frameNumber ), annotationInfo )
bgFrame.CompositeWithPositionAndGravity( studioAnnotation, 0.0, 1.0, Draft.PositionalGravity.NorthWestGravity, Draft.CompositeOperator.OverCompositeOp )
bgFrame.CompositeWithPositionAndGravity( entityAnnotation, 0.0, 0.0, Draft.PositionalGravity.SouthWestGravity, Draft.CompositeOperator.OverCompositeOp )
bgFrame.CompositeWithPositionAndGravity( framesAnnotation, 1.0, 0.0, Draft.PositionalGravity.SouthEastGravity, Draft.CompositeOperator.OverCompositeOp )
MJPEGencoder.EncodeNextFrame( bgFrame )
#Finalize the encoding process
MJPEGencoder.FinalizeEncoding()
[/code]