AWS Thinkbox Discussion Forums

Include sound in Draft movie?

Hello Everyone

I’m facing a problem right now while trying to create Quicktime blast with sound. If I let the basic setup (movie start at frame 1 and sound start at frame 1), there’s no problem, everything’s fine. But if I have to set the audioDelay parameter in the Draft.VideoEncoder() function, sound and/or images are always wrongly offsetted.

I’m develloping a tool right now to help our animators doing Quicktime playblasts on our render farm using Draft. I added the sound option recently so they now can hear it in the movie to tweak their facial animation. Everything worked fine till an animator tried to launch a blast from maya, with framerange going from 375 to 540, with a sound file covering frames from 1 to ~4500. I understand I have to offset the Draft.VideoEncoder() audioDelay parameter with a value of -375. But when I do that, sound and images are not in sync, and the last frames of the movie are blank white, with sound. In fact, sound begin just after the end of the images.

Anybody have an idea what I’m doing wrong?

The line defining my VideoEncoder goes like this.

MJPEGencoder = Draft.VideoEncoder(BLAST.outFilename, 24.0, BLAST.outWidth, BLAST.outHeight, 75000, "MJPEG", BLAST.params['audioFilename'], BLAST.params['audioDelay']+BLAST.slateFrames-BLAST.params['startFrame'])

BLAST being a custom class object doing pretty much what slate script example provided by Thinkbox was doing.

Thanks
Maxime

What audio file format are you using? Draft’s audio support works best with WAV files, and other uncompressed formats.

Hi Paul.

I use a WAV file. Like I said, I rendered a frame sequence in Maya going from 375 to 540. The WAV file used for facial animation goes from 1 to 4560, with blank from 1 to 375 approximately. So my script copy frames and sound file in a temporary directory on our server, reachable by our render farm. I create a plugin_info file and a job_info file with all paremeters correctly defined.

When Draft start to encode, I set the Draft.VideoEncoder() audioDelay param to -375 (also tried +375). The Quicktime I get is my frames with no sound, from 375 to 540 (about 7 seconds), and the sound seems to start at 541 for another 14 seconds, with white frames as video.

Maxime

Alright! I wonder if you are using an older version of Draft? We improved audio support in Beta 13.

In newer versions of Draft, you can find the version number in the Draft job’s log report. To find this, open the Deadline Monitor, and find a Draft job. Right-click the job, and choose Job Reports -> View Log Report… Around 25 lines into the report, you should see some STDOUT lines similar to:0: STDOUT: Checking for license at @license-server 0: STDOUT: Draft 1.0.0.49258
the second line here is your Draft version number. We described a couple other ways to find your version number here: http://forums.thinkboxsoftware.com/viewtopic.php?f=126&t=8683&p=36577

Could you please check and let us know what version of Draft you’re using?

0: STDOUT: Draft Beta 0.11.0.47662
0: STDOUT: Draft Version: 0.11.0.47662

Thanks

Looks like you’re using beta 11… if you upgrade to a more recent version, do you have the same problem? Here’s a link to Draft RC3 (version 1.0.0): http://forums.thinkboxsoftware.com/viewtopic.php?f=125&t=8551

Cheers,
Andrea

Hi Andrea,

We tried to install Draft RC3 on our farm, but before I could try to see if our audio problem was resolved, we noticed that every Draft movies generated since then were black framed. Only a little stripe in the bottom was showing the expected movie, but in fast forward. So we installed back our old version. I don’t know if we have to modify something in our slate script. Just below is the code of our slate script who have the bug mentionned.

Thanks a lot.

[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 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|i)(\d+))?", token[dashIndex + 1:] )
                if ( m == None ) :
                    raise StandardError( "Second part of Token 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 (frame * dir) <= (endFrame * dir):
                            frames.append( 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_new.png”
logoFrame = “\\fx-deadline\deadline\Draft\FrimaFX.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’] = ‘’
expectedTypes[‘startFrame’] = ‘’
expectedTypes[‘endFrame’] = ‘’

#Parse the command line arguments
params = ParseCommandLine( expectedTypes, sys.argv )

inFilePattern = params[‘inFile’]
params[‘frameList’] = “%d-%d” % (params[‘startFrame’], params[‘endFrame’])
frames = range( params[‘startFrame’], params[‘endFrame’] + 1 )
#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’])

outWidth = 1920
outHeight = 1080
#halfWidth = 2560
#halfHeight = 1350
slateFrames = 1
outLut = Draft.LUT.CreateRec709()

for eye in [‘l’,‘r’]:
#Build up the encoders
doOutSingleEye = False
if not ‘%v’ in outBase:
doOutSingleEye = True

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)
	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)
#	increment += 1

MJPEGencoder = Draft.VideoEncoder( newFileName, 24.0, outWidth, outHeight, 75000, "MJPEG" )
# MJPEGencoderHRes = Draft.VideoEncoder( newFileNameHalf, 24.0, halfWidth, halfHeight, 325000, "MJPEG" )

#Annotation info used for burn ins
annotationInfo = Draft.AnnotationInfo()
annotationInfo.FontType = "Arial"
annotationInfo.PointSize = int( outHeight * 0.017 )
annotationInfo.Color = Draft.ColorRGBA( 1.0, 1.0, 1.0, 1.0 )

#Annotation info used for burn ins
annotationInfoBig = Draft.AnnotationInfo()
annotationInfoBig.FontType = "Arial"
annotationInfoBig.PointSize = int( outHeight * 0.02 )
annotationInfoBig.Color = Draft.ColorRGBA( 1.0, 1.0, 1.0, 1.0 )

#Annotation info used for burn ins
annotationInfoFrame = Draft.AnnotationInfo()
annotationInfoFrame.FontType = "Arial"
annotationInfoFrame.PointSize = int( outHeight * 0.025 )
annotationInfoFrame.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 = [params['entity'], params['version'], params['username'], datetime.datetime.now().strftime("%m/%d/%Y %I:%M %p"), params['frameList']]

for i in range (0, 4):
	annotation = Draft.Image.CreateAnnotation(slateAnnotations[i], annotationInfo)
	slate.CompositeWithPositionAndGravity(annotation, 0.23, 0.446 - (i * 0.03), Draft.PositionalGravity.NorthWestGravity, Draft.CompositeOperator.OverCompositeOp)

annotation = Draft.Image.CreateAnnotation(slateAnnotations[4], annotationInfo)
slate.CompositeWithPositionAndGravity(annotation, 0.327, 0.24, Draft.PositionalGravity.SouthGravity, Draft.CompositeOperator.OverCompositeOp)

oFrameRangeSplit = slateAnnotations[4].split('-')
oFrameCount = str(int(oFrameRangeSplit[1]) - int(oFrameRangeSplit[0]) + 1)
annotation = Draft.Image.CreateAnnotation(oFrameCount, annotationInfoBig)
slate.CompositeWithPositionAndGravity(annotation, 0.251, 0.237, Draft.PositionalGravity.SouthGravity, 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 )
	#MJPEGencoderHRes.EncodeNextFrame( slate )

studioAnnotation = Draft.Image.CreateAnnotation( "PROJECT", annotationInfo )
entityAnnotation = Draft.Image.CreateAnnotation( "%s    %s" % (params['entity'], datetime.datetime.now().strftime("%m/%d/%Y")), annotationInfo )
dateAnnotation = Draft.Image.CreateAnnotation( datetime.datetime.now().strftime("%m/%d/%Y"), annotationInfo )
shotAnnotation = Draft.Image.CreateAnnotation(params['entity'], annotationInfo)

try:
	logo = Draft.Image.ReadFromFile( logoFrame )
	logo.Resize(int(0.1852*outHeight), int(0.0657*outHeight))
except:
	logo = Draft.Image.CreateImage( outWidth, outHeight )
	logo.SetToColor( Draft.ColorRGBA( 0.0, 0.0, 0.0, 1.0 ) )

#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 )

	if os.path.exists( inFile ):
		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, 0.0, 0.0, 1.0 ) )
	elif ( bgFrame.width != outWidth or bgFrame.height != outHeight ):
		bgFrame.ResizeWithLetterbox( outWidth, outHeight )

	#Do the frame burnins
	burned = Draft.Image.CreateImage( outWidth, outHeight )
	bgFrame.SetChannel('A', 1.0)
	burned.Composite(bgFrame, 0, 0, Draft.CompositeOperator.OverCompositeOp)
	framesAnnotation = Draft.Image.CreateAnnotation( str( frameNumber ), annotationInfoFrame )
	burned.CompositeWithPositionAndGravity( framesAnnotation, 0.825, 0.062, 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 os.path.exists( inFile ):
	burned.CompositeWithPositionAndGravity( studioAnnotation, 0.0, 1.0, Draft.PositionalGravity.NorthWestGravity, Draft.CompositeOperator.OverCompositeOp )
	burned.CompositeWithPositionAndGravity( dateAnnotation, 0.0, 0.0, Draft.PositionalGravity.SouthWestGravity, Draft.CompositeOperator.OverCompositeOp )
	burned.CompositeWithPositionAndGravity( shotAnnotation, 0.5, 0.0, Draft.PositionalGravity.SouthGravity, Draft.CompositeOperator.OverCompositeOp )

	outLut.Apply( burned )

	#if os.path.exists( inFile ):
	burned.CompositeWithPositionAndGravity( logo, 0.95, 0.05, Draft.PositionalGravity.SouthEastGravity, Draft.CompositeOperator.OverCompositeOp )

	MJPEGencoder.EncodeNextFrame( burned )
	#MJPEGencoderHRes.EncodeNextFrame( burned )

#Finalize the encoding process
MJPEGencoder.FinalizeEncoding()
#MJPEGencoderHRes.FinalizeEncoding()

if doOutSingleEye:
	break

[/code]

Very strange! I will have a look in a bit and get back to you.

Okay, I’m looking at this now. I started off running the script exactly the way you posted it. My results are somewhat similar to yours: I see the content only on the right side and bottom, although it doesn’t appear squished. It looks like there’s a black rectangle being comped over top of the frames. I’ll have a look at the code now to see what is causing it.

Some side notes, I noticed that you’re using an old, outdated sample script as your starting point.

  • FrameListToFrames unnecessary, now part of DraftParamParser (called FrameRangeToFrames)
  • using deprecated “gravity” form of composite operator, current is “anchor” form

I’ll post an updated version of the script here once I’ve fixed the other bug.

Cheers,
Andrea

Problem solved. It looks like it was due to how a missing logo was being handled. I’ve fixed that now, updated the code, and made another small change that should improve performance a bit. Could you check this to see if your other problems are fixed now too? (You mentioned it appeared to be fast-forward.) Note: You will need the newer version of Draft to run this updated script, as I changed deprecated method calls with the updated forms.

Cheers,
Andrea

[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()

#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_new.png”
logoFrame = “\\fx-deadline\deadline\Draft\FrimaFX.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’] = ‘’
expectedTypes[‘startFrame’] = ‘’
expectedTypes[‘endFrame’] = ‘’

#Parse the command line arguments
params = ParseCommandLine( expectedTypes, sys.argv )

inFilePattern = params[‘inFile’]
params[‘frameList’] = “%d-%d” % (params[‘startFrame’], params[‘endFrame’])
frames = range( params[‘startFrame’], params[‘endFrame’] + 1 )
#frames = FrameRangeToFrames( 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’])

outWidth = 1920
outHeight = 1080
#halfWidth = 2560
#halfHeight = 1350
slateFrames = 1
outLut = Draft.LUT.CreateRec709()

for eye in [‘l’,‘r’]:
#Build up the encoders
doOutSingleEye = False
if not ‘%v’ in outBase:
doOutSingleEye = True

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)
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)

#   increment += 1

MJPEGencoder = Draft.VideoEncoder( newFileName, 24.0, outWidth, outHeight, 75000, “MJPEG” )

MJPEGencoderHRes = Draft.VideoEncoder( newFileNameHalf, 24.0, halfWidth, halfHeight, 325000, “MJPEG” )

#Annotation info used for burn ins
annotationInfo = Draft.AnnotationInfo()
annotationInfo.PointSize = int( outHeight * 0.017 )
annotationInfo.Color = Draft.ColorRGBA( 1.0, 1.0, 1.0, 1.0 )

#Annotation info used for burn ins
annotationInfoBig = Draft.AnnotationInfo()
annotationInfoBig.PointSize = int( outHeight * 0.02 )
annotationInfoBig.Color = Draft.ColorRGBA( 1.0, 1.0, 1.0, 1.0 )

#Annotation info used for burn ins
annotationInfoFrame = Draft.AnnotationInfo()
annotationInfoFrame.PointSize = int( outHeight * 0.025 )
annotationInfoFrame.Color = Draft.ColorRGBA( 1.0, 1.0, 1.0, 1.0 )

#prep the Slate Frame
try:
slate = Draft.Image.ReadFromFile( slateFrame )
slate.SetChannel( ‘A’, 1.0 )
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.Resize( outWidth, outHeight, “fit” )

#sets up the text on the slate frame
slateAnnotations = [params[‘entity’], params[‘version’], params[‘username’], datetime.datetime.now().strftime("%m/%d/%Y %I:%M %p"), params[‘frameList’]]

for i in range (0, 4):
annotation = Draft.Image.CreateAnnotation(slateAnnotations[i], annotationInfo)
slate.CompositeWithPositionAndAnchor(annotation, 0.23, 0.446 - (i * 0.03), Draft.Anchor.NorthWest, Draft.CompositeOperator.OverCompositeOp)

annotation = Draft.Image.CreateAnnotation(slateAnnotations[4], annotationInfo)
slate.CompositeWithPositionAndAnchor(annotation, 0.327, 0.24, Draft.Anchor.South, Draft.CompositeOperator.OverCompositeOp)

oFrameRangeSplit = slateAnnotations[4].split(’-’)
oFrameCount = str(int(oFrameRangeSplit[1]) - int(oFrameRangeSplit[0]) + 1)
annotation = Draft.Image.CreateAnnotation(oFrameCount, annotationInfoBig)
slate.CompositeWithPositionAndAnchor(annotation, 0.251, 0.237, Draft.Anchor.South, 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 )
#MJPEGencoderHRes.EncodeNextFrame( slate )

studioAnnotation = Draft.Image.CreateAnnotation( “PROJECT”, annotationInfo )
entityAnnotation = Draft.Image.CreateAnnotation( “%s %s” % (params[‘entity’], datetime.datetime.now().strftime("%m/%d/%Y")), annotationInfo )
dateAnnotation = Draft.Image.CreateAnnotation( datetime.datetime.now().strftime("%m/%d/%Y"), annotationInfo )
shotAnnotation = Draft.Image.CreateAnnotation(params[‘entity’], annotationInfo)

try:
logo = Draft.Image.ReadFromFile( logoFrame )
logo.Resize(int(0.1852outHeight), int(0.0657outHeight))
except:
logo = None

#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 )

  if os.path.exists( inFile ):
     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 is None:
     bgFrame = Draft.Image.CreateImage( outWidth, outHeight )
     bgFrame.SetToColor( Draft.ColorRGBA( 0.0, 0.0, 0.0, 1.0 ) )
  elif ( bgFrame.width != outWidth or bgFrame.height != outHeight ):
     bgFrame.Resize( outWidth, outHeight, 'fit' )

  #Do the frame burnins
  bgFrame.SetChannel('A', 1.0)
  bgFrame.Composite(bgFrame, 0, 0, Draft.CompositeOperator.OverCompositeOp)
  framesAnnotation = Draft.Image.CreateAnnotation( str( frameNumber ), annotationInfoFrame )
  bgFrame.CompositeWithPositionAndAnchor( framesAnnotation, 0.825, 0.062, Draft.Anchor.SouthEast, Draft.CompositeOperator.OverCompositeOp )

  #don't redo the other burnins, or the LUT since we've already done it for the last frame
  #if os.path.exists( inFile ):
  bgFrame.CompositeWithPositionAndAnchor( studioAnnotation, 0.0, 1.0, Draft.Anchor.NorthWest, Draft.CompositeOperator.OverCompositeOp )
  bgFrame.CompositeWithPositionAndAnchor( dateAnnotation, 0.0, 0.0, Draft.Anchor.SouthWest, Draft.CompositeOperator.OverCompositeOp )
  bgFrame.CompositeWithPositionAndAnchor( shotAnnotation, 0.5, 0.0, Draft.Anchor.South, Draft.CompositeOperator.OverCompositeOp )

  outLut.Apply( bgFrame )

  #if os.path.exists( inFile ):
  if logo is not None :
     bgFrame.CompositeWithPositionAndAnchor( logo, 0.95, 0.05, Draft.Anchor.SouthEast, Draft.CompositeOperator.OverCompositeOp )

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

#Finalize the encoding process
MJPEGencoder.FinalizeEncoding()
#MJPEGencoderHRes.FinalizeEncoding()

if doOutSingleEye:
break[/code]

Hi Andrea,

we just reinstalled Draft RC3 and your corrected script. We now have a weird problem. If the draft job is launched from the event listener after a Nuke job finished, everything is going fine. But if we manually launch a Draft job, we get the following error message :

0: STDOUT: Traceback (most recent call last): 0: STDOUT: File "R:\SLATE_DRA3D2", line 10, in <module> 0: STDOUT: import Draft 0: STDOUT: ImportError: DLL load failed: Le module spécifié est introuvable.
It’s like our environment variables doesn’t find the location of Draft.pyd. Any idea?

Thanks

By “manually”, do you mean using the Deadline Monitor directly (edit: specifically, “Submit Draft Job to Deadline”), submitting a Deadline job from the command line, or (and I suspect it’s not this one, given the output) running the Draft script directly using python on the command line?

What are your PATH, PYTHONPATH, and MAGICK_CONFIGURE_PATH variables set to? (And MAGICK_FONT_PATH, if you have that one set too.)

Edit: Also, was the same Deadline slave machine used in both cases?

Cheers,
Andrea

For our environment variables, the only one we use in your list is PATH (cause PYTHONPATH cause some interference with Maya). So, our Path variable looks like this :

C:\Python27\Lib\site-packages\PyQt4; C:\Program Files\Thinkbox\Deadline\bin; %SystemRoot%\system32; %SystemRoot%; %SystemRoot%\System32\Wbem; %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\; C:\Program Files (x86)\QuickTime\QTSystem\; C:\Program Files (x86)\Autodesk\Backburner\; C:\Program Files\3Delight\bin; C:\Program Files\Autodesk\Maya2012\bin; C:\Program Files (x86)\AMD APP\bin\x86_64; C:\Program Files (x86)\AMD APP\bin\x86; C:\Tcl\bin; C:\Python27\Lib\site-packages\PyQt4; C:\Program Files\Common Files\Microsoft Shared\Windows Live; C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live; C:\Program Files\Thinkbox\Deadline\bin; %SystemRoot%\system32; %SystemRoot%; %SystemRoot%\System32\Wbem; %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\; C:\Program Files\TortoiseSVN\bin; C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static; C:\Program Files (x86)\Autodesk\Backburner\; C:\Program Files (x86)\Windows Live\Shared; C:\Program Files (x86)\QuickTime\QTSystem\; C:\Program Files\3Delight\bin; C:\Program Files\Autodesk\Maya2012\bin; c:\python27_x64; C:\Python27_x64\Lib\site-packages; K:\STUDIO\CGTOOLS\python; K:\STUDIO\CGTOOLS\python\managing;

Could you also post the log reports from both jobs?

Thanks,
Andrea

This code snippet is the log for the job launched manually who bug :

[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: Untitled (00l_050_00a_4263216d)
0: INFO: StartJob: initializing script plugin Draft
0: INFO: Found Draft python module at: ‘C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Fx-render-10\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:\SLATE_DRA3D.py” username=“sdafdsa” entity=“fdsdf” version=“fggrew” frameList=1-72 startFrame=1 endFrame=72 outFile=“R:\DRA3D2\SHOTS\042\0030\cmp\outputs\v03\Draft\DRA3D2_042_0030_v03.l.mov” inFile=“R:\DRA3D2\SHOTS\042\0030\cmp\outputs\v03\DRA3D2_042_0030_v03.l.####.exr”
0: INFO: Startup Directory: “C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Fx-render-10\Draft”
0: INFO: Process Priority: BelowNormal
0: INFO: Process is now running
0: STDOUT: Traceback (most recent call last):
0: STDOUT: File “R:\SLATE_DRA3D.py”, line 7, in
0: STDOUT: import Draft
0: STDOUT: ImportError: DLL load failed: Le module spécifié est introuvable.
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]
This code snippet is the one launched from the event listener who worked :

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

0: Plugin will be reloaded because a new job has been loaded, or one of the job files has been modified
0: Loaded plugin: Draft
0: Task timeout is disabled.
0: Loaded job: DRA3D2.042.0040.cmp.v04.nk [DRAFT] (002_058_00a_2d45fdbc)
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\Poste-0475\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\Poste-0475\jobsData\SLATE_DRA3D.py” username="" entity="" version=“lgtCmp v02” width=3500 height=2560 frameList=1-43 startFrame=1 endFrame=43 inFile="\fx-nas-01\vfx\RENDER\DRA3D2\SHOTS\042\0040\cmp\outputs\v04\DRA3D2_042_0040_cmp_v04.%v.####.exr" outFile="\fx-nas-01\vfx\RENDER\DRA3D2\SHOTS\042\0040\cmp\outputs\v04\Draft\DRA3D2_042_0040_cmp_v04.%v.mov" deadlineJobID=00f_058_999_2cd02b03
0: INFO: Startup Directory: “C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Poste-0475\Draft”
0: INFO: Process Priority: BelowNormal
0: INFO: Process is now running
0: STDOUT: Checking for license at @prodflexmr
0: STDOUT: Draft 1.0.0.49258
0: STDOUT: Draft Version: 1.0.0.49258
0: STDOUT: Command line args:
0: STDOUT: username=
0: STDOUT: entity=
0: STDOUT: version=lgtCmp v02
0: STDOUT: width=3500
0: STDOUT: height=2560
0: STDOUT: frameList=1-43
0: STDOUT: startFrame=1
0: STDOUT: endFrame=43
0: STDOUT: inFile=\fx-nas-01\vfx\RENDER\DRA3D2\SHOTS\042\0040\cmp\outputs\v04\DRA3D2_042_0040_cmp_v04.%v.####.exr
0: STDOUT: outFile=\fx-nas-01\vfx\RENDER\DRA3D2\SHOTS\042\0040\cmp\outputs\v04\Draft\DRA3D2_042_0040_cmp_v04.%v.mov
0: STDOUT: deadlineJobID=00f_058_999_2cd02b03
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: 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: Output #0, mov, to ‘\fx-nas-01\vfx\RENDER\DRA3D2\SHOTS\042\0040\cmp\outputs\v04\Draft/1080p/DRA3D2_042_0040_cmp_v04.l.mov’:
0: STDOUT: Metadata:
0: STDOUT: encoder : Lavf54.29.104
0: STDOUT: Stream #0:0: Video: mjpeg (jpeg / 0x6765706A), yuvj420p, 1920x1080, q=2-31, 75000 kb/s, 24 tbn, 24 tbc
0: STDOUT: [mov @ 00000000004AC240] Encoder did not produce proper pts, making some up.
0: STDOUT: Output #0, mov, to ‘\fx-nas-01\vfx\RENDER\DRA3D2\SHOTS\042\0040\cmp\outputs\v04\Draft/1080p/DRA3D2_042_0040_cmp_v04.r.mov’:
0: STDOUT: Metadata:
0: STDOUT: encoder : Lavf54.29.104
0: STDOUT: Stream #0:0: Video: mjpeg (jpeg / 0x6765706A), yuvj420p, 1920x1080, q=2-31, 75000 kb/s, 24 tbn, 24 tbc
0: INFO: Process exit code: 0
0: INFO: Draft job complete!
0: Render time for frame: 1.103 m
0: Total time for task: 1.139 m

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

Log Date/Time = Jan 17/13 14:20:32
Frames = 0-0

Slave Machine = Poste-0475
Slave Version = v5.1.0.46114 R

Plugin Name = Draft[/code]

It looks like both are finding the bundled python and so are using the correct version of python, but I noticed that that the two jobs were running on different slaves: the one that worked ran on Poste-0475, and the one that didn’t work ran on Fx-render-10. Try manually fixing the installation on 64-bit windows. You can do this by going onto Fx-render-10, and copying the files from:
\repository\Draft\Windows\64bit
to:
C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Fx-render-10\Draft
and then try running another draft job on Fx-render-10, to see if it fixed the problem.

Cheers,
Andrea

We already tried to launch our job manually on POSTE-0475 and we had the same problem. Draft module isn’t found.

Please clarify whether by “manually”, you mean using “Submit Draft Job to Deadline” in the Deadline Monitor, or something else.

Could we also see the log file from the failed job on poste-0475?

There it is!

[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: ISO DRAFTBLASTING : CoqSc115_anm.ma (002_100_00a_78638f7a)
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\Poste-0475\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 “\fx-nas-01\vfx\RENDER\isoPB_draftSlate.py” username=rbmonfette project=“Le Coq de St-Victor” audioDelay=0 scenename=CoqSc115_anm.ma width=1024 inDailies=0 dailiesFolder=\fx-nas-01\vfx\RENDER\COQ\REVIEW\DAILIES\ANM inFile=\fx-nas-01\vfx\RENDER\SWAP\tmpcjjgj0\DraftBlast.####.png entity= audioFilename= outFile=\fx-nas-01\vfx\render\COQ\SHOTS\115\SEQ\MOVIES\anm\CoqSc115_anm.mov shotsDB=\fx-nas-01\vfx\RENDER\SWAP\tmpcjjgj0\shotCams.db version= inFolder=\fx-nas-01\vfx\RENDER\SWAP\tmpcjjgj0 date=“2013-01-17 14:57:01” startFrame=28 frameList=28-320 height=576 endFrame=320
0: INFO: Startup Directory: “C:\Users\renderfx\AppData\Local\Thinkbox\Deadline\slave\Poste-0475\Draft”
0: INFO: Process Priority: BelowNormal
0: INFO: Process is now running
0: STDOUT: Traceback (most recent call last):
0: STDOUT: File “\fx-nas-01\vfx\RENDER\isoPB_draftSlate.py”, line 10, in
0: STDOUT: import Draft
0: STDOUT: ImportError: DLL load failed: Le module spécifié est introuvable.
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]

Privacy | Site terms | Cookie preferences