Spend Your Time Making Art, Not QuickTimes

Version: Deadline 7.2, Deadline 8.0

Background

Alice is a successful artist who is a perfectionist. She’s currently working on an animated short film using her favorite software Autodesk 3ds Max. In order to be more productive, she would like to automatically create QuickTimes from her renders.

Draft

Before leaving the office, Alice typically submits render jobs of the animated scenes she’s currently working on to Deadline from the 3ds Max Integrated Submitter. Then, she often starts her workday by looking at the rendered image sequences from the night before so she knows which parts still need improvement. In order to be more productive, she would like to watch QuickTimes instead, so she can spot immediately anything she dislikes. What Alice needs is to have QuickTimes waiting for her each morning. She would need Deadline to automatically launch jobs during the night to generate QuickTimes for her as soon as her render jobs complete.

Alice would benefit greatly from using DraftDraft is a lightweight compositing and video processing tool designed to automate typical post-render tasks. It is implemented as a Python library, which exposes functionality for use in Python scripts. Draft is designed to be tightly integrated with Deadline. There are two convenient ways to create Draft jobs from most Deadline Submitters. One is Quick Draft, that submits a Draft dependent job in just a couple of clicks, and the other is Custom Draft, that allows for fine customizations through Python scripts.

Quick Draft

The easiest way for Alice to generate her QuickTimes is through Quick Draft. Directly from the 3ds Max Integrated Submitter, under the tab Integration, she can generate a QuickTime any time she submits a render job by checking the Submit Draft Job On Completion box and by choosing the Quick option. As pictured on the screen capture below, Quick Draft offers a variety of image and movie formats. She can simply select the MOV format and keep all the defaults. To minimize the file size and to speed up the movie encoding process, she can also set Resolution to 1/2 or 1/4.

She could also have chosen an image format to generate an image sequence. The available options for the drop down menus get adjusted automatically based on the selected format, always ensuring a valid combination forFormatCompression and Frame Rate (when applicable), thus making Quick Draft extremely user-friendly.

Distributed Encoding

Lately, Alice has been working overtime to finish her project, often leaving the office very late at night. She regularly has to wait for her QuickTimes to be ready when she gets in. This is slowing her down at a critical time. She could very easily speed up the encoding process by enabling Distributed Job in the Draft Event Plugin configuration.

When Distributed Job is enabled, Draft will first generate smaller movie chunks simultaneously across multiple machines and then, in one final step, concatenate all the movie chunks together to create one single movie. By performing Distributed EncodingDraft effectively speeds up the encoding process and prevents Alice from experiencing very frustrating delays. Note that it is also possible to create an image sequence in a “distributed” way.

The only thing Alice needs to do to enable Distributed Job is to open the Draft Event Plugin configuration panel in Super User Mode (under Tools->Configure Events) and set Enable Distributed Job to True. As pictured below, she can set the Number Of Frames Per Task, or chunk size, which represents the number of frames that each movie chunk will have. To avoid monopolizing the entire farm for her own needs, she also has control over theMachine Limit, or the maximum number of machines that will be used to encode each of her QuickTimes. She wants to improve her productivity but she doesn’t want to alienate the entire team!

To avoid useless processing, jobs are submitted in a distributed way only when the number of frames in total is greater or equal to 5 chunk sizes.

Custom Draft

Using Quick Draft is very straightforward and doesn’t require any Python programming skills. But what if Alice needs to perform more sophisticated post-render tasks? For instance, Alice might need to apply a color transform to her frames before creating the QuickTimes. She might also want to add a slate frame. What Alice needs now is to use Custom Draft and to create her own Python script.

The good news is that Alice doesn’t need to write her Python script from the ground up. Pertinent sample scripts designed to work well with Custom Draft can be found under Samples in the draft folder of her Deadline Repository. The goal here is to allow users to customize those scripts to fit their specific needs. Users can also consult the section Cookbook in the Draft Documentation for many useful code snippets.

Now, back to Alice. Suppose she wants to add a basic slate frame to her QuickTime to display useful information and to apply a linear-to-Rec 709 LUT to each frame before encoding. Let’s suppose she would also like to specify the quality of her QuickTime at each submission. For instance, if she wants her QuickTime encoded with a quality of 70, she can set the quality parameter by typing quality=70 in the field Additional Args (see the screen capture below).

Alice specified the path to her newly written Python script in the field Template (as pictured above). Excerpts from that script will follow. You can download the entire script here: MyCustomTemplate.py. Please, consult the section Library Reference in the Draft Documentation for more details on the Draft API. You can also have a look at the file DraftParamParser.py (available under the draft folder of your Deadline Repository) that provides functionality for parsing Draft related parameters.

Deadline sends script parameters as command line arguments. In the first excerpt, we see how Alice extracted those arguments using methods from the DraftParamParser.py. In this particular case, all arguments but one get automatically pulled from Alice’s 3ds Max job. Only the quality parameter is explicitly set by Alice in the field Additional Args as described above.

# Parse the command line arguments
params = ParseCommandLine( expectedTypes, sys.argv )
frames = FrameRangeToFrames( params['frameList'] )
inFilePattern = params['inFile']
outFile = params['outFile']
username = params['username']
entity = params['entity']
outWidth = params['width']
outHeight = params['height']
quality = params['quality']

In the next excerpt, we see how she created the slate frame. Alice wanted to have the name of her short film, her own name and the current date on her slate.

# Variables used when creating the slate annotations
currentDate = datetime.datetime.now().strftime( "%d/%m/%Y" )
compositeOp = Draft.CompositeOperator.OverCompositeOp
anchorSE = Draft.Anchor.SouthEast
anchorSW = Draft.Anchor.SouthWest

# Dictionary holding the information that will appear on the slate frame
annotations = [("NAME", entity), ("ARTIST", username), ("DATE", currentDate )]

# AnnotationInfo used to set the font size for the slate frame's annotations
annotationInfo = Draft.AnnotationInfo()
annotationInfo.PointSize = int( outHeight * 0.04 )

# Create the slate
slate = Draft.Image.CreateImage( outWidth, outHeight )
for i in range( 0, len( annotations ) ):
# Add the annotations appearing on the left side on the slate frame
annotation = Draft.Image.CreateAnnotation( annotations[i][0] + ": ", annotationInfo )
slate.CompositeWithPositionAndAnchor( annotation, 0.45, 0.7 - ( i * 0.06 ), anchorSE, compositeOp )
# Add the annotations appearing on the right side on the slate frame
annotation = Draft.Image.CreateAnnotation( annotations[i][1], annotationInfo )
slate.CompositeWithPositionAndAnchor( annotation, 0.46, 0.7 - ( i * 0.06 ), anchorSW, compositeOp )

Finally, in the last excerpt, we see how she created the video. Before encoding each frame, she applied a linear-to-Rec 709 LUT.

# Create the encoder and encode the slate frame first
encoder = Draft.VideoEncoder( outFile, width = outWidth, height = outHeight, quality = quality )
encoder.EncodeNextFrame( slate )

# Create the LUT
lut = Draft.LUT.CreateRec709()

# Main encoding loop
for frameNumber in frames:
# Read current frame in memory
inFile = ReplaceFilenameHashesWithNumber( inFilePattern, frameNumber )
currentFrame = Draft.Image.ReadFromFile( inFile )

# Apply the LUT to current frame
lut.Apply( currentFrame )

# Encode current frame
encoder.EncodeNextFrame( currentFrame )

#Finalize the encoding process
encoder.FinalizeEncoding()

For a unique look and feel, Alice could have customized her slate frame using special fonts and colors and a background image with a company logo. She could have added relevant information to her slate frame by parsing and extracting meaningful information from her 3ds Max project path (see the Cookbook recipe Parsing File Names to Extract Shot Information). She could also have added burn-ins to each frame including, for instance, the current frame number.

Alice could have specified a custom LUT file she baked herself to apply to each frames instead of a linear-to-Rec 709 LUT. Alternatively, she could have taken a LUT file directly from the many LUTs available in the draft folder under ocio-configs (including Nuke‘s default) or used Draft in conjunction with OCIO to create a new one. She could have added an audio file to her QuickTime and a progress counter in the main encoding loop to monitor more closely her Draft job. As you can see, the possibilities are endless...

Wrapup

Draft can make your workflow easier by automating the creation and processing of QuickTimes, thumbnails and other deliverables in a pipeline. Besides 3ds MaxDraft is supported for many other applications such as MayaNuke,Houdini and Cinema4D. Furthermore, Draft is free for users on an active Deadline subscription. Automate your pipeline and spend more time making art and less time making QuickTimes!

We would like to hear from you! We are currently adding new controls and features in our Quick Draft UI and we would like to gather any special requests you might have, like, for instance, applying LUTs in one click, adding control for embedding timecodes (when applicable) or for specifying channel bit depth, adding a standard slate maker and burn-ins generator or adding the option to submit one single Draft job with multiple outputs – say a movie and multiple image sequences.

Please, help us adding new features in Quick Draft that users would get excited about by giving ideas and feedback through this Draft forum thread.