AWS Thinkbox Discussion Forums

NOOB question - simple h.264 encoding

Fantastic!

Thank you, Eric!

Will give it a try. Cheers.

Hi guys, me again. :slight_smile:

Ok, so I’m a bit stuck.

I’m completely new to writing Draft templates, so, please, bear with me.

What I’m trying to do is:

  1. catch the output file provided by the user when submitting the original job for rendering (i.e.: C:\myOutputVideo.mp4)
  2. Take the video file and burn in its TIMECODE with Draft
  3. Save the video file with the very same codec settings as the original as C:\myOutputVideo_TC.mp4

That’s it.

The user will provide the output file name during the submission (there is no other way around this as we’re talking about a custom Deadline plugin that doesn’t expose any API and therefore we won’t be able to pull the render output filename from the plugin itself) and I want Draft to automatically just add TIMECODE to the rendered video.

Nothing else.

So far, I’m pretty much stuck, since I have no idea how to interact with Draft and the provided examples don’t really show much in my direction.

Further more I’m working with video files, but Deadline keeps adding #### characters to my video file names during the submission, which is annoying and unnecessary.

Thank you again in advance for your help, I very much appretiate it.

Cheers…

How do you feel about jumping on the 8.1 beta of Deadline, as really you have just described “Quick Draft” used in combination with the new “Draft Annotations” system. One of our developers blogged about it recently, but it’s only in 8.1, which is still in beta: deadline.thinkboxsoftware.com/fe … -draft-way

It’s brand new, so it might be slightly rough around the edges, but if you are up for a few cycles of testing and feedback, this would likely be a nice and clean approach for you?

I wouldn’t mind, but this needs to be done in a production on a current 8.0, no beta, no upgrades any time soon, unfortunately :frowning:

The new Quick Draft seems super cool, though. :slight_smile:

Ah, ok, that will make it more tricky then. (using 8.0 instead of 8.1).

So, have you seen our Draft cookbook examples here on TIMECODE and how to burn?
docs.thinkboxsoftware.com/produc … s-timecode

and into a video file:
docs.thinkboxsoftware.com/produc … nvideofile

In terms of pulling data from a Deadline job:
docs.thinkboxsoftware.com/produc … ntegration

docs.thinkboxsoftware.com/produc … eters.html
docs.thinkboxsoftware.com/produc … alues.html

Thank you, Mike,

I’m still trying to wrap my head around Draft. It seems unnecessarily complicated for what it’s supposed to be doing, to be honest.

Quite honestly I’m inclined to actually work around Draft rather than with it. I’d rather install a utility that does the TIMECODE burn in for me rather than trying to figure out this weird clusterf*** Draft seems.

I’m sure seasoned Draft users are rolling their eyes thinking how I could possibly think of such a simple and elegant solution that Draft for sure is, being complicated. But the truth is, Draft seems incredibly backwards to me.

Hopefully I’ll be able to figure it out today (as it is my deadline :smiley: ).

Thank you again for your help, much appretiated!

By the way, is there any way I can import Draft into my Python session so that I don’t have to debug/test/develop by trial and error (submitting jobs to Deadline and waiting for their STDOUT)?!

I can’t find the Draft module I could import into my Python session anywhere in the Deadline repo, nor in my local Deadline installation.

Thanks in advance!

sys.path.append(“C:\Users\User_name\AppData\Local\Thinkbox\Deadline8\slave\machine_name\Draft”)
Should be there :>.

If you are on Linux I dont know where it is but you can find it using inspect module xD.

You are absolutely amazing! Thank you!

I’d never thought of this location and haven’t bumped into it in any of the documentation.

Thank you again! This will speed up my R&D substantially!

How to run Draft Standalone:
docs.thinkboxsoftware.com/produc … standalone

Ahh, there it is: \SERVER\deadline\draft\Windows\64bit\

Can’t believe I missed it!

Thank you!

Sorry guys, but I’m getting a bit frustrated here and I’m SERIOUSLY considering completely skipping this Draft nonsense and use a completely different solution (EVEN NUKE for that matter) so a super simple timecode burn in. Draft just doesn’t make any sense to me. It seems as if Draft was supposed to be a Pythonic module, but was written by somebody deeply rooted in C++ or other programming language (kinda like raw Python implementation in Maya felt). Passing objects, returning objects, somehow, nothing MAKES ANY SENSE and I don’t think I am a complete Python beginner here.

Ok, se here’s my, incomplete, Draft template code that I just cannot really think of ANY way putting together from the examples in the documentation:

[code]import sys

sys.path.append(r"C:\Users\loocas\AppData\Local\Thinkbox\Deadline8\slave\DUBER\Draft")

import Draft
from DraftParamParser import ReplaceFilenameHashesWithNumber

tmpFilesToProcess = [r"D:\V1880007_lens_A.MP4"]

Create a Draft.ImageInfo object to extract a Draft.Timecode object

imageInfo = Draft.ImageInfo()

decodedVideo = Draft.VideoDecoder(tmpFilesToProcess[0])
frameImage = Draft.Image.CreateImage(decodedVideo.width, decodedVideo.height)

now, what the hell do I do here?!!! Why do I have to work with single images suddenly? And, ok, if so, WHERE THE HELL DO I REFERENCE THE IMAGE?

while(decodedVideo.DecodeNextFrame(frameImage)):
#OK, WHERE DO I REFERENCE THE frameImage object?! Where do I use it? How? Is it always overwritten in memory, meaning
the object refreshes with each DecodeNextFrame call? Why can’t I index it? Or at least Yield it? HOW DOES IT WORK?!
# If first frame and a timecode is found, specify the timecode parameter when creating the encoder
if(imageInfo.timecode):
# WHAT IS THIS?!! why am I encoding a video with no parameters and mainly no reference to the frameImage object?!
encoder = Draft.VideoEncoder( ‘C:\myMovie.mov’, timecode = imageInfo.timecode )
else:
encoder = Draft.VideoEncoder( ‘C:\myMovie.mov’ )

# Add current frame to the video.
encoder.EncodeNextFrame(frameImage)

encoder.FinalizeEncoding()[/code]

I’m sorry, but this is just one huge mess. I don’t understand the Draft structure, its logic and I am really frustrated by it not doing anything remotely logical.

I’d much rather work around Draft than work with it, to be quite honest.

And not to be completely negative, here’s my suggestion for what Draft should be:

import Draft

videoToBeProcessed = r'C:\vid.mp4'

decodedVid = Draft.DecodeVideoFile(videoToBeProcessed)

for curFrame in range(decodedVid.frameRange):
	singleImage = decodedVid.getSingleFrame(curFrame)
	
	#do some stuff to the single image object
	
	encoder = Draft.VideoEncoder(r'C:\outputFile.mov', <parameters>)
	encoder.encodeFrame(curFrame, singleImage)

encoder.FinalizeEncoding()	

This would make sense, in my opinion.

If you create a video encoder for every frame, you’ll get into trouble. In your ideal case, you’d be destroying and re-creating your video encoder. I’ll see if I can make this work for you.

Imagine the VideoEncoder is a meat grinder where you put your frames in the top and it pushes out videos. You make the meat grinder, and you feed it individual frames with encoder.EncodeNextFrame. If you re-create the meat grinder for every frame, you’re not getting a very good QuickTime sausage. :smiley:

I’ll see if I can make a simpler example for you here quickly.

Here’s the transcode sample from “[repo]/draft/Samples/Transcode”:

import sys
import Draft
from DraftParamParser import *

expectedTypes = {}
expectedTypes['inFile'] = '<string>'
expectedTypes['outFile'] = '<string>'

params = ParseCommandLine( expectedTypes, sys.argv )

inFile = params['inFile']
outFile = params['outFile']

img = Draft.Image.CreateImage( 1, 1 )

dec = Draft.VideoDecoder( inFile )

hasFrame = dec.DecodeNextFrame( img )

enc = None

while hasFrame:
    if enc is None:
        enc = Draft.VideoEncoder( outFile, 25, dec.width, dec.height, codec='mjpeg' )

    enc.EncodeNextFrame( img )
    
    hasFrame = dec.DecodeNextFrame( img )

if enc is not None:
    enc.FinalizeEncoding()

Update: I’ve got to head out, but here’s the sample I’ve got working. The codec settings don’t match the input, and it’s not burning anything in yet so right now it’s just a seriously inefficient lossy copy.

import sys

import Draft
from DraftParamParser import ReplaceFilenameHashesWithNumber

tmpFilesToProcess = [r"/Users/edwin.amsler/Downloads/draft-test/input.mov"]
FilesProcessed = [r"/Users/edwin.amsler/Downloads/draft-test/output.mov"]
codec = 'h264'

# Create a Draft.ImageInfo object to extract a Draft.Timecode object
imageInfo = Draft.ImageInfo()

decodedVideo = Draft.VideoDecoder(tmpFilesToProcess[0])
encodedVideo = Draft.VideoEncoder(FilesProcessed[0], 25, decodedVideo.width, decodedVideo.height, codec = codec)
frameImage = Draft.Image.CreateImage(decodedVideo.width, decodedVideo.height)

index = 0

while(decodedVideo.DecodeNextFrame(frameImage)):
    index += 1
    print('Frame {}\r'.format(index))
    encodedVideo.EncodeNextFrame(frameImage)

encoder.FinalizeEncoding()

Thank ou Edwin, it seems to be working.

My code was a copy&paste from the documentation that didn’t work actually. So that’s why I had problems with wrapping my head around it.

But from your example, I get the logic.

I’ll see if I can compose stff onto the currently processed image and spit it out.

Thank you very much again, I much appretiate it!

Ok, fantastic! So annotations work, image composition works, I’m starting to get the logic behind Draft, finally :smiley:

However, I’m still in the dark as to how to pull parent job info data.

I use the implemented Deadline event job submission process, meaning that after the render job finishes, the Draft job picks it up. But I need to source the file paths users provided in the submission dialog in the Draft processing.

I need the “OutputBox” control object’s contents from the submission dialog.

Is there any simpler way than to search for the parent job ID, then pull the job’s data based on the ID and then parse everything from the job data to find the one specific field I’m looking for?

Thank you in advance, you’ve already helped me tremendously!

Allright, got it all working.

Thank you again, guys, very much appretiated! :slight_smile:

OH! I’m glad to hear it. Sorry I’ve been away from the forums the last few days. If you need anything else, just let me know!

Thank you, I very much appreatiate your help! :slight_smile:

I finally managed to wrap my head around Draft’s logic and the way the Event plugin works, so all is fine now and working. :slight_smile:

Privacy | Site terms | Cookie preferences