mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
Merge branch 'develop' into feature/PYPE-570-maya-renderlayer-creator
This commit is contained in:
commit
0dc5c7a21d
11 changed files with 267 additions and 57 deletions
56
pype/lib.py
56
pype/lib.py
|
|
@ -13,6 +13,62 @@ import avalon
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_paths_from_environ(env_key, return_first=False):
|
||||
"""Return existing paths from specific envirnment variable.
|
||||
|
||||
:param env_key: Environment key where should look for paths.
|
||||
:type env_key: str
|
||||
:param return_first: Return first path on `True`, list of all on `False`.
|
||||
:type return_first: boolean
|
||||
|
||||
Difference when none of paths exists:
|
||||
- when `return_first` is set to `False` then function returns empty list.
|
||||
- when `return_first` is set to `True` then function returns `None`.
|
||||
"""
|
||||
|
||||
existing_paths = []
|
||||
paths = os.environ.get(env_key) or ""
|
||||
path_items = paths.split(os.pathsep)
|
||||
for path in path_items:
|
||||
# Skip empty string
|
||||
if not path:
|
||||
continue
|
||||
# Normalize path
|
||||
path = os.path.normpath(path)
|
||||
# Check if path exists
|
||||
if os.path.exists(path):
|
||||
# Return path if `return_first` is set to True
|
||||
if return_first:
|
||||
return path
|
||||
# Store path
|
||||
existing_paths.append(path)
|
||||
|
||||
# Return None if none of paths exists
|
||||
if return_first:
|
||||
return None
|
||||
# Return all existing paths from environment variable
|
||||
return existing_paths
|
||||
|
||||
|
||||
def get_ffmpeg_tool_path(tool="ffmpeg"):
|
||||
"""Find path to ffmpeg tool in FFMPEG_PATH paths.
|
||||
|
||||
Function looks for tool in paths set in FFMPEG_PATH environment. If tool
|
||||
exists then returns it's full path.
|
||||
|
||||
Returns tool name itself when tool path was not found. (FFmpeg path may be
|
||||
set in PATH environment variable)
|
||||
"""
|
||||
|
||||
dir_paths = get_paths_from_environ("FFMPEG_PATH")
|
||||
for dir_path in dir_paths:
|
||||
for file_name in os.listdir(dir_path):
|
||||
base, ext = os.path.splitext(file_name)
|
||||
if base.lower() == tool.lower():
|
||||
return os.path.join(dir_path, tool)
|
||||
return tool
|
||||
|
||||
|
||||
# Special naming case for subprocess since its a built-in method.
|
||||
def _subprocess(*args, **kwargs):
|
||||
"""Convenience method for getting output errors for subprocess."""
|
||||
|
|
|
|||
|
|
@ -35,7 +35,18 @@ class CollectFtrackApi(pyblish.api.ContextPlugin):
|
|||
# Find project entity
|
||||
project_query = 'Project where full_name is "{0}"'.format(project_name)
|
||||
self.log.debug("Project query: < {0} >".format(project_query))
|
||||
project_entity = session.query(project_query).one()
|
||||
project_entity = list(session.query(project_query).all())
|
||||
if len(project_entity) == 0:
|
||||
raise AssertionError(
|
||||
"Project \"{0}\" not found in Ftrack.".format(project_name)
|
||||
)
|
||||
# QUESTION Is possible to happen?
|
||||
elif len(project_entity) > 1:
|
||||
raise AssertionError((
|
||||
"Found more than one project with name \"{0}\" in Ftrack."
|
||||
).format(project_name))
|
||||
|
||||
project_entity = project_entity[0]
|
||||
self.log.debug("Project found: {0}".format(project_entity))
|
||||
|
||||
# Find asset entity
|
||||
|
|
@ -44,7 +55,25 @@ class CollectFtrackApi(pyblish.api.ContextPlugin):
|
|||
' and name is "{1}"'
|
||||
).format(project_entity["id"], asset_name)
|
||||
self.log.debug("Asset entity query: < {0} >".format(entity_query))
|
||||
asset_entity = session.query(entity_query).one()
|
||||
asset_entities = []
|
||||
for entity in session.query(entity_query).all():
|
||||
# Skip tasks
|
||||
if entity.entity_type.lower() != "task":
|
||||
asset_entities.append(entity)
|
||||
|
||||
if len(asset_entities) == 0:
|
||||
raise AssertionError((
|
||||
"Entity with name \"{0}\" not found"
|
||||
" in Ftrack project \"{1}\"."
|
||||
).format(asset_name, project_name))
|
||||
|
||||
elif len(asset_entities) > 1:
|
||||
raise AssertionError((
|
||||
"Found more than one entity with name \"{0}\""
|
||||
" in Ftrack project \"{1}\"."
|
||||
).format(asset_name, project_name))
|
||||
|
||||
asset_entity = asset_entities[0]
|
||||
self.log.debug("Asset found: {0}".format(asset_entity))
|
||||
|
||||
# Find task entity if task is set
|
||||
|
|
@ -53,8 +82,15 @@ class CollectFtrackApi(pyblish.api.ContextPlugin):
|
|||
'Task where name is "{0}" and parent_id is "{1}"'
|
||||
).format(task_name, asset_entity["id"])
|
||||
self.log.debug("Task entity query: < {0} >".format(task_query))
|
||||
task_entity = session.query(task_query).one()
|
||||
self.log.debug("Task entity found: {0}".format(task_entity))
|
||||
task_entity = session.query(task_query).first()
|
||||
if not task_entity:
|
||||
self.log.warning(
|
||||
"Task entity with name \"{0}\" was not found.".format(
|
||||
task_name
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.log.debug("Task entity found: {0}".format(task_entity))
|
||||
|
||||
else:
|
||||
task_entity = None
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import os
|
|||
|
||||
import pyblish.api
|
||||
import pype.api
|
||||
import pype.lib
|
||||
|
||||
|
||||
class ExtractJpegEXR(pyblish.api.InstancePlugin):
|
||||
|
|
@ -56,9 +57,10 @@ class ExtractJpegEXR(pyblish.api.InstancePlugin):
|
|||
proj_name = os.environ.get('AVALON_PROJECT', '__default__')
|
||||
profile = config_data.get(proj_name, config_data['__default__'])
|
||||
|
||||
ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
jpeg_items = []
|
||||
jpeg_items.append(
|
||||
os.path.join(os.environ.get("FFMPEG_PATH"), "ffmpeg"))
|
||||
jpeg_items.append(ffmpeg_path)
|
||||
# override file if already exists
|
||||
jpeg_items.append("-y")
|
||||
# use same input args like with mov
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import os
|
|||
import pyblish.api
|
||||
import clique
|
||||
import pype.api
|
||||
import pype.lib
|
||||
|
||||
|
||||
class ExtractReview(pyblish.api.InstancePlugin):
|
||||
|
|
@ -40,6 +41,8 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
# get representation and loop them
|
||||
representations = inst_data["representations"]
|
||||
|
||||
ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
# filter out mov and img sequences
|
||||
representations_new = representations[:]
|
||||
for repre in representations:
|
||||
|
|
@ -149,6 +152,9 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
# necessary input data
|
||||
# adds start arg only if image sequence
|
||||
if isinstance(repre["files"], list):
|
||||
|
||||
if start_frame != repre.get("detectedStart", start_frame):
|
||||
start_frame = repre.get("detectedStart")
|
||||
input_args.append(
|
||||
"-start_number {0} -framerate {1}".format(
|
||||
start_frame, fps))
|
||||
|
|
@ -324,10 +330,7 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
os.mkdir(stg_dir)
|
||||
|
||||
mov_args = [
|
||||
os.path.join(
|
||||
os.environ.get(
|
||||
"FFMPEG_PATH",
|
||||
""), "ffmpeg"),
|
||||
ffmpeg_path,
|
||||
" ".join(input_args),
|
||||
" ".join(output_args)
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
import pype.api
|
||||
import pype.lib
|
||||
import pyblish
|
||||
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ class ExtractReviewSlate(pype.api.Extractor):
|
|||
|
||||
suffix = "_slate"
|
||||
slate_path = inst_data.get("slateFrame")
|
||||
ffmpeg_path = os.path.join(os.environ.get("FFMPEG_PATH", ""), "ffmpeg")
|
||||
ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
to_width = 1920
|
||||
to_height = 1080
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
import pyblish.api
|
||||
import os
|
||||
import subprocess
|
||||
import pype.lib
|
||||
try:
|
||||
import os.errno as errno
|
||||
except ImportError:
|
||||
import errno
|
||||
|
||||
|
||||
class ValidateFfmpegInstallef(pyblish.api.Validator):
|
||||
class ValidateFFmpegInstalled(pyblish.api.Validator):
|
||||
"""Validate availability of ffmpeg tool in PATH"""
|
||||
|
||||
order = pyblish.api.ValidatorOrder
|
||||
|
|
@ -27,10 +28,8 @@ class ValidateFfmpegInstallef(pyblish.api.Validator):
|
|||
return True
|
||||
|
||||
def process(self, instance):
|
||||
self.log.info("ffmpeg path: `{}`".format(
|
||||
os.environ.get("FFMPEG_PATH", "")))
|
||||
if self.is_tool(
|
||||
os.path.join(
|
||||
os.environ.get("FFMPEG_PATH", ""), "ffmpeg")) is False:
|
||||
ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
self.log.info("ffmpeg path: `{}`".format(ffmpeg_path))
|
||||
if self.is_tool(ffmpeg_path) is False:
|
||||
self.log.error("ffmpeg not found in PATH")
|
||||
raise RuntimeError('ffmpeg not installed.')
|
||||
|
|
|
|||
97
pype/plugins/maya/publish/validate_ass_relative_paths.py
Normal file
97
pype/plugins/maya/publish/validate_ass_relative_paths.py
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
import os
|
||||
import types
|
||||
|
||||
import maya.cmds as cmds
|
||||
|
||||
import pyblish.api
|
||||
import pype.api
|
||||
import pype.maya.action
|
||||
|
||||
|
||||
class ValidateAssRelativePaths(pyblish.api.InstancePlugin):
|
||||
"""Ensure exporting ass file has set relative texture paths"""
|
||||
|
||||
order = pype.api.ValidateContentsOrder
|
||||
hosts = ['maya']
|
||||
families = ['ass']
|
||||
label = "ASS has relative texture paths"
|
||||
actions = [pype.api.RepairAction]
|
||||
|
||||
def process(self, instance):
|
||||
# we cannot ask this until user open render settings as
|
||||
# `defaultArnoldRenderOptions` doesn't exists
|
||||
try:
|
||||
relative_texture = cmds.getAttr(
|
||||
"defaultArnoldRenderOptions.absolute_texture_paths")
|
||||
relative_procedural = cmds.getAttr(
|
||||
"defaultArnoldRenderOptions.absolute_procedural_paths")
|
||||
texture_search_path = cmds.getAttr(
|
||||
"defaultArnoldRenderOptions.tspath"
|
||||
)
|
||||
procedural_search_path = cmds.getAttr(
|
||||
"defaultArnoldRenderOptions.pspath"
|
||||
)
|
||||
except ValueError:
|
||||
assert False, ("Can not validate, render setting were not opened "
|
||||
"yet so Arnold setting cannot be validate")
|
||||
|
||||
scene_dir, scene_basename = os.path.split(cmds.file(q=True, loc=True))
|
||||
scene_name, _ = os.path.splitext(scene_basename)
|
||||
project_root = "{}{}{}".format(
|
||||
os.environ.get("AVALON_PROJECTS"),
|
||||
os.path.sep,
|
||||
os.environ.get("AVALON_PROJECT")
|
||||
)
|
||||
assert self.maya_is_true(relative_texture) is not True, \
|
||||
("Texture path is set to be absolute")
|
||||
assert self.maya_is_true(relative_procedural) is not True, \
|
||||
("Procedural path is set to be absolute")
|
||||
|
||||
texture_search_path = texture_search_path.replace("\\", "/")
|
||||
procedural_search_path = procedural_search_path.replace("\\", "/")
|
||||
project_root = project_root.replace("\\", "/")
|
||||
|
||||
assert project_root in texture_search_path, \
|
||||
("Project root is not in texture_search_path")
|
||||
assert project_root in procedural_search_path, \
|
||||
("Project root is not in procedural_search_path")
|
||||
|
||||
@classmethod
|
||||
def repair(cls, instance):
|
||||
texture_search_path = cmds.getAttr(
|
||||
"defaultArnoldRenderOptions.tspath"
|
||||
)
|
||||
procedural_search_path = cmds.getAttr(
|
||||
"defaultArnoldRenderOptions.pspath"
|
||||
)
|
||||
|
||||
project_root = "{}{}{}".format(
|
||||
os.environ.get("AVALON_PROJECTS"),
|
||||
os.path.sep,
|
||||
os.environ.get("AVALON_PROJECT"),
|
||||
).replace("\\", "/")
|
||||
|
||||
cmds.setAttr("defaultArnoldRenderOptions.tspath",
|
||||
project_root + os.pathsep + texture_search_path,
|
||||
type="string")
|
||||
cmds.setAttr("defaultArnoldRenderOptions.pspath",
|
||||
project_root + os.pathsep + procedural_search_path,
|
||||
type="string")
|
||||
cmds.setAttr("defaultArnoldRenderOptions.absolute_procedural_paths",
|
||||
False)
|
||||
cmds.setAttr("defaultArnoldRenderOptions.absolute_texture_paths",
|
||||
False)
|
||||
|
||||
def maya_is_true(self, attr_val):
|
||||
"""
|
||||
Whether a Maya attr evaluates to True.
|
||||
When querying an attribute value from an ambiguous object the
|
||||
Maya API will return a list of values, which need to be properly
|
||||
handled to evaluate properly.
|
||||
"""
|
||||
if isinstance(attr_val, types.BooleanType):
|
||||
return attr_val
|
||||
elif isinstance(attr_val, (types.ListType, types.GeneratorType)):
|
||||
return any(attr_val)
|
||||
else:
|
||||
return bool(attr_val)
|
||||
|
|
@ -4,6 +4,7 @@ import tempfile
|
|||
import pyblish.api
|
||||
import clique
|
||||
import pype.api
|
||||
import pype.lib
|
||||
|
||||
|
||||
class ExtractReviewSP(pyblish.api.InstancePlugin):
|
||||
|
|
@ -148,12 +149,7 @@ class ExtractReviewSP(pyblish.api.InstancePlugin):
|
|||
# output filename
|
||||
output_args.append(full_output_path)
|
||||
|
||||
ffmpeg_path = os.getenv("FFMPEG_PATH", "")
|
||||
if ffmpeg_path:
|
||||
ffmpeg_path += "/ffmpeg"
|
||||
else:
|
||||
ffmpeg_path = "ffmpeg"
|
||||
|
||||
ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
mov_args = [
|
||||
ffmpeg_path,
|
||||
" ".join(input_args),
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import tempfile
|
|||
import subprocess
|
||||
import pyblish.api
|
||||
import pype.api
|
||||
import pype.lib
|
||||
|
||||
|
||||
class ExtractThumbnailSP(pyblish.api.InstancePlugin):
|
||||
|
|
@ -73,11 +74,7 @@ class ExtractThumbnailSP(pyblish.api.InstancePlugin):
|
|||
config_data.get("__default__", {})
|
||||
)
|
||||
|
||||
ffmpeg_path = os.getenv("FFMPEG_PATH", "")
|
||||
if ffmpeg_path:
|
||||
ffmpeg_path += "/ffmpeg"
|
||||
else:
|
||||
ffmpeg_path = "ffmpeg"
|
||||
ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
jpeg_items = []
|
||||
jpeg_items.append(ffmpeg_path)
|
||||
|
|
|
|||
|
|
@ -1,33 +1,27 @@
|
|||
import os
|
||||
import sys
|
||||
import re
|
||||
import datetime
|
||||
import subprocess
|
||||
import json
|
||||
import opentimelineio_contrib.adapters.ffmpeg_burnins as ffmpeg_burnins
|
||||
from pypeapp.lib import config
|
||||
from pype import api as pype
|
||||
from subprocess import Popen, PIPE
|
||||
# FFmpeg in PATH is required
|
||||
from pypeapp import Logger
|
||||
import pype.lib
|
||||
|
||||
log = Logger().get_logger("BurninWrapper", "burninwrap")
|
||||
|
||||
|
||||
log = pype.Logger().get_logger("BurninWrapper", "burninwrap")
|
||||
ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
ffprobe_path = pype.lib.get_ffmpeg_tool_path("ffprobe")
|
||||
|
||||
|
||||
ffmpeg_path = os.environ.get("FFMPEG_PATH")
|
||||
if ffmpeg_path and os.path.exists(ffmpeg_path):
|
||||
# add separator "/" or "\" to be prepared for next part
|
||||
ffmpeg_path += os.path.sep
|
||||
else:
|
||||
ffmpeg_path = ""
|
||||
|
||||
FFMPEG = (
|
||||
'{} -loglevel panic -i %(input)s %(filters)s %(args)s%(output)s'
|
||||
).format(os.path.normpath(ffmpeg_path + "ffmpeg"))
|
||||
).format(ffmpeg_path)
|
||||
|
||||
FFPROBE = (
|
||||
'{} -v quiet -print_format json -show_format -show_streams %(source)s'
|
||||
).format(os.path.normpath(ffmpeg_path + "ffprobe"))
|
||||
).format(ffprobe_path)
|
||||
|
||||
DRAWTEXT = (
|
||||
"drawtext=text=\\'%(text)s\\':x=%(x)s:y=%(y)s:fontcolor="
|
||||
|
|
@ -41,6 +35,7 @@ TIMECODE = (
|
|||
|
||||
MISSING_KEY_VALUE = "N/A"
|
||||
CURRENT_FRAME_KEY = "{current_frame}"
|
||||
CURRENT_FRAME_SPLITTER = "_-_CURRENT_FRAME_-_"
|
||||
TIME_CODE_KEY = "{timecode}"
|
||||
|
||||
|
||||
|
|
@ -136,7 +131,9 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins):
|
|||
if options_init:
|
||||
self.options_init.update(options_init)
|
||||
|
||||
def add_text(self, text, align, frame_start=None, options=None):
|
||||
def add_text(
|
||||
self, text, align, frame_start=None, frame_end=None, options=None
|
||||
):
|
||||
"""
|
||||
Adding static text to a filter.
|
||||
|
||||
|
|
@ -152,11 +149,15 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins):
|
|||
if frame_start:
|
||||
options["frame_offset"] = frame_start
|
||||
|
||||
# `frame_end` is only for meassurements of text position
|
||||
if frame_end:
|
||||
options["frame_end"] = frame_end
|
||||
|
||||
self._add_burnin(text, align, options, DRAWTEXT)
|
||||
|
||||
def add_timecode(
|
||||
self, align, frame_start=None, frame_start_tc=None, text=None,
|
||||
options=None
|
||||
self, align, frame_start=None, frame_end=None, frame_start_tc=None,
|
||||
text=None, options=None
|
||||
):
|
||||
"""
|
||||
Convenience method to create the frame number expression.
|
||||
|
|
@ -174,6 +175,10 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins):
|
|||
if frame_start:
|
||||
options["frame_offset"] = frame_start
|
||||
|
||||
# `frame_end` is only for meassurements of text position
|
||||
if frame_end:
|
||||
options["frame_end"] = frame_end
|
||||
|
||||
if not frame_start_tc:
|
||||
frame_start_tc = options["frame_offset"]
|
||||
|
||||
|
|
@ -197,10 +202,31 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins):
|
|||
:param enum align: alignment, must use provided enum flags
|
||||
:param dict options:
|
||||
"""
|
||||
|
||||
final_text = text
|
||||
text_for_size = text
|
||||
if CURRENT_FRAME_SPLITTER in text:
|
||||
frame_start = options["frame_offset"]
|
||||
frame_end = options.get("frame_end", frame_start)
|
||||
if not frame_start:
|
||||
replacement_final = replacement_size = str(MISSING_KEY_VALUE)
|
||||
else:
|
||||
replacement_final = "\\'{}\\'".format(
|
||||
r'%%{eif\:n+%d\:d}' % frame_start
|
||||
)
|
||||
replacement_size = str(frame_end)
|
||||
|
||||
final_text = final_text.replace(
|
||||
CURRENT_FRAME_SPLITTER, replacement_final
|
||||
)
|
||||
text_for_size = text_for_size.replace(
|
||||
CURRENT_FRAME_SPLITTER, replacement_size
|
||||
)
|
||||
|
||||
resolution = self.resolution
|
||||
data = {
|
||||
'text': (
|
||||
text
|
||||
final_text
|
||||
.replace(",", r"\,")
|
||||
.replace(':', r'\:')
|
||||
),
|
||||
|
|
@ -208,7 +234,7 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins):
|
|||
'size': options['font_size']
|
||||
}
|
||||
timecode_text = options.get("timecode") or ""
|
||||
text_for_size = text + timecode_text
|
||||
text_for_size += timecode_text
|
||||
data.update(options)
|
||||
data.update(
|
||||
ffmpeg_burnins._drawtext(align, resolution, text_for_size, options)
|
||||
|
|
@ -272,7 +298,7 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins):
|
|||
)
|
||||
print(command)
|
||||
|
||||
proc = Popen(command, shell=True)
|
||||
proc = subprocess.Popen(command, shell=True)
|
||||
proc.communicate()
|
||||
if proc.returncode != 0:
|
||||
raise RuntimeError("Failed to render '%s': %s'"
|
||||
|
|
@ -368,6 +394,7 @@ def burnins_from_data(
|
|||
burnin = ModifiedBurnins(input_path, options_init=options_init)
|
||||
|
||||
frame_start = data.get("frame_start")
|
||||
frame_end = data.get("frame_end")
|
||||
frame_start_tc = data.get('frame_start_tc', frame_start)
|
||||
|
||||
stream = burnin._streams[0]
|
||||
|
|
@ -382,7 +409,7 @@ def burnins_from_data(
|
|||
|
||||
# Check frame start and add expression if is available
|
||||
if frame_start is not None:
|
||||
data[CURRENT_FRAME_KEY[1:-1]] = r'%%{eif\:n+%d\:d}' % frame_start
|
||||
data[CURRENT_FRAME_KEY[1:-1]] = CURRENT_FRAME_SPLITTER
|
||||
|
||||
if frame_start_tc is not None:
|
||||
data[TIME_CODE_KEY[1:-1]] = TIME_CODE_KEY
|
||||
|
|
@ -432,7 +459,7 @@ def burnins_from_data(
|
|||
|
||||
# Handle timecode differently
|
||||
if has_timecode:
|
||||
args = [align, frame_start, frame_start_tc]
|
||||
args = [align, frame_start, frame_end, frame_start_tc]
|
||||
if not value.startswith(TIME_CODE_KEY):
|
||||
value_items = value.split(TIME_CODE_KEY)
|
||||
text = value_items[0].format(**data)
|
||||
|
|
@ -442,7 +469,7 @@ def burnins_from_data(
|
|||
continue
|
||||
|
||||
text = value.format(**data)
|
||||
burnin.add_text(text, align, frame_start)
|
||||
burnin.add_text(text, align, frame_start, frame_end)
|
||||
|
||||
codec_args = ""
|
||||
if codec_data:
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import json
|
|||
import clique
|
||||
import subprocess
|
||||
from pypeapp import config
|
||||
import pype.lib
|
||||
from . import QtWidgets, QtCore
|
||||
from . import DropEmpty, ComponentsList, ComponentItem
|
||||
|
||||
|
|
@ -224,12 +225,7 @@ class DropDataFrame(QtWidgets.QFrame):
|
|||
self._process_data(data)
|
||||
|
||||
def load_data_with_probe(self, filepath):
|
||||
ffprobe_path = os.getenv("FFMPEG_PATH", "")
|
||||
if ffprobe_path:
|
||||
ffprobe_path += '/ffprobe'
|
||||
else:
|
||||
ffprobe_path = 'ffprobe'
|
||||
|
||||
ffprobe_path = pype.lib.get_ffmpeg_tool_path("ffprobe")
|
||||
args = [
|
||||
ffprobe_path,
|
||||
'-v', 'quiet',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue