mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 08:24:53 +01:00
Merge pull request #1467 from pypeclub/feature/extract_burnins_with_sequences
This commit is contained in:
commit
7d4063616f
2 changed files with 71 additions and 32 deletions
|
|
@ -3,6 +3,7 @@ import re
|
||||||
import json
|
import json
|
||||||
import copy
|
import copy
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import clique
|
||||||
|
|
||||||
import openpype
|
import openpype
|
||||||
import openpype.api
|
import openpype.api
|
||||||
|
|
@ -269,7 +270,9 @@ class ExtractBurnin(openpype.api.Extractor):
|
||||||
"output": temp_data["full_output_path"],
|
"output": temp_data["full_output_path"],
|
||||||
"burnin_data": burnin_data,
|
"burnin_data": burnin_data,
|
||||||
"options": burnin_options,
|
"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(
|
self.log.debug(
|
||||||
|
|
@ -483,32 +486,47 @@ class ExtractBurnin(openpype.api.Extractor):
|
||||||
None: This is processing method.
|
None: This is processing method.
|
||||||
"""
|
"""
|
||||||
# TODO we should find better way to know if input is sequence
|
# TODO we should find better way to know if input is sequence
|
||||||
is_sequence = (
|
input_filenames = new_repre["files"]
|
||||||
"sequence" in new_repre["tags"]
|
is_sequence = False
|
||||||
and isinstance(new_repre["files"], (tuple, list))
|
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:
|
if is_sequence:
|
||||||
input_filename = new_repre["sequence_file"]
|
collections, _ = clique.assemble(input_filenames)
|
||||||
else:
|
if not collections:
|
||||||
input_filename = new_repre["files"]
|
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)
|
first_frame = min(indexes)
|
||||||
dir_path, basename = os.path.split(filepart_start)
|
|
||||||
|
|
||||||
if is_sequence:
|
if not is_sequence:
|
||||||
# NOTE modified to keep name when multiple dots are in name
|
input_filename = input_filenames
|
||||||
basename_parts = basename.split(".")
|
if isinstance(input_filename, (tuple, list)):
|
||||||
frame_part = basename_parts.pop(-1)
|
input_filename = input_filename[0]
|
||||||
|
|
||||||
basename_start = ".".join(basename_parts) + filename_suffix
|
filepart_start, ext = os.path.splitext(input_filename)
|
||||||
new_basename = ".".join((basename_start, frame_part))
|
dir_path, basename = os.path.split(filepart_start)
|
||||||
output_filename = new_basename + ext
|
|
||||||
|
|
||||||
else:
|
|
||||||
output_filename = basename + filename_suffix + ext
|
output_filename = basename + filename_suffix + ext
|
||||||
|
if dir_path:
|
||||||
|
output_filename = os.path.join(dir_path, output_filename)
|
||||||
|
|
||||||
if dir_path:
|
repre_files = output_filename
|
||||||
output_filename = os.path.join(dir_path, output_filename)
|
|
||||||
|
|
||||||
stagingdir = new_repre["stagingDir"]
|
stagingdir = new_repre["stagingDir"]
|
||||||
full_input_path = os.path.join(
|
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_input_path"] = full_input_path
|
||||||
temp_data["full_output_path"] = full_output_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_input_path: {}".format(full_input_path))
|
||||||
self.log.debug("full_output_path: {}".format(full_output_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
|
# Prepare full paths to input files and filenames for reprensetation
|
||||||
full_input_paths = []
|
full_input_paths = []
|
||||||
if is_sequence:
|
if is_sequence:
|
||||||
repre_files = []
|
for filename in input_filenames:
|
||||||
for frame_index in range(1, temp_data["duration"] + 1):
|
filepath = os.path.join(
|
||||||
repre_files.append(output_filename % frame_index)
|
os.path.normpath(stagingdir), filename
|
||||||
full_input_paths.append(full_input_path % frame_index)
|
).replace("\\", "/")
|
||||||
|
full_input_paths.append(filepath)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
full_input_paths.append(full_input_path)
|
full_input_paths.append(full_input_path)
|
||||||
repre_files = output_filename
|
|
||||||
|
|
||||||
temp_data["full_input_paths"] = full_input_paths
|
temp_data["full_input_paths"] = full_input_paths
|
||||||
new_repre["files"] = repre_files
|
|
||||||
|
|
||||||
def prepare_repre_data(self, instance, repre, burnin_data, temp_data):
|
def prepare_repre_data(self, instance, repre, burnin_data, temp_data):
|
||||||
"""Prepare data for representation.
|
"""Prepare data for representation.
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ ffprobe_path = openpype.lib.get_ffmpeg_tool_path("ffprobe")
|
||||||
|
|
||||||
|
|
||||||
FFMPEG = (
|
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)
|
).format(ffmpeg_path)
|
||||||
|
|
||||||
FFPROBE = (
|
FFPROBE = (
|
||||||
|
|
@ -121,10 +121,18 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins):
|
||||||
'font_size': 42
|
'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:
|
if not streams:
|
||||||
streams = _streams(source)
|
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)
|
super().__init__(source, streams)
|
||||||
|
|
||||||
if options_init:
|
if options_init:
|
||||||
|
|
@ -289,7 +297,12 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins):
|
||||||
if self.filter_string:
|
if self.filter_string:
|
||||||
filters = '-vf "{}"'.format(self.filter_string)
|
filters = '-vf "{}"'.format(self.filter_string)
|
||||||
|
|
||||||
|
input_args = ""
|
||||||
|
if self.input_args:
|
||||||
|
input_args = " {}".format(" ".join(self.input_args))
|
||||||
|
|
||||||
return (FFMPEG % {
|
return (FFMPEG % {
|
||||||
|
'input_args': input_args,
|
||||||
'input': self.source,
|
'input': self.source,
|
||||||
'output': output,
|
'output': output,
|
||||||
'args': '%s ' % args if args else '',
|
'args': '%s ' % args if args else '',
|
||||||
|
|
@ -370,7 +383,8 @@ def example(input_path, output_path):
|
||||||
|
|
||||||
def burnins_from_data(
|
def burnins_from_data(
|
||||||
input_path, output_path, 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.
|
"""This method adds burnins to video/image file based on presets setting.
|
||||||
|
|
||||||
|
|
@ -427,8 +441,11 @@ def burnins_from_data(
|
||||||
"shot": "sh0010"
|
"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_start = data.get("frame_start")
|
||||||
frame_end = data.get("frame_end")
|
frame_end = data.get("frame_end")
|
||||||
|
|
@ -591,6 +608,8 @@ if __name__ == "__main__":
|
||||||
in_data["burnin_data"],
|
in_data["burnin_data"],
|
||||||
codec_data=in_data.get("codec"),
|
codec_data=in_data.get("codec"),
|
||||||
options=in_data.get("options"),
|
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")
|
print("* Burnin script has finished")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue