AWS Thinkbox Discussion Forums

draft event listener dosen't pickup all the job

Hi,

Most of the time, draft dosen’t pickup our job on the event listener script. Do you have reason that you could know why it’s doing this ?

Thanks !

Fred

Hi Fred,

There could be many different reasons for this. The easiest way to find out what’s going on is to first check the logs for one of the Jobs that isn’t generating a new Draft Job on completion. Just right-click the Job in the Monitor and select ''Job Reports" -> “View Log Reports”. In the log window, you want to look for any Logs generated by the ‘Draft’ plugin (as opposed to the plugin the Job is actually for).

If there aren’t any, or if it’s just a message that says “No draft settings found” or something similar, that means that there wasn’t a Draft Template tied to the original Job. You can double-check whether or not it has Draft submission info tied to it by checking the ‘Extra Info’ tab in the Job’s properties window; there should be a bunch of Draft-related stuff in the ‘Extra Info Key/Value Pairs’ section.

Either way, let us know what comes up in the Job’s logs, and we’ll go from there

Cheers,

  • Jon

Here’s one log

[code]=======================================================
Log Message

Checking job for Draft settings…
Found Draft Template: ‘//fx-nas-01/vfx/RENDER/simple_slate_h264_MJPEG_burnins.py’
Preparing Draft Job for output 1/1: \fx-nas-01\vfx\RENDER\IA\SHOTS\005\0012\cmp\outputs\v05\Draft\IA.005.0012.cmp.v05.%v.mov
Submitting Draft Job to Deadline…

=======================================================
Log Details

Log Date/Time = Jun 13/12 00:21:24
Frames = (no task)

Slave Machine = Fx-render-02_instance_01
Slave Version = v5.1.0.46114 R

Plugin Name = Draft

.[/code]

I double chek with the artist and the job proprieties. The draft is activated with a correct path to the template.
The draft is suppose to luanch event if the job failed. Could it be a reason that the render is in “x10” ?

Here’s my script.

[code]aimport 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’] )

if(True):
(outDir, outFile) = os.path.split(params[‘outFile’])
(outBase, outExt) = os.path.splitext(outFile)

outFolder = os.path.basename(outDir)

if not os.path.exists(os.path.join(outDir, '1080p')):
    os.makedirs(os.path.join(outDir, '1080p'))
if not os.path.exists(os.path.join(outDir, 'halfrez')):
    os.makedirs(os.path.join(outDir, 'halfrez'))
if not os.path.exists(os.path.join(outDir, 'fullrez')):
    os.makedirs(os.path.join(outDir, 'fullrez'))

else:
(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
fullWidth = 5120
fullHeight = 2700
halfWidth = 2560
halfHeight = 1350
slateFrames = 1
outLut = Draft.LUT.CreateRec709()

for eye in [‘l’,‘r’]:
#Build up the encoders
outBaseEye = outBase.replace( ‘%v’, eye )
outBaseEyeHalf = outBase.replace( ‘%v’, eye ) + “-Hres”
outBaseEyeFull = outBase.replace( ‘%v’, eye ) + “-Fres”

#Appends (#) on the end of the filename until we have a unique name
increment = 2
newFileName = '%s/1080p/%s%s'%(outDir, outBaseEye, outExt)
while os.path.exists( newFileName ):
    newFileName = '%s/1080p/%s (%d)%s'%(outDir, outBaseEye, increment, outExt)
    #newFileName = "%s (%d)%s" % (outBaseEye, increment, outExt)
    increment += 1

#Appends (#) on the end of the filename until we have a unique name
increment = 2
newFileNameHalf = '%s/halfrez/%s%s'%(outDir, outBaseEyeHalf, outExt)
while os.path.exists( newFileNameHalf ):
    newFileNameHalf = '%s/halfrez/%s (%d)%s'%(outDir, outBaseEyeHalf, increment, outExt)
    #newFileNameHalf = "%s (%d)%s" % (outBaseEyeHalf, increment, outExt)
    increment += 1

#Appends (#) on the end of the filename until we have a unique name
#increment = 2
#newFileNameFull = '%s/fullrez/%s%s'%(outDir, outBaseEyeFull, outExt)
#while os.path.exists( newFileNameFull ):
    #newFileNameFull = '%s/fullrez/%s (%d)%s'%(outDir, outBaseEyeFull, increment, outExt)
    #newFileNameFull = "%s (%d)%s" % (outBaseEyeFull, increment, outExt)
    #increment += 1	

MJPEGencoder = Draft.VideoEncoder( newFileName, 24.0, outWidth, outHeight, 75000, "MJPEG" )
MJPEGencoderHRes = Draft.VideoEncoder( newFileNameHalf, 24.0, halfWidth, halfHeight, 325000, "MJPEG" )
#MJPEGencoderFRes = Draft.VideoEncoder( newFileNameFull, 24.0, fullWidth, fullHeight, 350000, "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 )

outLut.Apply( slate )

#encode the slate frames at the start of the video
print( "Encoding Slate Frames..." )
for i in range( 0, slateFrames ):
    MJPEGencoder.EncodeNextFrame( slate )
    MJPEGencoderHRes.EncodeNextFrame( slate )
    #MJPEGencoderFRes.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 )

    #check if the file exists
    blackFrame = ( not os.path.exists( inFile ) )

    if not blackFrame:
        try:
            #try to read in the frame
            bgFrame = Draft.Image.ReadFromFile( inFile )
        except:
            #failed to read in, encode a black frame instead
            blackFrame = True

    #create a black frame if we weren't able to read it in
    if blackFrame:
        bgFrame = Draft.Image.CreateImage( outWidth, outHeight )
        bgFrame.SetToColor( Draft.ColorRGBA( 0.0, 1.0, 0.0, 1.0 ) )
    elif ( 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, 0.5, 0.0, Draft.PositionalGravity.SouthEastGravity, Draft.CompositeOperator.OverCompositeOp )

    outLut.Apply( bgFrame )

    MJPEGencoder.EncodeNextFrame( bgFrame )
    MJPEGencoderHRes.EncodeNextFrame( bgFrame )
    #MJPEGencoderFRes.EncodeNextFrame( bgFrame )
 
#Finalize the encoding process
MJPEGencoder.FinalizeEncoding()
MJPEGencoderHRes.FinalizeEncoding()
#MJPEGencoderFRes.FinalizeEncoding()

[/code]

Also, i wonder in my script if there could be a way, that insted of doing a green frame when there is no frame, to frezze the previous frame. (like in rv) so when can see the render in step properly.

Thks !

Fred

Hey Fred,

I’m a bit confused; the Log you posted seems to indicate successful submission of the Draft job. Are you sure there was no Draft Job associated with the Job whose log this is? If this is only a problem when the Jobs are failing, I would check to make sure the modifications you made for that to the Draft Event Script are still there (the ones I suggested in one of my previous posts). It might be that a recent Deadline upgrade reverted your changes. As with all plugin/submission script modifications, this is something you generally need to be aware of, unfortunately.

As for encoding the previous frame again, instead of a black frame, that shouldn’t be too hard to do. You just need to make sure the previous frame is still available for subsequent iterations of your encoding loop. Something like this should do:

[...]

    #initialize the frame to None
    bgFrame = None

    #Main encoding loop
    for frameNumber in frames:
        print( "Processing Frame: %d...-1" % frameNumber )

        inFile = inFilePattern.replace( '%v', eye )
        inFile = ReplaceFilenameHashesWithNumber( inFile, frameNumber )

        #check if the file exists
        prevFrame = ( not os.path.exists( inFile ) )

        if not prevFrame:
            try:
                #try to read in the frame
                bgFrame = Draft.Image.ReadFromFile( inFile )
            except:
                #failed to read in, that's OK, we'll just re-encode the previous frame
                pass

        #create a black frame if we couldn't read in, and don't have a previous frame to encode
        if bgFrame == None:
            bgFrame = Draft.Image.CreateImage( outWidth, outHeight )
            bgFrame.SetToColor( Draft.ColorRGBA( 0.0, 1.0, 0.0, 1.0 ) )
        elif ( bgFrame.width != outWidth or bgFrame.height != outHeight ):
            bgFrame.ResizeWithLetterbox( outWidth, outHeight )

[...]

You’ll note that the code is mostly the same as it was before, I just added a declaration of bgFrame outside of the loop to make sure it stayed in scope between iterations. It will also only set the frame to be green if there hasn’t been a successful frame yet.

Cheers,

  • Jon

Hi jon,

Here’s the wierd thing, it says it pickup a draft job, but then theres is no new job that queued itselft in deadline. I did make sure that the custom event listener is always properly updated. The other wierd thing is there half of the job that does the draft. Could there be a way that we are naming are job that could interfere with draft ?

Also since i updated my script with the new one, i got lots of crashes with similar logs.

[code]=======================================================
Error Message

Exception during render: An error occurred in RenderTasks(): Error in CheckExitCode(): Renderer returned non-zero error code, 1. Check the log for more information.
à Deadline.Plugins.ScriptPlugin.RenderTasks(String taskId, Int32 startFrame, Int32 endFrame, String& outMessage)

=======================================================
Slave Log

0: Loaded plugin: Draft
0: Task timeout is disabled.
0: Loaded job: IA_007_0001_prp_all.nk [DRAFT] (002_050_00a_6688d3c7)
0: Successfully mapped R: to \FX-NAS-01\vfx\RENDER
0: Successfully mapped K: to \FX-NAS-01\vfx\Projets
0: INFO: StartJob: initializing script plugin Draft
0: INFO: Found Draft python module at: ‘C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Draft_node_2\Draft\Draft.pyd’
0: INFO: About: Draft Plugin for Deadline
0: Plugin rendering frame(s): 0
0: INFO: Draft job starting…
0: INFO: Stdout Handling Enabled: False
0: INFO: Popup Handling Enabled: False
0: INFO: Using Process Tree: True
0: INFO: Hiding DOS Window: True
0: INFO: Creating New Console: False
0: INFO: Looking for bundled python at: ‘C:\Program Files\Thinkbox\Deadline\python\2.6.7\x64\python.exe’
0: INFO: Render Executable: “C:\Program Files\Thinkbox\Deadline\python\2.6.7\x64\python.exe”
0: INFO: Render Argument: -u “R:\simple_slate_h264_MJPEG_burnins.py” username=“somebody” entity=“IA_007_0001_prp_all.nk” version="" inFile=“R:\IA\PLATES\007\0001\prp\outputs\full_rez\IA_007_0001_prp_all_dst.%v.####.exr” outFile=“R:\IA\PLATES\007\0001\prp\outputs\full_rez\Draft\IA_007_0001_prp_all_dst.%v…mov” startFrame=“1” endFrame=“444” frameList=“1-444” deadlineJobID=003_040_999_7dcb7383
0: INFO: Startup Directory: “C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Draft_node_2\Draft”
0: INFO: Process Priority: BelowNormal
0: INFO: Process is now running
0: STDOUT: Checking for license at @prodflexmr
0: STDOUT: Draft Beta 0.10.0.47171
0: STDOUT: Draft Version: 0.10.0.47171
0: STDOUT: Command line args:
0: STDOUT: username=gboudreau
0: STDOUT: entity=IA_007_0001_prp_all.nk
0: STDOUT: version=
0: STDOUT: inFile=R:\IA\PLATES\007\0001\prp\outputs\full_rez\IA_007_0001_prp_all_dst.%v.####.exr
0: STDOUT: outFile=R:\IA\PLATES\007\0001\prp\outputs\full_rez\Draft\IA_007_0001_prp_all_dst.%v…mov
0: STDOUT: startFrame=1
0: STDOUT: endFrame=444
0: STDOUT: frameList=1-444
0: STDOUT: deadlineJobID=003_040_999_7dcb7383
0: STDOUT: Encoding Slate Frames…
0: STDOUT: Processing Frame: 1…-1
0: STDOUT: Processing Frame: 2…-1
0: STDOUT: Processing Frame: 3…-1
0: STDOUT: Processing Frame: 4…-1
0: STDOUT: Processing Frame: 5…-1
0: STDOUT: Processing Frame: 6…-1
0: STDOUT: Processing Frame: 7…-1
0: STDOUT: Processing Frame: 8…-1
0: STDOUT: Processing Frame: 9…-1
0: STDOUT: Processing Frame: 10…-1
0: STDOUT: Processing Frame: 11…-1
0: STDOUT: Processing Frame: 12…-1
0: STDOUT: Processing Frame: 13…-1
0: STDOUT: Processing Frame: 14…-1
0: STDOUT: Processing Frame: 15…-1
0: STDOUT: Processing Frame: 16…-1
0: STDOUT: Processing Frame: 17…-1
0: STDOUT: Processing Frame: 18…-1
0: STDOUT: Processing Frame: 19…-1
0: STDOUT: Processing Frame: 20…-1
0: STDOUT: Processing Frame: 21…-1
0: STDOUT: Processing Frame: 22…-1
0: STDOUT: Processing Frame: 23…-1
0: STDOUT: Processing Frame: 24…-1
0: STDOUT: Processing Frame: 25…-1
0: STDOUT: Processing Frame: 26…-1
0: STDOUT: Processing Frame: 27…-1
0: STDOUT: Processing Frame: 28…-1
0: STDOUT: Processing Frame: 29…-1
0: STDOUT: Processing Frame: 30…-1
0: STDOUT: Processing Frame: 31…-1
0: STDOUT: Processing Frame: 32…-1
0: STDOUT: Processing Frame: 33…-1
0: STDOUT: Processing Frame: 34…-1
0: STDOUT: Processing Frame: 35…-1
0: STDOUT: Processing Frame: 36…-1
0: STDOUT: Processing Frame: 37…-1
0: STDOUT: Processing Frame: 38…-1
0: STDOUT: Processing Frame: 39…-1
0: STDOUT: Processing Frame: 40…-1
0: STDOUT: Processing Frame: 41…-1
0: STDOUT: Processing Frame: 42…-1
0: STDOUT: Processing Frame: 43…-1
0: STDOUT: Processing Frame: 44…-1
0: STDOUT: Processing Frame: 45…-1
0: STDOUT: Processing Frame: 46…-1
0: STDOUT: Processing Frame: 47…-1
0: STDOUT: Processing Frame: 48…-1
0: STDOUT: Processing Frame: 49…-1
0: STDOUT: Processing Frame: 50…-1
0: STDOUT: Processing Frame: 51…-1
0: STDOUT: Processing Frame: 52…-1
0: STDOUT: Processing Frame: 53…-1
0: STDOUT: Processing Frame: 54…-1
0: STDOUT: Processing Frame: 55…-1
0: STDOUT: Processing Frame: 56…-1
0: STDOUT: Processing Frame: 57…-1
0: STDOUT: Processing Frame: 58…-1
0: STDOUT: Processing Frame: 59…-1
0: STDOUT: Processing Frame: 60…-1
0: STDOUT: Processing Frame: 61…-1
0: STDOUT: Processing Frame: 62…-1
0: STDOUT: Processing Frame: 63…-1
0: STDOUT: Processing Frame: 64…-1
0: STDOUT: Processing Frame: 65…-1
0: STDOUT: Processing Frame: 66…-1
0: STDOUT: Processing Frame: 67…-1
0: STDOUT: Processing Frame: 68…-1
0: STDOUT: Processing Frame: 69…-1
0: STDOUT: Processing Frame: 70…-1
0: STDOUT: Processing Frame: 71…-1
0: STDOUT: Processing Frame: 72…-1
0: STDOUT: Processing Frame: 73…-1
0: STDOUT: Processing Frame: 74…-1
0: STDOUT: Processing Frame: 75…-1
0: STDOUT: Processing Frame: 76…-1
0: STDOUT: Processing Frame: 77…-1
0: STDOUT: Processing Frame: 78…-1
0: STDOUT: Processing Frame: 79…-1
0: STDOUT: Processing Frame: 80…-1
0: STDOUT: Processing Frame: 81…-1
0: STDOUT: Processing Frame: 82…-1
0: STDOUT: Processing Frame: 83…-1
0: STDOUT: Processing Frame: 84…-1
0: STDOUT: Processing Frame: 85…-1
0: STDOUT: Processing Frame: 86…-1
0: STDOUT: Processing Frame: 87…-1
0: STDOUT: Processing Frame: 88…-1
0: STDOUT: Processing Frame: 89…-1
0: STDOUT: Processing Frame: 90…-1
0: STDOUT: Processing Frame: 91…-1
0: STDOUT: Processing Frame: 92…-1
0: STDOUT: Processing Frame: 93…-1
0: STDOUT: Processing Frame: 94…-1
0: STDOUT: Processing Frame: 95…-1
0: STDOUT: Processing Frame: 96…-1
0: STDOUT: Processing Frame: 97…-1
0: STDOUT: Processing Frame: 98…-1
0: STDOUT: Processing Frame: 99…-1
0: STDOUT: Processing Frame: 100…-1
0: STDOUT: Processing Frame: 101…-1
0: STDOUT: Processing Frame: 102…-1
0: STDOUT: Processing Frame: 103…-1
0: STDOUT: Processing Frame: 104…-1
0: STDOUT: Processing Frame: 105…-1
0: STDOUT: Processing Frame: 106…-1
0: STDOUT: Processing Frame: 107…-1
0: STDOUT: Processing Frame: 108…-1
0: STDOUT: Processing Frame: 109…-1
0: STDOUT: Processing Frame: 110…-1
0: STDOUT: Processing Frame: 111…-1
0: STDOUT: Processing Frame: 112…-1
0: STDOUT: Processing Frame: 113…-1
0: STDOUT: Processing Frame: 114…-1
0: STDOUT: Processing Frame: 115…-1
0: STDOUT: Processing Frame: 116…-1
0: STDOUT: Processing Frame: 117…-1
0: STDOUT: Processing Frame: 118…-1
0: STDOUT: Processing Frame: 119…-1
0: STDOUT: Processing Frame: 120…-1
0: STDOUT: Processing Frame: 121…-1
0: STDOUT: Processing Frame: 122…-1
0: STDOUT: Processing Frame: 123…-1
0: STDOUT: Processing Frame: 124…-1
0: STDOUT: Processing Frame: 125…-1
0: STDOUT: Processing Frame: 126…-1
0: STDOUT: Processing Frame: 127…-1
0: STDOUT: Processing Frame: 128…-1
0: STDOUT: Processing Frame: 129…-1
0: STDOUT: Processing Frame: 130…-1
0: STDOUT: Processing Frame: 131…-1
0: STDOUT: Processing Frame: 132…-1
0: STDOUT: Processing Frame: 133…-1
0: STDOUT: Processing Frame: 134…-1
0: STDOUT: Processing Frame: 135…-1
0: STDOUT: Processing Frame: 136…-1
0: STDOUT: Processing Frame: 137…-1
0: STDOUT: Processing Frame: 138…-1
0: STDOUT: Processing Frame: 139…-1
0: STDOUT: Processing Frame: 140…-1
0: STDOUT: Processing Frame: 141…-1
0: STDOUT: Processing Frame: 142…-1
0: STDOUT: Processing Frame: 143…-1
0: STDOUT: Processing Frame: 144…-1
0: STDOUT: Processing Frame: 145…-1
0: STDOUT: Processing Frame: 146…-1
0: STDOUT: Processing Frame: 147…-1
0: STDOUT: Processing Frame: 148…-1
0: STDOUT: Processing Frame: 149…-1
0: STDOUT: Processing Frame: 150…-1
0: STDOUT: Processing Frame: 151…-1
0: STDOUT: Processing Frame: 152…-1
0: STDOUT: Processing Frame: 153…-1
0: STDOUT: Processing Frame: 154…-1
0: STDOUT: Processing Frame: 155…-1
0: STDOUT: Processing Frame: 156…-1
0: STDOUT: Processing Frame: 157…-1
0: STDOUT: Processing Frame: 158…-1
0: STDOUT: Processing Frame: 159…-1
0: STDOUT: Processing Frame: 160…-1
0: STDOUT: Processing Frame: 161…-1
0: STDOUT: Processing Frame: 162…-1
0: STDOUT: Processing Frame: 163…-1
0: STDOUT: Processing Frame: 164…-1
0: STDOUT: Processing Frame: 165…-1
0: STDOUT: Processing Frame: 166…-1
0: STDOUT: Processing Frame: 167…-1
0: STDOUT: Processing Frame: 168…-1
0: STDOUT: Processing Frame: 169…-1
0: STDOUT: Processing Frame: 170…-1
0: STDOUT: Processing Frame: 171…-1
0: STDOUT: Processing Frame: 172…-1
0: STDOUT: Processing Frame: 173…-1
0: STDOUT: Processing Frame: 174…-1
0: STDOUT: Processing Frame: 175…-1
0: STDOUT: Processing Frame: 176…-1
0: STDOUT: Processing Frame: 177…-1
0: STDOUT: Processing Frame: 178…-1
0: STDOUT: Processing Frame: 179…-1
0: STDOUT: Processing Frame: 180…-1
0: STDOUT: Processing Frame: 181…-1
0: STDOUT: Processing Frame: 182…-1
0: STDOUT: Processing Frame: 183…-1
0: STDOUT: Processing Frame: 184…-1
0: STDOUT: Processing Frame: 185…-1
0: STDOUT: Processing Frame: 186…-1
0: STDOUT: Processing Frame: 187…-1
0: STDOUT: Processing Frame: 188…-1
0: STDOUT: Processing Frame: 189…-1
0: STDOUT: Processing Frame: 190…-1
0: STDOUT: Processing Frame: 191…-1
0: STDOUT: Processing Frame: 192…-1
0: STDOUT: Processing Frame: 193…-1
0: STDOUT: Processing Frame: 194…-1
0: STDOUT: Processing Frame: 195…-1
0: STDOUT: Processing Frame: 196…-1
0: STDOUT: Processing Frame: 197…-1
0: STDOUT: Processing Frame: 198…-1
0: STDOUT: Processing Frame: 199…-1
0: STDOUT: Processing Frame: 200…-1
0: STDOUT: Processing Frame: 201…-1
0: STDOUT: Processing Frame: 202…-1
0: STDOUT: Processing Frame: 203…-1
0: STDOUT: Processing Frame: 204…-1
0: STDOUT: Processing Frame: 205…-1
0: STDOUT: Processing Frame: 206…-1
0: STDOUT: Processing Frame: 207…-1
0: STDOUT: Processing Frame: 208…-1
0: STDOUT: Processing Frame: 209…-1
0: STDOUT: Processing Frame: 210…-1
0: STDOUT: Processing Frame: 211…-1
0: STDOUT: Processing Frame: 212…-1
0: STDOUT: Processing Frame: 213…-1
0: STDOUT: Processing Frame: 214…-1
0: STDOUT: Processing Frame: 215…-1
0: STDOUT: Processing Frame: 216…-1
0: STDOUT: Processing Frame: 217…-1
0: STDOUT: Processing Frame: 218…-1
0: STDOUT: Processing Frame: 219…-1
0: STDOUT: Processing Frame: 220…-1
0: STDOUT: Processing Frame: 221…-1
0: STDOUT: Processing Frame: 222…-1
0: STDOUT: Processing Frame: 223…-1
0: STDOUT: Processing Frame: 224…-1
0: STDOUT: Processing Frame: 225…-1
0: STDOUT: Processing Frame: 226…-1
0: STDOUT: Processing Frame: 227…-1
0: STDOUT: Processing Frame: 228…-1
0: STDOUT: Processing Frame: 229…-1
0: STDOUT: Processing Frame: 230…-1
0: STDOUT: Processing Frame: 231…-1
0: STDOUT: Processing Frame: 232…-1
0: STDOUT: Processing Frame: 233…-1
0: STDOUT: Processing Frame: 234…-1
0: STDOUT: Processing Frame: 235…-1
0: STDOUT: Processing Frame: 236…-1
0: STDOUT: Processing Frame: 237…-1
0: STDOUT: Processing Frame: 238…-1
0: STDOUT: Processing Frame: 239…-1
0: STDOUT: Processing Frame: 240…-1
0: STDOUT: Processing Frame: 241…-1
0: STDOUT: Processing Frame: 242…-1
0: STDOUT: Processing Frame: 243…-1
0: STDOUT: Processing Frame: 244…-1
0: STDOUT: Processing Frame: 245…-1
0: STDOUT: Processing Frame: 246…-1
0: STDOUT: Processing Frame: 247…-1
0: STDOUT: Processing Frame: 248…-1
0: STDOUT: Processing Frame: 249…-1
0: STDOUT: Processing Frame: 250…-1
0: STDOUT: Processing Frame: 251…-1
0: STDOUT: Processing Frame: 252…-1
0: STDOUT: Processing Frame: 253…-1
0: STDOUT: Processing Frame: 254…-1
0: STDOUT: Processing Frame: 255…-1
0: STDOUT: Processing Frame: 256…-1
0: STDOUT: Processing Frame: 257…-1
0: STDOUT: Processing Frame: 258…-1
0: STDOUT: Processing Frame: 259…-1
0: STDOUT: Processing Frame: 260…-1
0: STDOUT: Processing Frame: 261…-1
0: STDOUT: Processing Frame: 262…-1
0: STDOUT: Processing Frame: 263…-1
0: STDOUT: Processing Frame: 264…-1
0: STDOUT: Processing Frame: 265…-1
0: STDOUT: Processing Frame: 266…-1
0: STDOUT: Processing Frame: 267…-1
0: STDOUT: Processing Frame: 268…-1
0: STDOUT: Processing Frame: 269…-1
0: STDOUT: Processing Frame: 270…-1
0: STDOUT: Processing Frame: 271…-1
0: STDOUT: Processing Frame: 272…-1
0: STDOUT: Processing Frame: 273…-1
0: STDOUT: Processing Frame: 274…-1
0: STDOUT: Processing Frame: 275…-1
0: STDOUT: Processing Frame: 276…-1
0: STDOUT: Processing Frame: 277…-1
0: STDOUT: Processing Frame: 278…-1
0: STDOUT: Processing Frame: 279…-1
0: STDOUT: Processing Frame: 280…-1
0: STDOUT: Processing Frame: 281…-1
0: STDOUT: Processing Frame: 282…-1
0: STDOUT: Processing Frame: 283…-1
0: STDOUT: Processing Frame: 284…-1
0: STDOUT: Processing Frame: 285…-1
0: STDOUT: Processing Frame: 286…-1
0: STDOUT: Processing Frame: 287…-1
0: STDOUT: Processing Frame: 288…-1
0: STDOUT: Processing Frame: 289…-1
0: STDOUT: Processing Frame: 290…-1
0: STDOUT: Processing Frame: 291…-1
0: STDOUT: Processing Frame: 292…-1
0: STDOUT: Processing Frame: 293…-1
0: STDOUT: Processing Frame: 294…-1
0: STDOUT: Processing Frame: 295…-1
0: STDOUT: Processing Frame: 296…-1
0: STDOUT: Processing Frame: 297…-1
0: STDOUT: Processing Frame: 298…-1
0: STDOUT: Processing Frame: 299…-1
0: STDOUT: Processing Frame: 300…-1
0: STDOUT: Processing Frame: 301…-1
0: STDOUT: Processing Frame: 302…-1
0: STDOUT: Processing Frame: 303…-1
0: STDOUT: Processing Frame: 304…-1
0: STDOUT: Processing Frame: 305…-1
0: STDOUT: Processing Frame: 306…-1
0: STDOUT: Processing Frame: 307…-1
0: STDOUT: Processing Frame: 308…-1
0: STDOUT: Processing Frame: 309…-1
0: STDOUT: Processing Frame: 310…-1
0: STDOUT: Processing Frame: 311…-1
0: STDOUT: Processing Frame: 312…-1
0: STDOUT: Processing Frame: 313…-1
0: STDOUT: Processing Frame: 314…-1
0: STDOUT: Processing Frame: 315…-1
0: STDOUT: Processing Frame: 316…-1
0: STDOUT: Processing Frame: 317…-1
0: STDOUT: Processing Frame: 318…-1
0: STDOUT: Processing Frame: 319…-1
0: STDOUT: Processing Frame: 320…-1
0: STDOUT: Processing Frame: 321…-1
0: STDOUT: Processing Frame: 322…-1
0: STDOUT: Processing Frame: 323…-1
0: STDOUT: Processing Frame: 324…-1
0: STDOUT: Processing Frame: 325…-1
0: STDOUT: Processing Frame: 326…-1
0: STDOUT: Processing Frame: 327…-1
0: STDOUT: Processing Frame: 328…-1
0: STDOUT: Processing Frame: 329…-1
0: STDOUT: Processing Frame: 330…-1
0: STDOUT: Processing Frame: 331…-1
0: STDOUT: Processing Frame: 332…-1
0: STDOUT: Processing Frame: 333…-1
0: STDOUT: Processing Frame: 334…-1
0: STDOUT: Processing Frame: 335…-1
0: STDOUT: Processing Frame: 336…-1
0: STDOUT: Processing Frame: 337…-1
0: STDOUT: Processing Frame: 338…-1
0: STDOUT: Processing Frame: 339…-1
0: STDOUT: Processing Frame: 340…-1
0: STDOUT: Processing Frame: 341…-1
0: STDOUT: Processing Frame: 342…-1
0: STDOUT: Processing Frame: 343…-1
0: STDOUT: Processing Frame: 344…-1
0: STDOUT: Processing Frame: 345…-1
0: STDOUT: Processing Frame: 346…-1
0: STDOUT: Processing Frame: 347…-1
0: STDOUT: Processing Frame: 348…-1
0: STDOUT: Processing Frame: 349…-1
0: STDOUT: Processing Frame: 350…-1
0: STDOUT: Processing Frame: 351…-1
0: STDOUT: Processing Frame: 352…-1
0: STDOUT: Processing Frame: 353…-1
0: STDOUT: Processing Frame: 354…-1
0: STDOUT: Processing Frame: 355…-1
0: STDOUT: Processing Frame: 356…-1
0: STDOUT: Processing Frame: 357…-1
0: STDOUT: Processing Frame: 358…-1
0: STDOUT: Processing Frame: 359…-1
0: STDOUT: Processing Frame: 360…-1
0: STDOUT: Processing Frame: 361…-1
0: STDOUT: Processing Frame: 362…-1
0: STDOUT: Processing Frame: 363…-1
0: STDOUT: Processing Frame: 364…-1
0: STDOUT: Processing Frame: 365…-1
0: STDOUT: Processing Frame: 366…-1
0: STDOUT: Processing Frame: 367…-1
0: STDOUT: Processing Frame: 368…-1
0: STDOUT: Processing Frame: 369…-1
0: STDOUT: Processing Frame: 370…-1
0: STDOUT: Traceback (most recent call last):
0: STDOUT: File “R:\simple_slate_h264_MJPEG_burnins.py”, line 280, in
0: STDOUT: MJPEGencoder.EncodeNextFrame( bgFrame )
0: STDOUT: RuntimeError: Error while writing video frame
0: STDOUT: Output #0, mov, to ‘R:\IA\PLATES\007\0001\prp\outputs\full_rez\Draft/1080p/IA_007_0001_prp_all_dst.l. (2).mov’:
0: STDOUT: Metadata:
0: STDOUT: encoder : Lavf53.32.100
0: STDOUT: Stream #0:0: Video: mjpeg (jpeg / 0x6765706A), yuvj420p, 1920x1080, q=2-31, 75000 kb/s, 24 tbn, 24 tbc
0: STDOUT: Output #0, mov, to ‘R:\IA\PLATES\007\0001\prp\outputs\full_rez\Draft/halfrez/IA_007_0001_prp_all_dst.l.-Hres (2).mov’:
0: STDOUT: Metadata:
0: STDOUT: encoder : Lavf53.32.100
0: STDOUT: Stream #0:0: Video: mjpeg (jpeg / 0x6765706A), yuvj420p, 2560x1350, q=2-31, 325000 kb/s, 24 tbn, 24 tbc
0: INFO: Process exit code: 1
0: An exception occurred: Exception during render: An error occurred in RenderTasks(): Error in CheckExitCode(): Renderer returned non-zero error code, 1. Check the log for more information.
à Deadline.Plugins.ScriptPlugin.RenderTasks(String taskId, Int32 startFrame, Int32 endFrame, String& outMessage) (Deadline.Plugins.RenderPluginException)

=======================================================
Error Type

RenderPluginException

=======================================================
Error Stack Trace

à Deadline.Plugins.Plugin.RenderTask(String taskId, Int32 startFrame, Int32 endFrame)
à Deadline.Slaves.SlaveRenderThread.RenderCurrentTask(TaskLogWriter tlw)
[/code]

Hey Fred,

Sorry it took me a while to get back to this issue, I completely missed your response. I’m pretty much out of ideas as to why certain Draft jobs would get submitted, and some wouldn’t. And all ‘Draft’ plugin entries in your Job logs end with ‘Submitting Draft job to Deadline…’, and nothing else? I would definitely check a few more, just to be sure.

I don’t think the Job names should be an issue at all, since it worked for the original job, and Draft should just be appending to it. Have you noticed any kind of pattern in the ones that aren’t getting submitted? Are they all failed jobs? Have they all been completed by the same Slave?

And actually, saying that, I now wonder if it’s because some of the Slaves aren’t logged in as a Deadline user. Another client of ours had encountered something similar that was preventing jobs from being submitted.

Try adding the following line to your event plugin (events/Draft/Draft.py in your repo):

fileHandle.write( "UserName=%s\n" % job.UserName ) 

It would go in the the area where it’s building the Job Info file, say, right under the Department line:

...
fileHandle.write( "ChunkSize=1\n" )
fileHandle.write( "MachineLimit=1\n" )
fileHandle.write( "Department=%s\n" % job.Department )
fileHandle.write( "UserName=%s\n" % job.UserName ) 
...

As for the script, I wasn’t able to quite replicate the issues you were getting, but I was definitely issues of my own with it. I’ll get back to you on that one!

Cheers,

  • Jon

Update on the script side of things: I sorted out the issue I was having – I forgot you were applying a LUT and it would repeatedly apply it to previous frames, which was really mucking things up. There was also a similar issue with the annotations. I did not run into any actual errors, though. Have you tried with the latest version of Draft that Paul just posted? That is the version I was testing with.

Anywho, here’s an updated version that fixes the issues I ran into:

[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’] )

if(True):
(outDir, outFile) = os.path.split(params[‘outFile’])
(outBase, outExt) = os.path.splitext(outFile)

outFolder = os.path.basename(outDir)

if not os.path.exists(os.path.join(outDir, '1080p')):
	os.makedirs(os.path.join(outDir, '1080p'))
if not os.path.exists(os.path.join(outDir, 'halfrez')):
	os.makedirs(os.path.join(outDir, 'halfrez'))
if not os.path.exists(os.path.join(outDir, 'fullrez')):
	os.makedirs(os.path.join(outDir, 'fullrez'))

else:
(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
fullWidth = 5120
fullHeight = 2700
halfWidth = 2560
halfHeight = 1350
slateFrames = 1
outLut = Draft.LUT.CreateRec709()

for eye in [‘l’,‘r’]:
#Build up the encoders
outBaseEye = outBase.replace( ‘%v’, eye )
outBaseEyeHalf = outBase.replace( ‘%v’, eye ) + “-Hres”
outBaseEyeFull = outBase.replace( ‘%v’, eye ) + “-Fres”

#Appends (#) on the end of the filename until we have a unique name
increment = 2
newFileName = '%s/1080p/%s%s'%(outDir, outBaseEye, outExt)
while os.path.exists( newFileName ):
	newFileName = '%s/1080p/%s (%d)%s'%(outDir, outBaseEye, increment, outExt)
	#newFileName = "%s (%d)%s" % (outBaseEye, increment, outExt)
	increment += 1

#Appends (#) on the end of the filename until we have a unique name
increment = 2
newFileNameHalf = '%s/halfrez/%s%s'%(outDir, outBaseEyeHalf, outExt)
while os.path.exists( newFileNameHalf ):
	newFileNameHalf = '%s/halfrez/%s (%d)%s'%(outDir, outBaseEyeHalf, increment, outExt)
	#newFileNameHalf = "%s (%d)%s" % (outBaseEyeHalf, increment, outExt)
	increment += 1

#Appends (#) on the end of the filename until we have a unique name
#increment = 2
#newFileNameFull = '%s/fullrez/%s%s'%(outDir, outBaseEyeFull, outExt)
#while os.path.exists( newFileNameFull ):
	#newFileNameFull = '%s/fullrez/%s (%d)%s'%(outDir, outBaseEyeFull, increment, outExt)
	#newFileNameFull = "%s (%d)%s" % (outBaseEyeFull, increment, outExt)
	#increment += 1   

MJPEGencoder = Draft.VideoEncoder( newFileName, 24.0, outWidth, outHeight, 75000, "MJPEG" )
MJPEGencoderHRes = Draft.VideoEncoder( newFileNameHalf, 24.0, halfWidth, halfHeight, 325000, "MJPEG" )
#MJPEGencoderFRes = Draft.VideoEncoder( newFileNameFull, 24.0, fullWidth, fullHeight, 350000, "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 )

outLut.Apply( slate )

#encode the slate frames at the start of the video
print( "Encoding Slate Frames..." )
for i in range( 0, slateFrames ):
	MJPEGencoder.EncodeNextFrame( slate )
	MJPEGencoderHRes.EncodeNextFrame( slate )
	#MJPEGencoderFRes.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 )

#initialize the frame to None
bgFrame = None

#Main encoding loop
for frameNumber in frames:
	print( "Processing Frame: %d...-1" % frameNumber )

	inFile = inFilePattern.replace( '%v', eye )
	inFile = ReplaceFilenameHashesWithNumber( inFile, frameNumber )

	#check if the file exists
	prevFrame = ( not os.path.exists( inFile ) )

	if not prevFrame:
		try:
			#try to read in the frame
			bgFrame = Draft.Image.ReadFromFile( inFile )
		except:
			#failed to read in, that's OK, we'll just re-encode the previous frame
			pass

	#create a black frame if we couldn't read in, and don't have a previous frame to encode
	if bgFrame == None:
		bgFrame = Draft.Image.CreateImage( outWidth, outHeight )
		bgFrame.SetToColor( Draft.ColorRGBA( 0.0, 1.0, 0.0, 1.0 ) )
	elif ( bgFrame.width != outWidth or bgFrame.height != outHeight ):
		bgFrame.ResizeWithLetterbox( outWidth, outHeight )

	#Do the frame burnins
	framesAnnotation = Draft.Image.CreateAnnotation( str( frameNumber ), annotationInfo )
	bgFrame.CompositeWithPositionAndGravity( framesAnnotation, 0.5, 0.0, Draft.PositionalGravity.SouthEastGravity, Draft.CompositeOperator.OverCompositeOp )
	
	#don't redo the other burnins, or the LUT since we've already done it for the last frame
	if not prevFrame:
		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 )

		outLut.Apply( bgFrame )

	MJPEGencoder.EncodeNextFrame( bgFrame )
	MJPEGencoderHRes.EncodeNextFrame( bgFrame )
	#MJPEGencoderFRes.EncodeNextFrame( bgFrame )

#Finalize the encoding process
MJPEGencoder.FinalizeEncoding()
MJPEGencoderHRes.FinalizeEncoding()
#MJPEGencoderFRes.FinalizeEncoding()[/code]

I got new error with draft since the update. But i don’t know if it’s reliate to the new version or the new script:

[code]=======================================================
Error Message

Exception during render: An error occurred in RenderTasks(): Error in CheckExitCode(): Renderer returned non-zero error code, 1. Check the log for more information.
à Deadline.Plugins.ScriptPlugin.RenderTasks(String taskId, Int32 startFrame, Int32 endFrame, String& outMessage)

=======================================================
Slave Log

0: Loaded plugin: Draft
0: Task timeout is disabled.
0: Loaded job: IA_005_0001_lgtCmp_preCmp.nk [DRAFT] (002_060_00a_6f168144)
0: Successfully mapped R: to \FX-NAS-01\vfx\RENDER
0: Successfully mapped K: to \FX-NAS-01\vfx\Projets
0: INFO: StartJob: initializing script plugin Draft
0: INFO: Found Draft python module at: ‘C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Draft_node_2\Draft\Draft.pyd’
0: INFO: About: Draft Plugin for Deadline
0: Plugin rendering frame(s): 0
0: INFO: Draft job starting…
0: INFO: Stdout Handling Enabled: False
0: INFO: Popup Handling Enabled: False
0: INFO: Using Process Tree: True
0: INFO: Hiding DOS Window: True
0: INFO: Creating New Console: False
0: INFO: Looking for bundled python at: ‘C:\Program Files\Thinkbox\Deadline\python\2.6.7\x64\python.exe’
0: INFO: Render Executable: “C:\Program Files\Thinkbox\Deadline\python\2.6.7\x64\python.exe”
0: INFO: Render Argument: -u “C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Draft_node_2\jobsData\simple_slate_h264_MJPEG_burnins.py” username=“Frima FX” entity=“Motion_blur” version="" width=5120 height=2700 frameList=43,53,63,73,83,93,103,113,123,133,143,153,163,173,183,193,203,213,223,233,243,253,263,273,283,293 startFrame=43 endFrame=293 inFile="\fx-nas-01\vfx\RENDER\IA\SHOTS\005\0001\lts\lgtCmp\preCmp\v01\IA_005_0001_lts_preCmp.v01.%v.####.exr" outFile="\fx-nas-01\vfx\RENDER\IA\SHOTS\005\0001\lts\lgtCmp\preCmp\v01\Draft\IA_005_0001_lts_preCmp.v01.%v.mov" deadlineJobID=000_060_999_739ac6c6
0: INFO: Startup Directory: “C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Draft_node_2\Draft”
0: INFO: Process Priority: BelowNormal
0: INFO: Process is now running
0: STDOUT: Checking for license at @prodflexmr
0: STDOUT: Draft Beta 0.11.0.47662
0: STDOUT: Draft Version: 0.11.0.47662
0: STDOUT: Command line args:
0: STDOUT: username=Frima FX
0: STDOUT: entity=Motion_blur
0: STDOUT: version=
0: STDOUT: width=5120
0: STDOUT: height=2700
0: STDOUT: frameList=43,53,63,73,83,93,103,113,123,133,143,153,163,173,183,193,203,213,223,233,243,253,263,273,283,293
0: STDOUT: startFrame=43
0: STDOUT: endFrame=293
0: STDOUT: inFile=\fx-nas-01\vfx\RENDER\IA\SHOTS\005\0001\lts\lgtCmp\preCmp\v01\IA_005_0001_lts_preCmp.v01.%v.####.exr
0: STDOUT: outFile=\fx-nas-01\vfx\RENDER\IA\SHOTS\005\0001\lts\lgtCmp\preCmp\v01\Draft\IA_005_0001_lts_preCmp.v01.%v.mov
0: STDOUT: deadlineJobID=000_060_999_739ac6c6
0: STDOUT: ERROR: Frame Range token ‘43’ is malformed. Skipping this token.
0: STDOUT: Traceback (most recent call last):
0: STDOUT: File “C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Draft_node_2\jobsData\simple_slate_h264_MJPEG_burnins.py”, line 116, in
0: STDOUT: frames = FrameListToFrames( params[‘frameList’] )
0: STDOUT: File “C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Draft_node_2\jobsData\simple_slate_h264_MJPEG_burnins.py”, line 63, in FrameListToFrames
0: STDOUT: frames.add( startFrame )
0: STDOUT: AttributeError: ‘list’ object has no attribute ‘add’
0: INFO: Process exit code: 1
0: An exception occurred: Exception during render: An error occurred in RenderTasks(): Error in CheckExitCode(): Renderer returned non-zero error code, 1. Check the log for more information.
à Deadline.Plugins.ScriptPlugin.RenderTasks(String taskId, Int32 startFrame, Int32 endFrame, String& outMessage) (Deadline.Plugins.RenderPluginException)

=======================================================
Error Type

RenderPluginException

=======================================================
Error Stack Trace

à Deadline.Plugins.Plugin.RenderTask(String taskId, Int32 startFrame, Int32 endFrame)
à Deadline.Slaves.SlaveRenderThread.RenderCurrentTask(TaskLogWriter tlw)
[/code]

Thks

Fred

Could you please post a copy of your simple_slate_h264_MJPEG_burnins.py script as an attachment?

Hey Fred,

This should be a simple fix. Open up your draft script and replace ‘frames.add( startFrame )’ with ‘frames.append( startFrame )’. Should be at line 63 in the file.

Cheers,

  • Jon

sweet thanks,

i’ll come back with the result

Another thing,

heres my template

[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.append( 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’] )

if(True):
(outDir, outFile) = os.path.split(params[‘outFile’])
(outBase, outExt) = os.path.splitext(outFile)

outFolder = os.path.basename(outDir)

if not os.path.exists(os.path.join(outDir, ‘1080p’)):
os.makedirs(os.path.join(outDir, ‘1080p’))
if not os.path.exists(os.path.join(outDir, ‘halfrez’)):
os.makedirs(os.path.join(outDir, ‘halfrez’))
if not os.path.exists(os.path.join(outDir, ‘fullrez’)):
os.makedirs(os.path.join(outDir, ‘fullrez’))

else:
(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
fullWidth = 5120
fullHeight = 2700
halfWidth = 2560
halfHeight = 1350
slateFrames = 1
outLut = Draft.LUT.CreateRec709()

for eye in [‘l’,‘r’]:
#Build up the encoders
outBaseEye = outBase.replace( ‘%v’, eye )
outBaseEyeHalf = outBase.replace( ‘%v’, eye ) + “-Hres”
outBaseEyeFull = outBase.replace( ‘%v’, eye ) + “-Fres”

#Appends (#) on the end of the filename until we have a unique name
increment = 2
newFileName = ‘%s/1080p/%s%s’%(outDir, outBaseEye, outExt)
while os.path.exists( newFileName ):
newFileName = ‘%s/1080p/%s (%d)%s’%(outDir, outBaseEye, increment, outExt)
#newFileName = “%s (%d)%s” % (outBaseEye, increment, outExt)
increment += 1

#Appends (#) on the end of the filename until we have a unique name
increment = 2
newFileNameHalf = ‘%s/halfrez/%s%s’%(outDir, outBaseEyeHalf, outExt)
while os.path.exists( newFileNameHalf ):
newFileNameHalf = ‘%s/halfrez/%s (%d)%s’%(outDir, outBaseEyeHalf, increment, outExt)
#newFileNameHalf = “%s (%d)%s” % (outBaseEyeHalf, increment, outExt)
increment += 1

#Appends (#) on the end of the filename until we have a unique name
#increment = 2
#newFileNameFull = ‘%s/fullrez/%s%s’%(outDir, outBaseEyeFull, outExt)
#while os.path.exists( newFileNameFull ):
#newFileNameFull = ‘%s/fullrez/%s (%d)%s’%(outDir, outBaseEyeFull, increment, outExt)
#newFileNameFull = “%s (%d)%s” % (outBaseEyeFull, increment, outExt)
#increment += 1

MJPEGencoder = Draft.VideoEncoder( newFileName, 24.0, outWidth, outHeight, 75000, “MJPEG” )
MJPEGencoderHRes = Draft.VideoEncoder( newFileNameHalf, 24.0, halfWidth, halfHeight, 325000, “MJPEG” )
#MJPEGencoderFRes = Draft.VideoEncoder( newFileNameFull, 24.0, fullWidth, fullHeight, 350000, “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’, ‘’)), #This line is skipped if there is not ExtraInfo1
(“Episode”, params.get(‘episode’, ‘’)), #This line is skipped if ‘episode’ isn’t in the extra args
(“Shot”, params[‘entity’]),
(“Frames”, params[‘frameList’]),
(“Handles”, params.get(‘handles’, ‘’)), #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 )

outLut.Apply( slate )

#encode the slate frames at the start of the video
print( “Encoding Slate Frames…” )
for i in range( 0, slateFrames ):
MJPEGencoder.EncodeNextFrame( slate )
MJPEGencoderHRes.EncodeNextFrame( slate )
#MJPEGencoderFRes.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 )

#initialize the frame to None
bgFrame = None

#Main encoding loop
for frameNumber in frames:
print( “Processing Frame: %d…-1” % frameNumber )

  inFile = inFilePattern.replace( '%v', eye )
  inFile = ReplaceFilenameHashesWithNumber( inFile, frameNumber )

  #check if the file exists
  prevFrame = ( not os.path.exists( inFile ) )

  if not prevFrame:
     try:
        #try to read in the frame
        bgFrame = Draft.Image.ReadFromFile( inFile )
     except:
        #failed to read in, that's OK, we'll just re-encode the previous frame
        pass

  #create a black frame if we couldn't read in, and don't have a previous frame to encode
  if bgFrame == None:
     bgFrame = Draft.Image.CreateImage( outWidth, outHeight )
     bgFrame.SetToColor( Draft.ColorRGBA( 0.0, 1.0, 0.0, 1.0 ) )
  elif ( bgFrame.width != outWidth or bgFrame.height != outHeight ):
     bgFrame.ResizeWithLetterbox( outWidth, outHeight )

  #Do the frame burnins
  framesAnnotation = Draft.Image.CreateAnnotation( str( frameNumber ), annotationInfo )
  bgFrame.CompositeWithPositionAndGravity( framesAnnotation, 0.5, 0.0, Draft.PositionalGravity.SouthEastGravity, Draft.CompositeOperator.OverCompositeOp )
  
  #don't redo the other burnins, or the LUT since we've already done it for the last frame
  if not prevFrame:
     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 )

     outLut.Apply( bgFrame )

  MJPEGencoder.EncodeNextFrame( bgFrame )
  MJPEGencoderHRes.EncodeNextFrame( bgFrame )
  #MJPEGencoderFRes.EncodeNextFrame( bgFrame )

#Finalize the encoding process
MJPEGencoder.FinalizeEncoding()
MJPEGencoderHRes.FinalizeEncoding()
#MJPEGencoderFRes.FinalizeEncoding()[/code]

so far, everything goes well, but i wanna try making some movie trough the draft submitter. I always get this error

[code]=======================================================
Error Message

Exception during render: An error occurred in RenderTasks(): Error in CheckExitCode(): Renderer returned non-zero error code, 1. Check the log for more information.
à Deadline.Plugins.ScriptPlugin.RenderTasks(String taskId, Int32 startFrame, Int32 endFrame, String& outMessage)

=======================================================
Slave Log

0: Loaded plugin: Draft
0: Task timeout is disabled.
0: Loaded job: Test Draft (002_055_00a_194e8254)
0: Successfully mapped R: to \FX-NAS-01\vfx\RENDER
0: Successfully mapped K: to \FX-NAS-01\vfx\Projets
0: INFO: StartJob: initializing script plugin Draft
0: INFO: Found Draft python module at: ‘C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Draft_node\Draft\Draft.pyd’
0: INFO: About: Draft Plugin for Deadline
0: Plugin rendering frame(s): 0
0: INFO: Draft job starting…
0: INFO: Stdout Handling Enabled: False
0: INFO: Popup Handling Enabled: False
0: INFO: Using Process Tree: True
0: INFO: Hiding DOS Window: True
0: INFO: Creating New Console: False
0: INFO: Looking for bundled python at: ‘C:\Program Files\Thinkbox\Deadline\python\2.6.7\x64\python.exe’
0: INFO: Render Executable: “C:\Program Files\Thinkbox\Deadline\python\2.6.7\x64\python.exe”
0: INFO: Render Argument: -u “R:\simple_slate_h264_MJPEG_burnins.py” username="" entity="" version="" startFrame=1 endFrame=300 frameList=1-300 outFile=“R:\IA\SHOTS\011\0001b\comp\output\layer_all_v07\Draft\IA_011_0001b_layer_all_v07.l…mov” inFile=“R:\IA\SHOTS\011\0001b\comp\output\layer_all_v07\IA_011_0001b_layer_all_v07.l.####.exr”
0: INFO: Startup Directory: “C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Draft_node\Draft”
0: INFO: Process Priority: BelowNormal
0: INFO: Process is now running
0: STDOUT: Checking for license at @prodflexmr
0: STDOUT: Draft Beta 0.11.0.47662
0: STDOUT: Draft Version: 0.11.0.47662
0: STDOUT: Command line args:
0: STDOUT: username=
0: STDOUT: entity=
0: STDOUT: version=
0: STDOUT: startFrame=1
0: STDOUT: endFrame=300
0: STDOUT: frameList=1-300
0: STDOUT: outFile=R:\IA\SHOTS\011\0001b\comp\output\layer_all_v07\Draft\IA_011_0001b_layer_all_v07.l…mov
0: STDOUT: inFile=R:\IA\SHOTS\011\0001b\comp\output\layer_all_v07\IA_011_0001b_layer_all_v07.l.####.exr
0: STDOUT: Traceback (most recent call last):
0: STDOUT: File “R:\simple_slate_h264_MJPEG_burnins.py”, line 113, in
0: STDOUT: params = ParseCommandLine( expectedTypes, sys.argv )
0: STDOUT: File “C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Draft_node\Draft\DraftParamParser.py”, line 196, in ParseCommandLine
0: STDOUT: return ParseParams( expected, params )
0: STDOUT: File “C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Draft_node\Draft\DraftParamParser.py”, line 119, in ParseParams
0: STDOUT: raise StandardError( “ERROR: Expected parameter ‘%s’ was not found.” % key )
0: STDOUT: StandardError: ERROR: Expected parameter ‘deadlineJobID’ was not found.
0: INFO: Process exit code: 1
0: An exception occurred: Exception during render: An error occurred in RenderTasks(): Error in CheckExitCode(): Renderer returned non-zero error code, 1. Check the log for more information.
à Deadline.Plugins.ScriptPlugin.RenderTasks(String taskId, Int32 startFrame, Int32 endFrame, String& outMessage) (Deadline.Plugins.RenderPluginException)

=======================================================
Error Type

RenderPluginException

=======================================================
Error Stack Trace

à Deadline.Plugins.Plugin.RenderTask(String taskId, Int32 startFrame, Int32 endFrame)
à Deadline.Slaves.SlaveRenderThread.RenderCurrentTask(TaskLogWriter tlw)
[/code]

I think it is searchin for the right eye. Is there any chance to tell the template to, if theres is no right eye, ignore the %v ?

thks !

Fred

Also, is there any way i could in the draft submitter put multiple in/output ?

So that error comes up because that template is trying to pull information from the original job. This is only really used in that script for Shotgun. If you’re not using Shotgun you could just take out the lines that use the deadlineJobID parameter, see script below.

[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.append( 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’] )

if(True):
(outDir, outFile) = os.path.split(params[‘outFile’])
(outBase, outExt) = os.path.splitext(outFile)

outFolder = os.path.basename(outDir)

if not os.path.exists(os.path.join(outDir, ‘1080p’)):
os.makedirs(os.path.join(outDir, ‘1080p’))
if not os.path.exists(os.path.join(outDir, ‘halfrez’)):
os.makedirs(os.path.join(outDir, ‘halfrez’))
if not os.path.exists(os.path.join(outDir, ‘fullrez’)):
os.makedirs(os.path.join(outDir, ‘fullrez’))

else:
(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
fullWidth = 5120
fullHeight = 2700
halfWidth = 2560
halfHeight = 1350
slateFrames = 1
outLut = Draft.LUT.CreateRec709()

for eye in [‘l’,‘r’]:
#Build up the encoders
outBaseEye = outBase.replace( ‘%v’, eye )
outBaseEyeHalf = outBase.replace( ‘%v’, eye ) + “-Hres”
outBaseEyeFull = outBase.replace( ‘%v’, eye ) + “-Fres”

#Appends (#) on the end of the filename until we have a unique name
increment = 2
newFileName = ‘%s/1080p/%s%s’%(outDir, outBaseEye, outExt)
while os.path.exists( newFileName ):
newFileName = ‘%s/1080p/%s (%d)%s’%(outDir, outBaseEye, increment, outExt)
#newFileName = “%s (%d)%s” % (outBaseEye, increment, outExt)
increment += 1

#Appends (#) on the end of the filename until we have a unique name
increment = 2
newFileNameHalf = ‘%s/halfrez/%s%s’%(outDir, outBaseEyeHalf, outExt)
while os.path.exists( newFileNameHalf ):
newFileNameHalf = ‘%s/halfrez/%s (%d)%s’%(outDir, outBaseEyeHalf, increment, outExt)
#newFileNameHalf = “%s (%d)%s” % (outBaseEyeHalf, increment, outExt)
increment += 1

#Appends (#) on the end of the filename until we have a unique name
#increment = 2
#newFileNameFull = ‘%s/fullrez/%s%s’%(outDir, outBaseEyeFull, outExt)
#while os.path.exists( newFileNameFull ):
#newFileNameFull = ‘%s/fullrez/%s (%d)%s’%(outDir, outBaseEyeFull, increment, outExt)
#newFileNameFull = “%s (%d)%s” % (outBaseEyeFull, increment, outExt)
#increment += 1

MJPEGencoder = Draft.VideoEncoder( newFileName, 24.0, outWidth, outHeight, 75000, “MJPEG” )
MJPEGencoderHRes = Draft.VideoEncoder( newFileNameHalf, 24.0, halfWidth, halfHeight, 325000, “MJPEG” )
#MJPEGencoderFRes = Draft.VideoEncoder( newFileNameFull, 24.0, fullWidth, fullHeight, 350000, “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’, ‘’)), #This line is skipped if there is not ExtraInfo1
(“Episode”, params.get(‘episode’, ‘’)), #This line is skipped if ‘episode’ isn’t in the extra args
(“Shot”, params[‘entity’]),
(“Frames”, params[‘frameList’]),
(“Handles”, params.get(‘handles’, ‘’)), #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 )

outLut.Apply( slate )

#encode the slate frames at the start of the video
print( “Encoding Slate Frames…” )
for i in range( 0, slateFrames ):
MJPEGencoder.EncodeNextFrame( slate )
MJPEGencoderHRes.EncodeNextFrame( slate )
#MJPEGencoderFRes.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 )

#initialize the frame to None
bgFrame = None

#Main encoding loop
for frameNumber in frames:
print( “Processing Frame: %d…-1” % frameNumber )

  inFile = inFilePattern.replace( '%v', eye )
  inFile = ReplaceFilenameHashesWithNumber( inFile, frameNumber )

  #check if the file exists
  prevFrame = ( not os.path.exists( inFile ) )

  if not prevFrame:
     try:
        #try to read in the frame
        bgFrame = Draft.Image.ReadFromFile( inFile )
     except:
        #failed to read in, that's OK, we'll just re-encode the previous frame
        pass

  #create a black frame if we couldn't read in, and don't have a previous frame to encode
  if bgFrame == None:
     bgFrame = Draft.Image.CreateImage( outWidth, outHeight )
     bgFrame.SetToColor( Draft.ColorRGBA( 0.0, 1.0, 0.0, 1.0 ) )
  elif ( bgFrame.width != outWidth or bgFrame.height != outHeight ):
     bgFrame.ResizeWithLetterbox( outWidth, outHeight )

  #Do the frame burnins
  framesAnnotation = Draft.Image.CreateAnnotation( str( frameNumber ), annotationInfo )
  bgFrame.CompositeWithPositionAndGravity( framesAnnotation, 0.5, 0.0, Draft.PositionalGravity.SouthEastGravity, Draft.CompositeOperator.OverCompositeOp )
  
  #don't redo the other burnins, or the LUT since we've already done it for the last frame
  if not prevFrame:
     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 )

     outLut.Apply( bgFrame )

  MJPEGencoder.EncodeNextFrame( bgFrame )
  MJPEGencoderHRes.EncodeNextFrame( bgFrame )
  #MJPEGencoderFRes.EncodeNextFrame( bgFrame )

#Finalize the encoding process
MJPEGencoder.FinalizeEncoding()
MJPEGencoderHRes.FinalizeEncoding()
#MJPEGencoderFRes.FinalizeEncoding()[/code]

As for the multiple input/output, that’s not something we had planned for, really. If you’re submitting Draft jobs through the Event plugin, it should generate one job per output (so one input per Draft job). That’s pretty much how we generally expect it to work, and it’s the way we built all of our templates/submitters. You could do some heavy modifications of the submitter to get the multi input submission to work, but that would require a bunch of scripting legwork on your end.

Cheers,

  • Jon

Seem to work well ! I’ll try to find a way to optimize my pipeline with your latest comment.

Thks

Fred

I might have a demande to add on the wish list.

When submitting manually a draft, the output path is not automaticly detect. So i cannot go on my job and do ctrl-O to go see the output.

Could you implant this you think,

Thks !

I’ve attached an updated version of the submitter (and right-click submitter) that correctly sets the Output Path in Deadline, so it should work with ‘Explore Output Folder’. The appropriate path for each script is in the file comments

Cheers,

Thanks !!

Hi, i got some update on my problem.

I don’t know if the name of the file could be related to the problem.

Sometime, when the draft file doesn’t get submitted, i saw the the job name is IA_011.0004.lts.cMammoth.render.nk instead of IA_011_0004_lts_cMammoth_render.nk

Could that be the problem ?

Thks

Fred

Another thing,

I realise that deadline dosen’t render my right eye through Rib render. I don’t know if the problem is correlated.

I have seen in the ribs that the other display have a +r:/ to start the path. Instead of only r:/. I don’t know if this is the problem or not.

Thks

Fred

Privacy | Site terms | Cookie preferences