Merge pull request #1467 from pypeclub/feature/extract_burnins_with_sequences

This commit is contained in:
Milan Kolar 2021-05-04 22:54:23 +02:00 committed by GitHub
commit 7d4063616f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 32 deletions

View file

@ -3,6 +3,7 @@ import re
import json
import copy
import tempfile
import clique
import openpype
import openpype.api
@ -269,7 +270,9 @@ class ExtractBurnin(openpype.api.Extractor):
"output": temp_data["full_output_path"],
"burnin_data": burnin_data,
"options": burnin_options,
"values": burnin_values
"values": burnin_values,
"full_input_path": temp_data["full_input_paths"][0],
"first_frame": temp_data["first_frame"]
}
self.log.debug(
@ -483,32 +486,47 @@ class ExtractBurnin(openpype.api.Extractor):
None: This is processing method.
"""
# TODO we should find better way to know if input is sequence
is_sequence = (
"sequence" in new_repre["tags"]
and isinstance(new_repre["files"], (tuple, list))
)
input_filenames = new_repre["files"]
is_sequence = False
if isinstance(input_filenames, (tuple, list)):
if len(input_filenames) > 1:
is_sequence = True
# Sequence must have defined first frame
# - not used if input is not a sequence
first_frame = None
if is_sequence:
input_filename = new_repre["sequence_file"]
else:
input_filename = new_repre["files"]
collections, _ = clique.assemble(input_filenames)
if not collections:
is_sequence = False
else:
input_filename = new_repre["sequence_file"]
collection = collections[0]
indexes = list(collection.indexes)
padding = len(str(max(indexes)))
head = collection.format("{head}")
tail = collection.format("{tail}")
output_filename = "{}%{:0>2}d{}{}".format(
head, padding, filename_suffix, tail
)
repre_files = []
for idx in indexes:
repre_files.append(output_filename % idx)
filepart_start, ext = os.path.splitext(input_filename)
dir_path, basename = os.path.split(filepart_start)
first_frame = min(indexes)
if is_sequence:
# NOTE modified to keep name when multiple dots are in name
basename_parts = basename.split(".")
frame_part = basename_parts.pop(-1)
if not is_sequence:
input_filename = input_filenames
if isinstance(input_filename, (tuple, list)):
input_filename = input_filename[0]
basename_start = ".".join(basename_parts) + filename_suffix
new_basename = ".".join((basename_start, frame_part))
output_filename = new_basename + ext
else:
filepart_start, ext = os.path.splitext(input_filename)
dir_path, basename = os.path.split(filepart_start)
output_filename = basename + filename_suffix + ext
if dir_path:
output_filename = os.path.join(dir_path, output_filename)
if dir_path:
output_filename = os.path.join(dir_path, output_filename)
repre_files = output_filename
stagingdir = new_repre["stagingDir"]
full_input_path = os.path.join(
@ -520,6 +538,9 @@ class ExtractBurnin(openpype.api.Extractor):
temp_data["full_input_path"] = full_input_path
temp_data["full_output_path"] = full_output_path
temp_data["first_frame"] = first_frame
new_repre["files"] = repre_files
self.log.debug("full_input_path: {}".format(full_input_path))
self.log.debug("full_output_path: {}".format(full_output_path))
@ -527,17 +548,16 @@ class ExtractBurnin(openpype.api.Extractor):
# Prepare full paths to input files and filenames for reprensetation
full_input_paths = []
if is_sequence:
repre_files = []
for frame_index in range(1, temp_data["duration"] + 1):
repre_files.append(output_filename % frame_index)
full_input_paths.append(full_input_path % frame_index)
for filename in input_filenames:
filepath = os.path.join(
os.path.normpath(stagingdir), filename
).replace("\\", "/")
full_input_paths.append(filepath)
else:
full_input_paths.append(full_input_path)
repre_files = output_filename
temp_data["full_input_paths"] = full_input_paths
new_repre["files"] = repre_files
def prepare_repre_data(self, instance, repre, burnin_data, temp_data):
"""Prepare data for representation.

View file

@ -14,7 +14,7 @@ ffprobe_path = openpype.lib.get_ffmpeg_tool_path("ffprobe")
FFMPEG = (
'"{}" -i "%(input)s" %(filters)s %(args)s%(output)s'
'"{}"%(input_args)s -i "%(input)s" %(filters)s %(args)s%(output)s'
).format(ffmpeg_path)
FFPROBE = (
@ -121,10 +121,18 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins):
'font_size': 42
}
def __init__(self, source, streams=None, options_init=None):
def __init__(
self, source, streams=None, options_init=None, first_frame=None
):
if not streams:
streams = _streams(source)
input_args = []
if first_frame:
input_args.append("-start_number {}".format(first_frame))
self.input_args = input_args
super().__init__(source, streams)
if options_init:
@ -289,7 +297,12 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins):
if self.filter_string:
filters = '-vf "{}"'.format(self.filter_string)
input_args = ""
if self.input_args:
input_args = " {}".format(" ".join(self.input_args))
return (FFMPEG % {
'input_args': input_args,
'input': self.source,
'output': output,
'args': '%s ' % args if args else '',
@ -370,7 +383,8 @@ def example(input_path, output_path):
def burnins_from_data(
input_path, output_path, data,
codec_data=None, options=None, burnin_values=None, overwrite=True
codec_data=None, options=None, burnin_values=None, overwrite=True,
full_input_path=None, first_frame=None
):
"""This method adds burnins to video/image file based on presets setting.
@ -427,8 +441,11 @@ def burnins_from_data(
"shot": "sh0010"
}
"""
streams = None
if full_input_path:
streams = _streams(full_input_path)
burnin = ModifiedBurnins(input_path, options_init=options)
burnin = ModifiedBurnins(input_path, streams, options, first_frame)
frame_start = data.get("frame_start")
frame_end = data.get("frame_end")
@ -591,6 +608,8 @@ if __name__ == "__main__":
in_data["burnin_data"],
codec_data=in_data.get("codec"),
options=in_data.get("options"),
burnin_values=in_data.get("values")
burnin_values=in_data.get("values"),
full_input_path=in_data.get("full_input_path"),
first_frame=in_data.get("first_frame")
)
print("* Burnin script has finished")