mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
AYON: 3rd party addon usage (#5300)
* implemented helper functions to get ffmpeg and oiio tool arguments * modified validation functions to be able to handle list of arguments * path getters can return a path in AYON mode if one argument is returned * removed test exception * modified docstrings * is_oiio_supported is using new functions to get launch arguments * new functions are in lib public = * use new functions all over the place * renamed 'ffmpeg_path' to 'ffmpeg_args' * raise 'ToolNotFoundError' if tool argument could not be found * reraise 'KnownPublishError' in publish plugins * fix comment * simplify args start * ffmpeg and oiio function require tool name and support additional arguments * renamed 'get_oiio_tools_args' to 'get_oiio_tool_args' * fix variable name
This commit is contained in:
parent
7b5e716147
commit
d63aa34a76
21 changed files with 302 additions and 198 deletions
|
|
@ -94,15 +94,14 @@ class ExtractRender(pyblish.api.InstancePlugin):
|
|||
|
||||
# Generate thumbnail.
|
||||
thumbnail_path = os.path.join(path, "thumbnail.png")
|
||||
ffmpeg_path = openpype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
args = [
|
||||
ffmpeg_path,
|
||||
args = openpype.lib.get_ffmpeg_tool_args(
|
||||
"ffmpeg",
|
||||
"-y",
|
||||
"-i", os.path.join(path, list(collections[0])[0]),
|
||||
"-vf", "scale=300:-1",
|
||||
"-vframes", "1",
|
||||
thumbnail_path
|
||||
]
|
||||
)
|
||||
process = subprocess.Popen(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import os
|
|||
import pyblish.api
|
||||
|
||||
from openpype.lib import (
|
||||
get_oiio_tools_path,
|
||||
get_oiio_tool_args,
|
||||
run_subprocess,
|
||||
)
|
||||
from openpype.pipeline import publish
|
||||
|
|
@ -18,7 +18,7 @@ class ExtractFrames(publish.Extractor):
|
|||
movie_extensions = ["mov", "mp4"]
|
||||
|
||||
def process(self, instance):
|
||||
oiio_tool_path = get_oiio_tools_path()
|
||||
oiio_tool_args = get_oiio_tool_args("oiiotool")
|
||||
staging_dir = self.staging_dir(instance)
|
||||
output_template = os.path.join(staging_dir, instance.data["name"])
|
||||
sequence = instance.context.data["activeTimeline"]
|
||||
|
|
@ -36,7 +36,7 @@ class ExtractFrames(publish.Extractor):
|
|||
output_path = output_template
|
||||
output_path += ".{:04d}.{}".format(int(frame), output_ext)
|
||||
|
||||
args = [oiio_tool_path]
|
||||
args = list(oiio_tool_args)
|
||||
|
||||
ext = os.path.splitext(input_path)[1][1:]
|
||||
if ext in self.movie_extensions:
|
||||
|
|
|
|||
|
|
@ -15,8 +15,14 @@ import pyblish.api
|
|||
|
||||
from maya import cmds # noqa
|
||||
|
||||
from openpype.lib.vendor_bin_utils import find_executable
|
||||
from openpype.lib import source_hash, run_subprocess, get_oiio_tools_path
|
||||
from openpype.lib import (
|
||||
find_executable,
|
||||
source_hash,
|
||||
run_subprocess,
|
||||
get_oiio_tool_args,
|
||||
ToolNotFoundError,
|
||||
)
|
||||
|
||||
from openpype.pipeline import legacy_io, publish, KnownPublishError
|
||||
from openpype.hosts.maya.api import lib
|
||||
|
||||
|
|
@ -267,12 +273,11 @@ class MakeTX(TextureProcessor):
|
|||
|
||||
"""
|
||||
|
||||
maketx_path = get_oiio_tools_path("maketx")
|
||||
|
||||
if not maketx_path:
|
||||
raise AssertionError(
|
||||
"OIIO 'maketx' tool not found. Result: {}".format(maketx_path)
|
||||
)
|
||||
try:
|
||||
maketx_args = get_oiio_tool_args("maketx")
|
||||
except ToolNotFoundError:
|
||||
raise KnownPublishError(
|
||||
"OpenImageIO is not available on the machine")
|
||||
|
||||
# Define .tx filepath in staging if source file is not .tx
|
||||
fname, ext = os.path.splitext(os.path.basename(source))
|
||||
|
|
@ -328,8 +333,7 @@ class MakeTX(TextureProcessor):
|
|||
|
||||
self.log.info("Generating .tx file for %s .." % source)
|
||||
|
||||
subprocess_args = [
|
||||
maketx_path,
|
||||
subprocess_args = maketx_args + [
|
||||
"-v", # verbose
|
||||
"-u", # update mode
|
||||
# --checknan doesn't influence the output file but aborts the
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import os
|
||||
import shutil
|
||||
from PIL import Image
|
||||
|
||||
from openpype.lib import (
|
||||
run_subprocess,
|
||||
get_ffmpeg_tool_path,
|
||||
get_ffmpeg_tool_args,
|
||||
)
|
||||
from openpype.pipeline import publish
|
||||
from openpype.hosts.photoshop import api as photoshop
|
||||
|
|
@ -85,7 +84,7 @@ class ExtractReview(publish.Extractor):
|
|||
instance.data["representations"].append(repre_skeleton)
|
||||
processed_img_names = [img_list]
|
||||
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
ffmpeg_args = get_ffmpeg_tool_args("ffmpeg")
|
||||
|
||||
instance.data["stagingDir"] = staging_dir
|
||||
|
||||
|
|
@ -94,13 +93,21 @@ class ExtractReview(publish.Extractor):
|
|||
source_files_pattern = self._check_and_resize(processed_img_names,
|
||||
source_files_pattern,
|
||||
staging_dir)
|
||||
self._generate_thumbnail(ffmpeg_path, instance, source_files_pattern,
|
||||
staging_dir)
|
||||
self._generate_thumbnail(
|
||||
list(ffmpeg_args),
|
||||
instance,
|
||||
source_files_pattern,
|
||||
staging_dir)
|
||||
|
||||
no_of_frames = len(processed_img_names)
|
||||
if no_of_frames > 1:
|
||||
self._generate_mov(ffmpeg_path, instance, fps, no_of_frames,
|
||||
source_files_pattern, staging_dir)
|
||||
self._generate_mov(
|
||||
list(ffmpeg_args),
|
||||
instance,
|
||||
fps,
|
||||
no_of_frames,
|
||||
source_files_pattern,
|
||||
staging_dir)
|
||||
|
||||
self.log.info(f"Extracted {instance} to {staging_dir}")
|
||||
|
||||
|
|
@ -142,8 +149,9 @@ class ExtractReview(publish.Extractor):
|
|||
"tags": self.mov_options['tags']
|
||||
})
|
||||
|
||||
def _generate_thumbnail(self, ffmpeg_path, instance, source_files_pattern,
|
||||
staging_dir):
|
||||
def _generate_thumbnail(
|
||||
self, ffmpeg_args, instance, source_files_pattern, staging_dir
|
||||
):
|
||||
"""Generates scaled down thumbnail and adds it as representation.
|
||||
|
||||
Args:
|
||||
|
|
@ -157,8 +165,7 @@ class ExtractReview(publish.Extractor):
|
|||
# Generate thumbnail
|
||||
thumbnail_path = os.path.join(staging_dir, "thumbnail.jpg")
|
||||
self.log.info(f"Generate thumbnail {thumbnail_path}")
|
||||
args = [
|
||||
ffmpeg_path,
|
||||
args = ffmpeg_args + [
|
||||
"-y",
|
||||
"-i", source_files_pattern,
|
||||
"-vf", "scale=300:-1",
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import pyblish.api
|
||||
from openpype.lib import (
|
||||
get_ffmpeg_tool_path,
|
||||
get_ffmpeg_tool_args,
|
||||
get_ffprobe_streams,
|
||||
path_to_subprocess_arg,
|
||||
run_subprocess,
|
||||
|
|
@ -62,12 +63,12 @@ class ExtractThumbnailSP(pyblish.api.InstancePlugin):
|
|||
|
||||
instance.context.data["cleanupFullPaths"].append(full_thumbnail_path)
|
||||
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
ffmpeg_executable_args = get_ffmpeg_tool_args("ffmpeg")
|
||||
|
||||
ffmpeg_args = self.ffmpeg_args or {}
|
||||
|
||||
jpeg_items = [
|
||||
path_to_subprocess_arg(ffmpeg_path),
|
||||
subprocess.list2cmdline(ffmpeg_executable_args),
|
||||
# override file if already exists
|
||||
"-y"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ import json
|
|||
|
||||
import pyblish.api
|
||||
from openpype.lib import (
|
||||
get_oiio_tools_path,
|
||||
get_oiio_tool_args,
|
||||
ToolNotFoundError,
|
||||
run_subprocess,
|
||||
)
|
||||
from openpype.pipeline import KnownPublishError
|
||||
|
|
@ -34,11 +35,12 @@ class ExtractConvertToEXR(pyblish.api.InstancePlugin):
|
|||
if not repres:
|
||||
return
|
||||
|
||||
oiio_path = get_oiio_tools_path()
|
||||
# Raise an exception when oiiotool is not available
|
||||
# - this can currently happen on MacOS machines
|
||||
if not os.path.exists(oiio_path):
|
||||
KnownPublishError(
|
||||
try:
|
||||
oiio_args = get_oiio_tool_args("oiiotool")
|
||||
except ToolNotFoundError:
|
||||
# Raise an exception when oiiotool is not available
|
||||
# - this can currently happen on MacOS machines
|
||||
raise KnownPublishError(
|
||||
"OpenImageIO tool is not available on this machine."
|
||||
)
|
||||
|
||||
|
|
@ -64,8 +66,8 @@ class ExtractConvertToEXR(pyblish.api.InstancePlugin):
|
|||
|
||||
src_filepaths.add(src_filepath)
|
||||
|
||||
args = [
|
||||
oiio_path, src_filepath,
|
||||
args = oiio_args + [
|
||||
src_filepath,
|
||||
"--compression", self.exr_compression,
|
||||
# TODO how to define color conversion?
|
||||
"--colorconvert", "sRGB", "linear",
|
||||
|
|
|
|||
|
|
@ -22,11 +22,14 @@ from .events import (
|
|||
)
|
||||
|
||||
from .vendor_bin_utils import (
|
||||
ToolNotFoundError,
|
||||
find_executable,
|
||||
get_vendor_bin_path,
|
||||
get_oiio_tools_path,
|
||||
get_oiio_tool_args,
|
||||
get_ffmpeg_tool_path,
|
||||
is_oiio_supported
|
||||
get_ffmpeg_tool_args,
|
||||
is_oiio_supported,
|
||||
)
|
||||
|
||||
from .attribute_definitions import (
|
||||
|
|
@ -172,7 +175,6 @@ __all__ = [
|
|||
"emit_event",
|
||||
"register_event_callback",
|
||||
|
||||
"find_executable",
|
||||
"get_openpype_execute_args",
|
||||
"get_linux_launcher_args",
|
||||
"execute",
|
||||
|
|
@ -186,9 +188,13 @@ __all__ = [
|
|||
"env_value_to_bool",
|
||||
"get_paths_from_environ",
|
||||
|
||||
"ToolNotFoundError",
|
||||
"find_executable",
|
||||
"get_vendor_bin_path",
|
||||
"get_oiio_tools_path",
|
||||
"get_oiio_tool_args",
|
||||
"get_ffmpeg_tool_path",
|
||||
"get_ffmpeg_tool_args",
|
||||
"is_oiio_supported",
|
||||
|
||||
"AbstractAttrDef",
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import xml.etree.ElementTree
|
|||
|
||||
from .execute import run_subprocess
|
||||
from .vendor_bin_utils import (
|
||||
get_ffmpeg_tool_path,
|
||||
get_oiio_tools_path,
|
||||
get_ffmpeg_tool_args,
|
||||
get_oiio_tool_args,
|
||||
is_oiio_supported,
|
||||
)
|
||||
|
||||
|
|
@ -83,11 +83,11 @@ def get_oiio_info_for_input(filepath, logger=None, subimages=False):
|
|||
|
||||
Stdout should contain xml format string.
|
||||
"""
|
||||
args = [
|
||||
get_oiio_tools_path(),
|
||||
args = get_oiio_tool_args(
|
||||
"oiiotool",
|
||||
"--info",
|
||||
"-v"
|
||||
]
|
||||
)
|
||||
if subimages:
|
||||
args.append("-a")
|
||||
|
||||
|
|
@ -486,12 +486,11 @@ def convert_for_ffmpeg(
|
|||
compression = "none"
|
||||
|
||||
# Prepare subprocess arguments
|
||||
oiio_cmd = [
|
||||
get_oiio_tools_path(),
|
||||
|
||||
oiio_cmd = get_oiio_tool_args(
|
||||
"oiiotool",
|
||||
# Don't add any additional attributes
|
||||
"--nosoftwareattrib",
|
||||
]
|
||||
)
|
||||
# Add input compression if available
|
||||
if compression:
|
||||
oiio_cmd.extend(["--compression", compression])
|
||||
|
|
@ -656,12 +655,11 @@ def convert_input_paths_for_ffmpeg(
|
|||
|
||||
for input_path in input_paths:
|
||||
# Prepare subprocess arguments
|
||||
oiio_cmd = [
|
||||
get_oiio_tools_path(),
|
||||
|
||||
oiio_cmd = get_oiio_tool_args(
|
||||
"oiiotool",
|
||||
# Don't add any additional attributes
|
||||
"--nosoftwareattrib",
|
||||
]
|
||||
)
|
||||
# Add input compression if available
|
||||
if compression:
|
||||
oiio_cmd.extend(["--compression", compression])
|
||||
|
|
@ -729,8 +727,8 @@ def get_ffprobe_data(path_to_file, logger=None):
|
|||
logger.info(
|
||||
"Getting information about input \"{}\".".format(path_to_file)
|
||||
)
|
||||
args = [
|
||||
get_ffmpeg_tool_path("ffprobe"),
|
||||
ffprobe_args = get_ffmpeg_tool_args("ffprobe")
|
||||
args = ffprobe_args + [
|
||||
"-hide_banner",
|
||||
"-loglevel", "fatal",
|
||||
"-show_error",
|
||||
|
|
@ -1084,13 +1082,13 @@ def convert_colorspace(
|
|||
if logger is None:
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
oiio_cmd = [
|
||||
get_oiio_tools_path(),
|
||||
oiio_cmd = get_oiio_tool_args(
|
||||
"oiiotool",
|
||||
input_path,
|
||||
# Don't add any additional attributes
|
||||
"--nosoftwareattrib",
|
||||
"--colorconfig", config_path
|
||||
]
|
||||
)
|
||||
|
||||
if all([target_colorspace, view, display]):
|
||||
raise ValueError("Colorspace and both screen and display"
|
||||
|
|
|
|||
|
|
@ -3,9 +3,15 @@ import logging
|
|||
import platform
|
||||
import subprocess
|
||||
|
||||
from openpype import AYON_SERVER_ENABLED
|
||||
|
||||
log = logging.getLogger("Vendor utils")
|
||||
|
||||
|
||||
class ToolNotFoundError(Exception):
|
||||
"""Raised when tool arguments are not found."""
|
||||
|
||||
|
||||
class CachedToolPaths:
|
||||
"""Cache already used and discovered tools and their executables.
|
||||
|
||||
|
|
@ -252,7 +258,7 @@ def _check_args_returncode(args):
|
|||
return proc.returncode == 0
|
||||
|
||||
|
||||
def _oiio_executable_validation(filepath):
|
||||
def _oiio_executable_validation(args):
|
||||
"""Validate oiio tool executable if can be executed.
|
||||
|
||||
Validation has 2 steps. First is using 'find_executable' to fill possible
|
||||
|
|
@ -270,32 +276,63 @@ def _oiio_executable_validation(filepath):
|
|||
should be used.
|
||||
|
||||
Args:
|
||||
filepath (str): Path to executable.
|
||||
args (Union[str, list[str]]): Arguments to launch tool or
|
||||
path to tool executable.
|
||||
|
||||
Returns:
|
||||
bool: Filepath is valid executable.
|
||||
"""
|
||||
|
||||
filepath = find_executable(filepath)
|
||||
if not filepath:
|
||||
if not args:
|
||||
return False
|
||||
|
||||
return _check_args_returncode([filepath, "--help"])
|
||||
if not isinstance(args, list):
|
||||
filepath = find_executable(args)
|
||||
if not filepath:
|
||||
return False
|
||||
args = [filepath]
|
||||
return _check_args_returncode(args + ["--help"])
|
||||
|
||||
|
||||
def _get_ayon_oiio_tool_args(tool_name):
|
||||
try:
|
||||
# Use 'ayon-third-party' addon to get oiio arguments
|
||||
from ayon_third_party import get_oiio_arguments
|
||||
except Exception:
|
||||
print("!!! Failed to import 'ayon_third_party' addon.")
|
||||
return None
|
||||
|
||||
try:
|
||||
return get_oiio_arguments(tool_name)
|
||||
except Exception as exc:
|
||||
print("!!! Failed to get OpenImageIO args. Reason: {}".format(exc))
|
||||
return None
|
||||
|
||||
|
||||
def get_oiio_tools_path(tool="oiiotool"):
|
||||
"""Path to vendorized OpenImageIO tool executables.
|
||||
"""Path to OpenImageIO tool executables.
|
||||
|
||||
On Window it adds .exe extension if missing from tool argument.
|
||||
On Windows it adds .exe extension if missing from tool argument.
|
||||
|
||||
Args:
|
||||
tool (string): Tool name (oiiotool, maketx, ...).
|
||||
tool (string): Tool name 'oiiotool', 'maketx', etc.
|
||||
Default is "oiiotool".
|
||||
"""
|
||||
|
||||
if CachedToolPaths.is_tool_cached(tool):
|
||||
return CachedToolPaths.get_executable_path(tool)
|
||||
|
||||
if AYON_SERVER_ENABLED:
|
||||
args = _get_ayon_oiio_tool_args(tool)
|
||||
if args:
|
||||
if len(args) > 1:
|
||||
raise ValueError(
|
||||
"AYON oiio arguments consist of multiple arguments."
|
||||
)
|
||||
tool_executable_path = args[0]
|
||||
CachedToolPaths.cache_executable_path(tool, tool_executable_path)
|
||||
return tool_executable_path
|
||||
|
||||
custom_paths_str = os.environ.get("OPENPYPE_OIIO_PATHS") or ""
|
||||
tool_executable_path = find_tool_in_custom_paths(
|
||||
custom_paths_str.split(os.pathsep),
|
||||
|
|
@ -321,7 +358,33 @@ def get_oiio_tools_path(tool="oiiotool"):
|
|||
return tool_executable_path
|
||||
|
||||
|
||||
def _ffmpeg_executable_validation(filepath):
|
||||
def get_oiio_tool_args(tool_name, *extra_args):
|
||||
"""Arguments to launch OpenImageIO tool.
|
||||
|
||||
Args:
|
||||
tool_name (str): Tool name 'oiiotool', 'maketx', etc.
|
||||
*extra_args (str): Extra arguments to add to after tool arguments.
|
||||
|
||||
Returns:
|
||||
list[str]: List of arguments.
|
||||
"""
|
||||
|
||||
extra_args = list(extra_args)
|
||||
|
||||
if AYON_SERVER_ENABLED:
|
||||
args = _get_ayon_oiio_tool_args(tool_name)
|
||||
if args:
|
||||
return args + extra_args
|
||||
|
||||
path = get_oiio_tools_path(tool_name)
|
||||
if path:
|
||||
return [path] + extra_args
|
||||
raise ToolNotFoundError(
|
||||
"OIIO '{}' tool not found.".format(tool_name)
|
||||
)
|
||||
|
||||
|
||||
def _ffmpeg_executable_validation(args):
|
||||
"""Validate ffmpeg tool executable if can be executed.
|
||||
|
||||
Validation has 2 steps. First is using 'find_executable' to fill possible
|
||||
|
|
@ -338,24 +401,45 @@ def _ffmpeg_executable_validation(filepath):
|
|||
It does not validate if the executable is really a ffmpeg tool.
|
||||
|
||||
Args:
|
||||
filepath (str): Path to executable.
|
||||
args (Union[str, list[str]]): Arguments to launch tool or
|
||||
path to tool executable.
|
||||
|
||||
Returns:
|
||||
bool: Filepath is valid executable.
|
||||
"""
|
||||
|
||||
filepath = find_executable(filepath)
|
||||
if not filepath:
|
||||
if not args:
|
||||
return False
|
||||
|
||||
return _check_args_returncode([filepath, "-version"])
|
||||
if not isinstance(args, list):
|
||||
filepath = find_executable(args)
|
||||
if not filepath:
|
||||
return False
|
||||
args = [filepath]
|
||||
return _check_args_returncode(args + ["--help"])
|
||||
|
||||
|
||||
def _get_ayon_ffmpeg_tool_args(tool_name):
|
||||
try:
|
||||
# Use 'ayon-third-party' addon to get ffmpeg arguments
|
||||
from ayon_third_party import get_ffmpeg_arguments
|
||||
|
||||
except Exception:
|
||||
print("!!! Failed to import 'ayon_third_party' addon.")
|
||||
return None
|
||||
|
||||
try:
|
||||
return get_ffmpeg_arguments(tool_name)
|
||||
except Exception as exc:
|
||||
print("!!! Failed to get FFmpeg args. Reason: {}".format(exc))
|
||||
return None
|
||||
|
||||
|
||||
def get_ffmpeg_tool_path(tool="ffmpeg"):
|
||||
"""Path to vendorized FFmpeg executable.
|
||||
|
||||
Args:
|
||||
tool (string): Tool name (ffmpeg, ffprobe, ...).
|
||||
tool (str): Tool name 'ffmpeg', 'ffprobe', etc.
|
||||
Default is "ffmpeg".
|
||||
|
||||
Returns:
|
||||
|
|
@ -365,6 +449,17 @@ def get_ffmpeg_tool_path(tool="ffmpeg"):
|
|||
if CachedToolPaths.is_tool_cached(tool):
|
||||
return CachedToolPaths.get_executable_path(tool)
|
||||
|
||||
if AYON_SERVER_ENABLED:
|
||||
args = _get_ayon_ffmpeg_tool_args(tool)
|
||||
if args is not None:
|
||||
if len(args) > 1:
|
||||
raise ValueError(
|
||||
"AYON ffmpeg arguments consist of multiple arguments."
|
||||
)
|
||||
tool_executable_path = args[0]
|
||||
CachedToolPaths.cache_executable_path(tool, tool_executable_path)
|
||||
return tool_executable_path
|
||||
|
||||
custom_paths_str = os.environ.get("OPENPYPE_FFMPEG_PATHS") or ""
|
||||
tool_executable_path = find_tool_in_custom_paths(
|
||||
custom_paths_str.split(os.pathsep),
|
||||
|
|
@ -390,19 +485,44 @@ def get_ffmpeg_tool_path(tool="ffmpeg"):
|
|||
return tool_executable_path
|
||||
|
||||
|
||||
def get_ffmpeg_tool_args(tool_name, *extra_args):
|
||||
"""Arguments to launch FFmpeg tool.
|
||||
|
||||
Args:
|
||||
tool_name (str): Tool name 'ffmpeg', 'ffprobe', exc.
|
||||
*extra_args (str): Extra arguments to add to after tool arguments.
|
||||
|
||||
Returns:
|
||||
list[str]: List of arguments.
|
||||
"""
|
||||
|
||||
extra_args = list(extra_args)
|
||||
|
||||
if AYON_SERVER_ENABLED:
|
||||
args = _get_ayon_ffmpeg_tool_args(tool_name)
|
||||
if args:
|
||||
return args + extra_args
|
||||
|
||||
executable_path = get_ffmpeg_tool_path(tool_name)
|
||||
if executable_path:
|
||||
return [executable_path] + extra_args
|
||||
raise ToolNotFoundError(
|
||||
"FFmpeg '{}' tool not found.".format(tool_name)
|
||||
)
|
||||
|
||||
|
||||
def is_oiio_supported():
|
||||
"""Checks if oiiotool is configured for this platform.
|
||||
|
||||
Returns:
|
||||
bool: OIIO tool executable is available.
|
||||
"""
|
||||
loaded_path = oiio_path = get_oiio_tools_path()
|
||||
if oiio_path:
|
||||
oiio_path = find_executable(oiio_path)
|
||||
|
||||
if not oiio_path:
|
||||
log.debug("OIIOTool is not configured or not present at {}".format(
|
||||
loaded_path
|
||||
))
|
||||
try:
|
||||
args = get_oiio_tool_args("oiiotool")
|
||||
except ToolNotFoundError:
|
||||
args = None
|
||||
if not args:
|
||||
log.debug("OIIOTool is not configured or not present.")
|
||||
return False
|
||||
return True
|
||||
return _oiio_executable_validation(args)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import os
|
||||
import pyblish
|
||||
from openpype.lib import (
|
||||
get_ffmpeg_tool_path,
|
||||
get_ffmpeg_tool_args,
|
||||
run_subprocess
|
||||
)
|
||||
import tempfile
|
||||
|
|
@ -20,9 +20,6 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin):
|
|||
label = "Extract OTIO Audio Tracks"
|
||||
hosts = ["hiero", "resolve", "flame"]
|
||||
|
||||
# FFmpeg tools paths
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
def process(self, context):
|
||||
"""Convert otio audio track's content to audio representations
|
||||
|
||||
|
|
@ -91,13 +88,13 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin):
|
|||
# temp audio file
|
||||
audio_fpath = self.create_temp_file(name)
|
||||
|
||||
cmd = [
|
||||
self.ffmpeg_path,
|
||||
cmd = get_ffmpeg_tool_args(
|
||||
"ffmpeg",
|
||||
"-ss", str(start_sec),
|
||||
"-t", str(duration_sec),
|
||||
"-i", audio_file,
|
||||
audio_fpath
|
||||
]
|
||||
)
|
||||
|
||||
# run subprocess
|
||||
self.log.debug("Executing: {}".format(" ".join(cmd)))
|
||||
|
|
@ -210,13 +207,13 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin):
|
|||
max_duration_sec = max(end_secs)
|
||||
|
||||
# create empty cmd
|
||||
cmd = [
|
||||
self.ffmpeg_path,
|
||||
cmd = get_ffmpeg_tool_args(
|
||||
"ffmpeg",
|
||||
"-f", "lavfi",
|
||||
"-i", "anullsrc=channel_layout=stereo:sample_rate=48000",
|
||||
"-t", str(max_duration_sec),
|
||||
empty_fpath
|
||||
]
|
||||
)
|
||||
|
||||
# generate empty with ffmpeg
|
||||
# run subprocess
|
||||
|
|
@ -295,7 +292,7 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin):
|
|||
filters_tmp_filepath = tmp_file.name
|
||||
tmp_file.write(",".join(filters))
|
||||
|
||||
args = [self.ffmpeg_path]
|
||||
args = get_ffmpeg_tool_args("ffmpeg")
|
||||
args.extend(input_args)
|
||||
args.extend([
|
||||
"-filter_complex_script", filters_tmp_filepath,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import opentimelineio as otio
|
|||
from pyblish import api
|
||||
|
||||
from openpype.lib import (
|
||||
get_ffmpeg_tool_path,
|
||||
get_ffmpeg_tool_args,
|
||||
run_subprocess,
|
||||
)
|
||||
from openpype.pipeline import publish
|
||||
|
|
@ -338,8 +338,6 @@ class ExtractOTIOReview(publish.Extractor):
|
|||
Returns:
|
||||
otio.time.TimeRange: trimmed available range
|
||||
"""
|
||||
# get rendering app path
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
# create path and frame start to destination
|
||||
output_path, out_frame_start = self._get_ffmpeg_output()
|
||||
|
|
@ -348,7 +346,7 @@ class ExtractOTIOReview(publish.Extractor):
|
|||
out_frame_start += end_offset
|
||||
|
||||
# start command list
|
||||
command = [ffmpeg_path]
|
||||
command = get_ffmpeg_tool_args("ffmpeg")
|
||||
|
||||
input_extension = None
|
||||
if sequence:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ from copy import deepcopy
|
|||
import pyblish.api
|
||||
|
||||
from openpype.lib import (
|
||||
get_ffmpeg_tool_path,
|
||||
get_ffmpeg_tool_args,
|
||||
run_subprocess,
|
||||
)
|
||||
from openpype.pipeline import publish
|
||||
|
|
@ -75,14 +75,12 @@ class ExtractOTIOTrimmingVideo(publish.Extractor):
|
|||
otio_range (opentime.TimeRange): range to trim to
|
||||
|
||||
"""
|
||||
# get rendering app path
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
# create path to destination
|
||||
output_path = self._get_ffmpeg_output(input_file_path)
|
||||
|
||||
# start command list
|
||||
command = [ffmpeg_path]
|
||||
command = get_ffmpeg_tool_args("ffmpeg")
|
||||
|
||||
video_path = input_file_path
|
||||
frame_start = otio_range.start_time.value
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import re
|
|||
import copy
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
import six
|
||||
|
|
@ -11,7 +12,7 @@ import speedcopy
|
|||
import pyblish.api
|
||||
|
||||
from openpype.lib import (
|
||||
get_ffmpeg_tool_path,
|
||||
get_ffmpeg_tool_args,
|
||||
filter_profiles,
|
||||
path_to_subprocess_arg,
|
||||
run_subprocess,
|
||||
|
|
@ -72,9 +73,6 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
|
||||
alpha_exts = ["exr", "png", "dpx"]
|
||||
|
||||
# FFmpeg tools paths
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
# Preset attributes
|
||||
profiles = None
|
||||
|
||||
|
|
@ -787,8 +785,9 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
arg = arg.replace(identifier, "").strip()
|
||||
audio_filters.append(arg)
|
||||
|
||||
all_args = []
|
||||
all_args.append(path_to_subprocess_arg(self.ffmpeg_path))
|
||||
all_args = [
|
||||
subprocess.list2cmdline(get_ffmpeg_tool_args("ffmpeg"))
|
||||
]
|
||||
all_args.extend(input_args)
|
||||
if video_filters:
|
||||
all_args.append("-filter:v")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from pprint import pformat
|
||||
|
||||
import pyblish.api
|
||||
|
|
@ -7,7 +8,7 @@ import pyblish.api
|
|||
from openpype.lib import (
|
||||
path_to_subprocess_arg,
|
||||
run_subprocess,
|
||||
get_ffmpeg_tool_path,
|
||||
get_ffmpeg_tool_args,
|
||||
get_ffprobe_data,
|
||||
get_ffprobe_streams,
|
||||
get_ffmpeg_codec_args,
|
||||
|
|
@ -47,8 +48,6 @@ class ExtractReviewSlate(publish.Extractor):
|
|||
|
||||
self.log.info("_ slates_data: {}".format(pformat(slates_data)))
|
||||
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
if "reviewToWidth" in inst_data:
|
||||
use_legacy_code = True
|
||||
else:
|
||||
|
|
@ -260,7 +259,7 @@ class ExtractReviewSlate(publish.Extractor):
|
|||
_remove_at_end.append(slate_v_path)
|
||||
|
||||
slate_args = [
|
||||
path_to_subprocess_arg(ffmpeg_path),
|
||||
subprocess.list2cmdline(get_ffmpeg_tool_args("ffmpeg")),
|
||||
" ".join(input_args),
|
||||
" ".join(output_args)
|
||||
]
|
||||
|
|
@ -281,7 +280,6 @@ class ExtractReviewSlate(publish.Extractor):
|
|||
os.path.splitext(slate_v_path))
|
||||
_remove_at_end.append(slate_silent_path)
|
||||
self._create_silent_slate(
|
||||
ffmpeg_path,
|
||||
slate_v_path,
|
||||
slate_silent_path,
|
||||
audio_codec,
|
||||
|
|
@ -309,12 +307,12 @@ class ExtractReviewSlate(publish.Extractor):
|
|||
"[0:v] [1:v] concat=n=2:v=1:a=0 [v]",
|
||||
"-map", '[v]'
|
||||
]
|
||||
concat_args = [
|
||||
ffmpeg_path,
|
||||
concat_args = get_ffmpeg_tool_args(
|
||||
"ffmpeg",
|
||||
"-y",
|
||||
"-i", slate_v_path,
|
||||
"-i", input_path,
|
||||
]
|
||||
)
|
||||
concat_args.extend(fmap)
|
||||
if offset_timecode:
|
||||
concat_args.extend(["-timecode", offset_timecode])
|
||||
|
|
@ -490,7 +488,6 @@ class ExtractReviewSlate(publish.Extractor):
|
|||
|
||||
def _create_silent_slate(
|
||||
self,
|
||||
ffmpeg_path,
|
||||
src_path,
|
||||
dst_path,
|
||||
audio_codec,
|
||||
|
|
@ -515,8 +512,8 @@ class ExtractReviewSlate(publish.Extractor):
|
|||
one_frame_duration = str(int(one_frame_duration)) + "us"
|
||||
self.log.debug("One frame duration is {}".format(one_frame_duration))
|
||||
|
||||
slate_silent_args = [
|
||||
ffmpeg_path,
|
||||
slate_silent_args = get_ffmpeg_tool_args(
|
||||
"ffmpeg",
|
||||
"-i", src_path,
|
||||
"-f", "lavfi", "-i",
|
||||
"anullsrc=r={}:cl={}:d={}".format(
|
||||
|
|
@ -531,7 +528,7 @@ class ExtractReviewSlate(publish.Extractor):
|
|||
"-shortest",
|
||||
"-y",
|
||||
dst_path
|
||||
]
|
||||
)
|
||||
# run slate generation subprocess
|
||||
self.log.debug("Silent Slate Executing: {}".format(
|
||||
" ".join(slate_silent_args)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,12 @@ import shutil
|
|||
|
||||
import pyblish.api
|
||||
|
||||
from openpype.lib import run_subprocess, get_oiio_tools_path
|
||||
from openpype.lib import (
|
||||
run_subprocess,
|
||||
get_oiio_tool_args,
|
||||
ToolNotFoundError,
|
||||
)
|
||||
from openpype.pipeline import KnownPublishError
|
||||
|
||||
|
||||
class ExtractScanlineExr(pyblish.api.InstancePlugin):
|
||||
|
|
@ -45,11 +50,11 @@ class ExtractScanlineExr(pyblish.api.InstancePlugin):
|
|||
|
||||
stagingdir = os.path.normpath(repre.get("stagingDir"))
|
||||
|
||||
oiio_tool_path = get_oiio_tools_path()
|
||||
if not os.path.exists(oiio_tool_path):
|
||||
self.log.error(
|
||||
"OIIO tool not found in {}".format(oiio_tool_path))
|
||||
raise AssertionError("OIIO tool not found")
|
||||
try:
|
||||
oiio_tool_args = get_oiio_tool_args("oiiotool")
|
||||
except ToolNotFoundError:
|
||||
self.log.error("OIIO tool not found.")
|
||||
raise KnownPublishError("OIIO tool not found")
|
||||
|
||||
for file in input_files:
|
||||
|
||||
|
|
@ -57,8 +62,7 @@ class ExtractScanlineExr(pyblish.api.InstancePlugin):
|
|||
temp_name = os.path.join(stagingdir, "__{}".format(file))
|
||||
# move original render to temp location
|
||||
shutil.move(original_name, temp_name)
|
||||
oiio_cmd = [
|
||||
oiio_tool_path,
|
||||
oiio_cmd = oiio_tool_args + [
|
||||
os.path.join(stagingdir, temp_name), "--scanline", "-o",
|
||||
os.path.join(stagingdir, original_name)
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
import pyblish.api
|
||||
from openpype.lib import (
|
||||
get_ffmpeg_tool_path,
|
||||
get_oiio_tools_path,
|
||||
get_ffmpeg_tool_args,
|
||||
get_oiio_tool_args,
|
||||
is_oiio_supported,
|
||||
|
||||
run_subprocess,
|
||||
|
|
@ -174,12 +175,11 @@ class ExtractThumbnail(pyblish.api.InstancePlugin):
|
|||
|
||||
def create_thumbnail_oiio(self, src_path, dst_path):
|
||||
self.log.info("Extracting thumbnail {}".format(dst_path))
|
||||
oiio_tool_path = get_oiio_tools_path()
|
||||
oiio_cmd = [
|
||||
oiio_tool_path,
|
||||
oiio_cmd = get_oiio_tool_args(
|
||||
"oiiotool",
|
||||
"-a", src_path,
|
||||
"-o", dst_path
|
||||
]
|
||||
)
|
||||
self.log.debug("running: {}".format(" ".join(oiio_cmd)))
|
||||
try:
|
||||
run_subprocess(oiio_cmd, logger=self.log)
|
||||
|
|
@ -194,27 +194,27 @@ class ExtractThumbnail(pyblish.api.InstancePlugin):
|
|||
def create_thumbnail_ffmpeg(self, src_path, dst_path):
|
||||
self.log.info("outputting {}".format(dst_path))
|
||||
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
ffmpeg_path_args = get_ffmpeg_tool_args("ffmpeg")
|
||||
ffmpeg_args = self.ffmpeg_args or {}
|
||||
|
||||
jpeg_items = []
|
||||
jpeg_items.append(path_to_subprocess_arg(ffmpeg_path))
|
||||
# override file if already exists
|
||||
jpeg_items.append("-y")
|
||||
jpeg_items = [
|
||||
subprocess.list2cmdline(ffmpeg_path_args)
|
||||
]
|
||||
# flag for large file sizes
|
||||
max_int = 2147483647
|
||||
jpeg_items.append("-analyzeduration {}".format(max_int))
|
||||
jpeg_items.append("-probesize {}".format(max_int))
|
||||
jpeg_items.extend([
|
||||
"-y",
|
||||
"-analyzeduration", str(max_int),
|
||||
"-probesize", str(max_int),
|
||||
])
|
||||
# use same input args like with mov
|
||||
jpeg_items.extend(ffmpeg_args.get("input") or [])
|
||||
# input file
|
||||
jpeg_items.append("-i {}".format(
|
||||
path_to_subprocess_arg(src_path)
|
||||
))
|
||||
jpeg_items.extend(["-i", path_to_subprocess_arg(src_path)])
|
||||
# output arguments from presets
|
||||
jpeg_items.extend(ffmpeg_args.get("output") or [])
|
||||
# we just want one frame from movie files
|
||||
jpeg_items.append("-vframes 1")
|
||||
jpeg_items.extend(["-vframes", "1"])
|
||||
# output file
|
||||
jpeg_items.append(path_to_subprocess_arg(dst_path))
|
||||
subprocess_command = " ".join(jpeg_items)
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ import tempfile
|
|||
|
||||
import pyblish.api
|
||||
from openpype.lib import (
|
||||
get_ffmpeg_tool_path,
|
||||
get_oiio_tools_path,
|
||||
get_ffmpeg_tool_args,
|
||||
get_oiio_tool_args,
|
||||
is_oiio_supported,
|
||||
|
||||
run_subprocess,
|
||||
|
|
@ -144,12 +144,11 @@ class ExtractThumbnailFromSource(pyblish.api.InstancePlugin):
|
|||
|
||||
def create_thumbnail_oiio(self, src_path, dst_path):
|
||||
self.log.info("outputting {}".format(dst_path))
|
||||
oiio_tool_path = get_oiio_tools_path()
|
||||
oiio_cmd = [
|
||||
oiio_tool_path,
|
||||
oiio_cmd = get_oiio_tool_args(
|
||||
"oiiotool",
|
||||
"-a", src_path,
|
||||
"-o", dst_path
|
||||
]
|
||||
)
|
||||
self.log.info("Running: {}".format(" ".join(oiio_cmd)))
|
||||
try:
|
||||
run_subprocess(oiio_cmd, logger=self.log)
|
||||
|
|
@ -162,18 +161,16 @@ class ExtractThumbnailFromSource(pyblish.api.InstancePlugin):
|
|||
return False
|
||||
|
||||
def create_thumbnail_ffmpeg(self, src_path, dst_path):
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
max_int = str(2147483647)
|
||||
ffmpeg_cmd = [
|
||||
ffmpeg_path,
|
||||
ffmpeg_cmd = get_ffmpeg_tool_args(
|
||||
"ffmpeg",
|
||||
"-y",
|
||||
"-analyzeduration", max_int,
|
||||
"-probesize", max_int,
|
||||
"-i", src_path,
|
||||
"-vframes", "1",
|
||||
dst_path
|
||||
]
|
||||
)
|
||||
|
||||
self.log.info("Running: {}".format(" ".join(ffmpeg_cmd)))
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from pprint import pformat
|
|||
import pyblish.api
|
||||
|
||||
from openpype.lib import (
|
||||
get_ffmpeg_tool_path,
|
||||
get_ffmpeg_tool_args,
|
||||
run_subprocess,
|
||||
)
|
||||
from openpype.pipeline import publish
|
||||
|
|
@ -32,7 +32,7 @@ class ExtractTrimVideoAudio(publish.Extractor):
|
|||
instance.data["representations"] = list()
|
||||
|
||||
# get ffmpet path
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
ffmpeg_tool_args = get_ffmpeg_tool_args("ffmpeg")
|
||||
|
||||
# get staging dir
|
||||
staging_dir = self.staging_dir(instance)
|
||||
|
|
@ -76,8 +76,7 @@ class ExtractTrimVideoAudio(publish.Extractor):
|
|||
if "trimming" not in fml
|
||||
]
|
||||
|
||||
ffmpeg_args = [
|
||||
ffmpeg_path,
|
||||
ffmpeg_args = ffmpeg_tool_args + [
|
||||
"-ss", str(clip_start_h / fps),
|
||||
"-i", video_file_path,
|
||||
"-t", str(clip_dur_h / fps)
|
||||
|
|
|
|||
|
|
@ -8,21 +8,15 @@ from string import Formatter
|
|||
|
||||
import opentimelineio_contrib.adapters.ffmpeg_burnins as ffmpeg_burnins
|
||||
from openpype.lib import (
|
||||
get_ffmpeg_tool_path,
|
||||
get_ffmpeg_tool_args,
|
||||
get_ffmpeg_codec_args,
|
||||
get_ffmpeg_format_args,
|
||||
convert_ffprobe_fps_value,
|
||||
convert_ffprobe_fps_to_float,
|
||||
)
|
||||
|
||||
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
ffprobe_path = get_ffmpeg_tool_path("ffprobe")
|
||||
|
||||
|
||||
FFMPEG = (
|
||||
'"{}"%(input_args)s -i "%(input)s" %(filters)s %(args)s%(output)s'
|
||||
).format(ffmpeg_path)
|
||||
'{}%(input_args)s -i "%(input)s" %(filters)s %(args)s%(output)s'
|
||||
).format(subprocess.list2cmdline(get_ffmpeg_tool_args("ffmpeg")))
|
||||
|
||||
DRAWTEXT = (
|
||||
"drawtext@'%(label)s'=fontfile='%(font)s':text=\\'%(text)s\\':"
|
||||
|
|
@ -46,14 +40,14 @@ def _get_ffprobe_data(source):
|
|||
:param str source: source media file
|
||||
:rtype: [{}, ...]
|
||||
"""
|
||||
command = [
|
||||
ffprobe_path,
|
||||
command = get_ffmpeg_tool_args(
|
||||
"ffprobe",
|
||||
"-v", "quiet",
|
||||
"-print_format", "json",
|
||||
"-show_format",
|
||||
"-show_streams",
|
||||
source
|
||||
]
|
||||
)
|
||||
kwargs = {
|
||||
"stdout": subprocess.PIPE,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ from openpype.style import get_objected_colors
|
|||
from openpype.lib import (
|
||||
run_subprocess,
|
||||
is_oiio_supported,
|
||||
get_oiio_tools_path,
|
||||
get_ffmpeg_tool_path,
|
||||
get_oiio_tool_args,
|
||||
get_ffmpeg_tool_args,
|
||||
)
|
||||
from openpype.lib.transcoding import (
|
||||
IMAGE_EXTENSIONS,
|
||||
|
|
@ -481,12 +481,12 @@ def _convert_thumbnail_oiio(src_path, dst_path):
|
|||
if not is_oiio_supported():
|
||||
return None
|
||||
|
||||
oiio_cmd = [
|
||||
get_oiio_tools_path(),
|
||||
oiio_cmd = get_oiio_tool_args(
|
||||
"oiiotool",
|
||||
"-i", src_path,
|
||||
"--subimage", "0",
|
||||
"-o", dst_path
|
||||
]
|
||||
)
|
||||
try:
|
||||
_run_silent_subprocess(oiio_cmd)
|
||||
except Exception:
|
||||
|
|
@ -495,12 +495,12 @@ def _convert_thumbnail_oiio(src_path, dst_path):
|
|||
|
||||
|
||||
def _convert_thumbnail_ffmpeg(src_path, dst_path):
|
||||
ffmpeg_cmd = [
|
||||
get_ffmpeg_tool_path(),
|
||||
ffmpeg_cmd = get_ffmpeg_tool_args(
|
||||
"ffmpeg",
|
||||
"-y",
|
||||
"-i", src_path,
|
||||
dst_path
|
||||
]
|
||||
)
|
||||
try:
|
||||
_run_silent_subprocess(ffmpeg_cmd)
|
||||
except Exception:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import clique
|
|||
import subprocess
|
||||
import openpype.lib
|
||||
from qtpy import QtWidgets, QtCore
|
||||
|
||||
from openpype.lib import get_ffprobe_data
|
||||
from . import DropEmpty, ComponentsList, ComponentItem
|
||||
|
||||
|
||||
|
|
@ -269,26 +271,8 @@ class DropDataFrame(QtWidgets.QFrame):
|
|||
self._process_data(data)
|
||||
|
||||
def load_data_with_probe(self, filepath):
|
||||
ffprobe_path = openpype.lib.get_ffmpeg_tool_path("ffprobe")
|
||||
args = [
|
||||
"\"{}\"".format(ffprobe_path),
|
||||
'-v', 'quiet',
|
||||
'-print_format json',
|
||||
'-show_format',
|
||||
'-show_streams',
|
||||
'"{}"'.format(filepath)
|
||||
]
|
||||
ffprobe_p = subprocess.Popen(
|
||||
' '.join(args),
|
||||
stdout=subprocess.PIPE,
|
||||
shell=True
|
||||
)
|
||||
ffprobe_output = ffprobe_p.communicate()[0]
|
||||
if ffprobe_p.returncode != 0:
|
||||
raise RuntimeError(
|
||||
'Failed on ffprobe: check if ffprobe path is set in PATH env'
|
||||
)
|
||||
return json.loads(ffprobe_output)['streams'][0]
|
||||
ffprobe_data = get_ffprobe_data(filepath)
|
||||
return ffprobe_data["streams"][0]
|
||||
|
||||
def get_file_data(self, data):
|
||||
filepath = data['files'][0]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue