mirror of
https://github.com/iluvcapra/pycmx.git
synced 2026-10-02 01:37:19 +00:00
134 lines
3.3 KiB
Python
134 lines
3.3 KiB
Python
import argparse
|
|
import logging
|
|
import re
|
|
import sys
|
|
|
|
import pycmx
|
|
|
|
FORMAT = "%(asctime)-15s %(message)s"
|
|
logging.basicConfig(format=FORMAT)
|
|
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
def all_video_edits(edl):
|
|
for event in edl.events:
|
|
for edit in event.edits:
|
|
if edit.channels.video:
|
|
yield edit
|
|
|
|
|
|
def get_scene_name(edit, pattern):
|
|
scene_extractor = re.compile(pattern, re.IGNORECASE)
|
|
if edit.clip_name is None:
|
|
return None
|
|
else:
|
|
match_data = re.match(scene_extractor, edit.clip_name)
|
|
if match_data:
|
|
return match_data[1]
|
|
else:
|
|
return edit.clip_name
|
|
|
|
|
|
def output_cmx(outfile, out_list):
|
|
outfile.write("TITLE: SCENE LIST\r\n")
|
|
outfile.write("FCM: NON-DROP FRAME\r\n")
|
|
|
|
for i, o in enumerate(out_list):
|
|
line = "%03i AX V C " % (i)
|
|
line += "00:00:00:00 00:00:00:00 %s %s\r\n" % (o["start"], o["end"])
|
|
outfile.write(line)
|
|
outfile.write("* FROM CLIP NAME: %s\r\n" % (o["scene"]))
|
|
|
|
|
|
def output_cols(outfile, out_list):
|
|
for o in out_list:
|
|
outfile.write("%-12s\t%-12s\t%s\n" % (o["start"], o["end"], o["scene"]))
|
|
|
|
|
|
def scene_list(infile, outfile, out_format, pattern):
|
|
|
|
edl = pycmx.parse_cmx3600(infile)
|
|
|
|
current_scene_name = None
|
|
|
|
grouped_edits = []
|
|
|
|
for edit in all_video_edits(edl):
|
|
this_scene_name = get_scene_name(edit, pattern)
|
|
if this_scene_name is not None:
|
|
if current_scene_name != this_scene_name:
|
|
grouped_edits.append([])
|
|
current_scene_name = this_scene_name
|
|
|
|
grouped_edits[-1].append(edit)
|
|
|
|
out_list = []
|
|
for group in grouped_edits:
|
|
out_list.append(
|
|
{
|
|
"start": group[0].record_in,
|
|
"end": group[-1].record_out,
|
|
"scene": get_scene_name(group[0], pattern),
|
|
}
|
|
)
|
|
|
|
if out_format == "cmx":
|
|
output_cmx(outfile, out_list)
|
|
if out_format == "cols":
|
|
output_cols(outfile, out_list)
|
|
else:
|
|
log.warning(f"Format {out_format} unrecognized. Will use cmx.\n")
|
|
output_cmx(outfile, out_list)
|
|
|
|
|
|
def scene_list_cli():
|
|
parser = argparse.ArgumentParser(
|
|
description="Read video events from an input CMX EDL and output "
|
|
"events merged into scenes."
|
|
)
|
|
parser.add_argument(
|
|
"-o",
|
|
"--outfile",
|
|
default=sys.stdout,
|
|
type=argparse.FileType("w"),
|
|
help="Output file. Default is stdout.",
|
|
)
|
|
parser.add_argument(
|
|
"-f",
|
|
"--format",
|
|
default="cmx",
|
|
type=str,
|
|
help="Output format. Options are cols and cmx, cmx is the default.",
|
|
)
|
|
parser.add_argument(
|
|
"-p",
|
|
"--pattern",
|
|
default="V?([A-Z]*[0-9]+)",
|
|
help="RE pattern for extracting scene name from clip "
|
|
'name. The default is "V?([A-Z]*[0-9]+)". '
|
|
+ "This pattern will be matched case-insensitively.",
|
|
)
|
|
parser.add_argument(
|
|
"input_edl",
|
|
default=sys.stdin,
|
|
type=argparse.FileType("r"),
|
|
nargs="?",
|
|
help="Input file. Default is stdin.",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
infile = args.input_edl
|
|
|
|
scene_list(
|
|
infile=infile,
|
|
outfile=args.outfile,
|
|
out_format=args.format,
|
|
pattern=args.pattern,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
scene_list_cli()
|