Skip to content

Instantly share code, notes, and snippets.

@flablog flablog/play.py
Created Jul 19, 2018

Embed
What would you like to do?
Play : simple command line to play shots as sequences
#!/usr/bin/python
'''This scripts reads CSVs prepared from a XML edit export,
and prepares a Melt command to play shots as a sequence
https://mltframework.org/twiki/bin/view/MLT/MltMelt
'''
import argparse
import os
import sys
import glob
from pprint import pprint
project = "Dilili"
parser = argparse.ArgumentParser()
parser.add_argument("episode", type=str,
default="DIL",
help="episode name")
parser.add_argument("seq", type=int,
help="sequence number (without S)")
parser.add_argument("shots",
type=int,
action='store',
nargs='*',
help="shot number(s), without P")
parser.add_argument("-r", "--range",
type=str,
help="range start:end :end (from beginning to the end) start: (from start to the end)")
parser.add_argument("-rv", help="play in rv instead of melt",
action="store_true")
parser.add_argument("-dj", help="play one shot in djv_view",
action="store_true")
parser.add_argument("-v", '--verbose', help="verbose mode",
action="store_true")
parser.add_argument('--list-only', help="activate verbose mode and does not execute the commad at the end",
action="store_true")
parser.add_argument("-compo", help="play compo OUT image sequence instead of movie preview",
action="store_true")
args = parser.parse_args()
if args.list_only:
args.verbose = True
start = 0
end = 999999
# If a range is specified
if args.range and ":" not in args.range:
print("range invalid, should be start:end or :end or start:")
elif args.range and ":" in args.range:
s, e = args.range.split(":")
if s and s.isdigit():
start = int(s)
if e and e.isdigit():
end = int(e)
# If not argument provided
if len(sys.argv) < 2:
print("Provide a least a sequence number to play > ex: play 2")
sys.exit()
root = "/u/production/%s/%s/" % (project, episode)
seq = "S%02i" % args.seq
wip = args.wip
compo = args.compo
# Checking if episode or sequence exists
if not os.path.exists(root):
print("Episode %s DOES NOT EXISTS" % root)
sys.exit()
if not os.path.exists(root + seq):
print("SEQUENCE DOES NOT EXISTS IN %s" % root)
sys.exit()
# Checking if there is a CSV file available for that sequence
current = root + seq + "/EDIT/current/"
EDL_path = root + seq + "/EDIT/EDL/*.csv"
EDLs = glob.glob(EDL_path)
if not EDLs:
print("NO EDL (CSV) FILE FOUND ON : %s" % EDL_path)
sys.exit()
# Grabbing the last version :
EDLs.sort()
last_EDL = EDLs[-1]
if args.verbose:
print("Using following EDL : %s" % last_EDL)
# Parsing the EDL file and listing all the shots
shots = []
f = open(last_EDL, 'r')
lines = f.readlines()
f.close()
if args.verbose:
if args.range:
print("Range set : %i:%i" % (start, end))
else:
print("default range : %i:%i" % (start, end))
in_range = False
start_consumed = False
for l in lines:
if not l or l.startswith('#') or ',' not in l:
print("skipped : %s" % l)
continue
shot = l.split(',')[0]
if shot.startswith(episode):
if args.range:
shot_id = int(shot.split("_")[-1].split("P")[1])
if in_range is False:
if shot_id == start or (start == 0 and start_consumed is False):
in_range = True
start_consumed = True
shots.append(shot)
else:
if shot_id == end:
in_range = False
shots.append(shot)
if args.shots:
for s in args.shots:
if "P%04i" % s in shot and shot not in shots:
shots.append(shot)
elif args.range:
continue
else:
shots.append(shot)
if args.verbose:
print(" # List of shots to be screened : ")
pprint(shots)
print("%i Shots" % len(shots))
# Now the parsing has been done, and the list is ready
# Preparing the command line, default is melt, but could be rv ou djv_view
cmd = "melt "
if args.rv:
cmd = "rv -play -l "
if args.dj:
cmd = "djv_view "
# For each shot of the list, fetches the shot
# Depending on parameters provided. Default choice is using "CURRENT"
# The command ('cmd' variable) will be incremented for each shot
for s in shots:
if wip is False and compo is False:
# CURRENT
path = current + "%s.mov" % s
if os.path.exists(path):
cmd += "%s " % path
else:
print("Missing shot : %s" % s)
elif compo is True:
# COMPO IMAGE SEQUENCE
episode, seq, shot = s.split("_")
compo_path = root + "%s/%s/Compo-Render/OUT" % (seq, shot)
if os.path.exists(compo_path):
cmd += "%s " % compo_path
else:
print("Missing shot : %s" % s)
elif wip is True:
# WORK IN PROGRESS MOVIE, NOT THE CURRENT ONE
# This is more depending on our workflow, where a wip preview
# might not be in the CURRENT folder yet until publishing the
# work file (like the animation file).
episode, seq, shot = s.split("_")
wip_path = root + "%s/%s/*-Movie/%s_*.mov" % (seq, shot, s)
results = glob.glob(wip_path)
oldest_path = 0
file_path = None
for f in results:
st = os.stat(f)
if st.st_mtime > oldest_path:
oldest_path = st.st_mtime
file_path = f
if file_path:
cmd += "%s " % file_path
else:
print("Missing shot : %s" % s)
if args.verbose:
print(cmd)
# The command is now ready, and we ask the system to execute it
if args.list_only is False:
os.system(cmd)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.