Skip to content

Instantly share code, notes, and snippets.

@tokejepsen
Last active November 24, 2020 08:48
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tokejepsen/b2e5a8c35b5dbd5810ca607dfcf9aa75 to your computer and use it in GitHub Desktop.
Save tokejepsen/b2e5a8c35b5dbd5810ca607dfcf9aa75 to your computer and use it in GitHub Desktop.
OTIO to FFMPEG
import subprocess
import sys
import os
import json
import shutil
import requests
import opentimelineio as otio
def submit_deadline(args, name="temp", batch_name="temp", dependencies=[]):
# Generate the payload for Deadline submission
payload = {
"JobInfo": {
"Plugin": "CommandLine",
"BatchName": batch_name,
"Name": name,
},
"PluginInfo": {
"Executable": shutil.which(args[0]),
"Arguments": subprocess.list2cmdline(args[1:]),
"SingleFrameOnly": "True"
},
# Mandatory for Deadline, may be empty
"AuxFiles": []
}
# Generate dependencies payload.
count = 0
for dependency in dependencies:
payload["JobInfo"]["JobDependency{}".format(count)] = dependency
count += 1
print("Submitting..")
print(json.dumps(payload, indent=4, sort_keys=True))
url = "{}/api/jobs".format(
os.environ.get("DEADLINE_REST_URL", "http://localhost:8082")
)
response = requests.post(url, json=payload)
if not response.ok:
raise Exception(response.text)
return json.loads(response.text)["_id"]
def main(input_otio, output_path):
timeline = otio.adapters.read_from_file(input_otio)
batch_name = os.path.basename(input_otio)
destination = os.path.join(
output_path, "{}_%04d.exr".format(os.path.splitext(batch_name)[0])
)
for clip in timeline.each_clip():
path = clip.media_reference.target_url
visible_range = clip.visible_range()
available_range = clip.available_range()
start_time = int(
available_range.start_time.value - visible_range.start_time.value
)
duration = clip.duration().value
start_number = clip.range_in_parent().start_time.value
# If the start number is a float then something is wrong. A clip is
# probably in the wrong framerate.
if isinstance(start_number, float):
raise ValueError(
"Clip start number is a float. A clip is probably in the wrong"
" frame rate."
)
# Using no compression for speed and the files will be deleted
# once used.
args = [
"magick", "convert",
"-background", "rgba(0, 0, 0, 0)",
"{}[{}-{}]".format(
path, start_time, start_time + duration - 1
),
"-compress", "None",
"-scene", str(start_number),
destination
]
submit_deadline(
args,
name=os.path.basename(path),
batch_name=batch_name
)
if __name__ == "__main__":
main(sys.argv[1], sys.argv[2])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment