mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge branch 'develop' into enhancement/AY-4911_Move-Celaction-client-code
This commit is contained in:
commit
eac7e5f962
7 changed files with 244 additions and 51 deletions
|
|
@ -1,26 +1,23 @@
|
|||
Updated as of 26 May 2023
|
||||
Last Updated: 1 April 2024
|
||||
----------------------------
|
||||
In this package, you will find a brief introduction to the Scripting API for DaVinci Resolve Studio. Apart from this README.txt file, this package contains folders containing the basic import
|
||||
modules for scripting access (DaVinciResolve.py) and some representative examples.
|
||||
|
||||
From v16.2.0 onwards, the nodeIndex parameters accepted by SetLUT() and SetCDL() are 1-based instead of 0-based, i.e. 1 <= nodeIndex <= total number of nodes.
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
As with Blackmagic Design Fusion scripts, user scripts written in Lua and Python programming languages are supported. By default, scripts can be invoked from the Console window in the Fusion page,
|
||||
As with Blackmagic Fusion scripts, user scripts written in Lua and Python programming languages are supported. By default, scripts can be invoked from the Console window in the Fusion page,
|
||||
or via command line. This permission can be changed in Resolve Preferences, to be only from Console, or to be invoked from the local network. Please be aware of the security implications when
|
||||
allowing scripting access from outside of the Resolve application.
|
||||
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
DaVinci Resolve scripting requires one of the following to be installed (for all users):
|
||||
|
||||
Lua 5.1
|
||||
Python 2.7 64-bit
|
||||
Python >= 3.6 64-bit
|
||||
|
||||
Python 2.7 64-bit
|
||||
|
||||
Using a script
|
||||
--------------
|
||||
|
|
@ -64,6 +61,7 @@ The interactive Console window allows for an easy way to execute simple scriptin
|
|||
and Lua and evaluates and executes them immediately. For more information on how to use the Console, please refer to the DaVinci Resolve User Manual.
|
||||
|
||||
This example Python script creates a simple project:
|
||||
|
||||
#!/usr/bin/env python
|
||||
import DaVinciResolveScript as dvr_script
|
||||
resolve = dvr_script.scriptapp("Resolve")
|
||||
|
|
@ -80,9 +78,8 @@ Running DaVinci Resolve in headless mode
|
|||
DaVinci Resolve can be launched in a headless mode without the user interface using the -nogui command line option. When DaVinci Resolve is launched using this option, the user interface is disabled.
|
||||
However, the various scripting APIs will continue to work as expected.
|
||||
|
||||
|
||||
Basic Resolve API
|
||||
-----------------
|
||||
DaVinci Resolve API
|
||||
-------------------
|
||||
Some commonly used API functions are described below (*). As with the resolve object, each object is inspectable for properties and functions.
|
||||
|
||||
Resolve
|
||||
|
|
@ -101,6 +98,12 @@ Resolve
|
|||
SaveLayoutPreset(presetName) --> Bool # Saves current UI layout as a preset named 'presetName'.
|
||||
ImportLayoutPreset(presetFilePath, presetName) --> Bool # Imports preset from path 'presetFilePath'. The optional argument 'presetName' specifies how the preset shall be named. If not specified, the preset is named based on the filename.
|
||||
Quit() --> None # Quits the Resolve App.
|
||||
ImportRenderPreset(presetPath) --> Bool # Import a preset from presetPath (string) and set it as current preset for rendering.
|
||||
ExportRenderPreset(presetName, exportPath) --> Bool # Export a preset to a given path (string) if presetName(string) exists.
|
||||
ImportBurnInPreset(presetPath) --> Bool # Import a data burn in preset from a given presetPath (string)
|
||||
ExportBurnInPreset(presetName, exportPath) --> Bool # Export a data burn in preset to a given path (string) if presetName (string) exists.
|
||||
GetKeyframeMode() --> keyframeMode # Returns the currently set keyframe mode (int). Refer to section 'Keyframe Mode information' below for details.
|
||||
SetKeyframeMode(keyframeMode) --> Bool # Returns True when 'keyframeMode'(enum) is successfully set. Refer to section 'Keyframe Mode information' below for details.
|
||||
|
||||
ProjectManager
|
||||
ArchiveProject(projectName,
|
||||
|
|
@ -131,6 +134,14 @@ ProjectManager
|
|||
# 'DbType': 'Disk' or 'PostgreSQL' (string)
|
||||
# 'DbName': database name (string)
|
||||
# 'IpAddress': IP address of the PostgreSQL server (string, optional key - defaults to '127.0.0.1')
|
||||
CreateCloudProject({cloudSettings}) --> Project # Creates and returns a cloud project.
|
||||
# '{cloudSettings}': Check 'Cloud Projects Settings' subsection below for more information.
|
||||
ImportCloudProject(filePath, {cloudSettings}) --> Bool # Returns True if import cloud project is successful; False otherwise
|
||||
# 'filePath': String; filePath of file to import
|
||||
# '{cloudSettings}': Check 'Cloud Projects Settings' subsection below for more information.
|
||||
RestoreCloudProject(folderPath, {cloudSettings}) --> Bool # Returns True if restore cloud project is successful; False otherwise
|
||||
# 'folderPath': String; path of folder to restore
|
||||
# '{cloudSettings}': Check 'Cloud Projects Settings' subsection below for more information.
|
||||
|
||||
Project
|
||||
GetMediaPool() --> MediaPool # Returns the Media Pool object.
|
||||
|
|
@ -175,6 +186,9 @@ Project
|
|||
startOffsetInSamples, durationInSamples)
|
||||
LoadBurnInPreset(presetName) --> Bool # Loads user defined data burn in preset for project when supplied presetName (string). Returns true if successful.
|
||||
ExportCurrentFrameAsStill(filePath) --> Bool # Exports current frame as still to supplied filePath. filePath must end in valid export file format. Returns True if succssful, False otherwise.
|
||||
GetColorGroupsList() --> [ColorGroups...] # Returns a list of all group objects in the timeline.
|
||||
AddColorGroup(groupName) --> ColorGroup # Creates a new ColorGroup. groupName must be a unique string.
|
||||
DeleteColorGroup(colorGroup) --> Bool # Deletes the given color group and sets clips to ungrouped.
|
||||
|
||||
MediaStorage
|
||||
GetMountedVolumeList() --> [paths...] # Returns list of folder paths corresponding to mounted volumes displayed in Resolve’s Media Storage.
|
||||
|
|
@ -198,7 +212,7 @@ MediaPool
|
|||
CreateTimelineFromClips(name, clip1, clip2,...) --> Timeline # Creates new timeline with specified name, and appends the specified MediaPoolItem objects.
|
||||
CreateTimelineFromClips(name, [clips]) --> Timeline # Creates new timeline with specified name, and appends the specified MediaPoolItem objects.
|
||||
CreateTimelineFromClips(name, [{clipInfo}]) --> Timeline # Creates new timeline with specified name, appending the list of clipInfos specified as a dict of "mediaPoolItem", "startFrame" (int), "endFrame" (int), "recordFrame" (int).
|
||||
ImportTimelineFromFile(filePath, {importOptions}) --> Timeline # Creates timeline based on parameters within given file (AAF/EDL/XML/FCPXML/DRT/ADL) and optional importOptions dict, with support for the keys:
|
||||
ImportTimelineFromFile(filePath, {importOptions}) --> Timeline # Creates timeline based on parameters within given file (AAF/EDL/XML/FCPXML/DRT/ADL/OTIO) and optional importOptions dict, with support for the keys:
|
||||
# "timelineName": string, specifies the name of the timeline to be created. Not valid for DRT import
|
||||
# "importSourceClips": Bool, specifies whether source clips should be imported, True by default. Not valid for DRT import
|
||||
# "sourceClipsPath": string, specifies a filesystem path to search for source clips if the media is inaccessible in their original path and if "importSourceClips" is True
|
||||
|
|
@ -225,6 +239,8 @@ MediaPool
|
|||
ExportMetadata(fileName, [clips]) --> Bool # Exports metadata of specified clips to 'fileName' in CSV format.
|
||||
# If no clips are specified, all clips from media pool will be used.
|
||||
GetUniqueId() --> string # Returns a unique ID for the media pool
|
||||
CreateStereoClip(LeftMediaPoolItem,
|
||||
RightMediaPoolItem) --> MediaPoolItem # Takes in two existing media pool items and creates a new 3D stereoscopic media pool entry replacing the input media in the media pool.
|
||||
|
||||
Folder
|
||||
GetClipList() --> [clips...] # Returns a list of clips (items) within the folder.
|
||||
|
|
@ -233,6 +249,8 @@ Folder
|
|||
GetIsFolderStale() --> bool # Returns true if folder is stale in collaboration mode, false otherwise
|
||||
GetUniqueId() --> string # Returns a unique ID for the media pool folder
|
||||
Export(filePath) --> bool # Returns true if export of DRB folder to filePath is successful, false otherwise
|
||||
TranscribeAudio() --> Bool # Transcribes audio of the MediaPoolItems within the folder and nested folders. Returns True if successful; False otherwise
|
||||
ClearTranscription() --> Bool # Clears audio transcription of the MediaPoolItems within the folder and nested folders. Returns True if successful; False otherwise.
|
||||
|
||||
MediaPoolItem
|
||||
GetName() --> string # Returns the clip name.
|
||||
|
|
@ -340,8 +358,12 @@ Timeline
|
|||
GrabStill() --> galleryStill # Grabs still from the current video clip. Returns a GalleryStill object.
|
||||
GrabAllStills(stillFrameSource) --> [galleryStill] # Grabs stills from all the clips of the timeline at 'stillFrameSource' (1 - First frame, 2 - Middle frame). Returns the list of GalleryStill objects.
|
||||
GetUniqueId() --> string # Returns a unique ID for the timeline
|
||||
CreateSubtitlesFromAudio() --> Bool # Creates subtitles from audio for the timeline. Returns True on success, False otherwise.
|
||||
CreateSubtitlesFromAudio({autoCaptionSettings}) --> Bool # Creates subtitles from audio for the timeline.
|
||||
# Takes in optional dictionary {autoCaptionSettings}. Check 'Auto Caption Settings' subsection below for more information.
|
||||
# Returns True on success, False otherwise.
|
||||
DetectSceneCuts() --> Bool # Detects and makes scene cuts along the timeline. Returns True if successful, False otherwise.
|
||||
ConvertTimelineToStereo() --> Bool # Converts timeline to stereo. Returns True if successful; False otherwise.
|
||||
GetNodeGraph() --> Graph # Returns the timeline's node graph object.
|
||||
|
||||
TimelineItem
|
||||
GetName() --> string # Returns the item name.
|
||||
|
|
@ -390,12 +412,7 @@ TimelineItem
|
|||
GetStereoConvergenceValues() --> {keyframes...} # Returns a dict (offset -> value) of keyframe offsets and respective convergence values.
|
||||
GetStereoLeftFloatingWindowParams() --> {keyframes...} # For the LEFT eye -> returns a dict (offset -> dict) of keyframe offsets and respective floating window params. Value at particular offset includes the left, right, top and bottom floating window values.
|
||||
GetStereoRightFloatingWindowParams() --> {keyframes...} # For the RIGHT eye -> returns a dict (offset -> dict) of keyframe offsets and respective floating window params. Value at particular offset includes the left, right, top and bottom floating window values.
|
||||
GetNumNodes() --> int # Returns the number of nodes in the current graph for the timeline item
|
||||
ApplyArriCdlLut() --> Bool # Applies ARRI CDL and LUT. Returns True if successful, False otherwise.
|
||||
SetLUT(nodeIndex, lutPath) --> Bool # Sets LUT on the node mapping the node index provided, 1 <= nodeIndex <= total number of nodes.
|
||||
# The lutPath can be an absolute path, or a relative path (based off custom LUT paths or the master LUT path).
|
||||
# The operation is successful for valid lut paths that Resolve has already discovered (see Project.RefreshLUTList).
|
||||
GetLUT(nodeIndex) --> String # Gets relative LUT path based on the node index provided, 1 <= nodeIndex <= total number of nodes.
|
||||
SetCDL([CDL map]) --> Bool # Keys of map are: "NodeIndex", "Slope", "Offset", "Power", "Saturation", where 1 <= NodeIndex <= total number of nodes.
|
||||
# Example python code - SetCDL({"NodeIndex" : "1", "Slope" : "0.5 0.4 0.2", "Offset" : "0.4 0.3 0.2", "Power" : "0.6 0.7 0.8", "Saturation" : "0.65"})
|
||||
AddTake(mediaPoolItem, startFrame, endFrame) --> Bool # Adds mediaPoolItem as a new take. Initializes a take selector for the timeline item if needed. By default, the full clip extents is added. startFrame (int) and endFrame (int) are optional arguments used to specify the extents.
|
||||
|
|
@ -411,11 +428,17 @@ TimelineItem
|
|||
UpdateSidecar() --> Bool # Updates sidecar file for BRAW clips or RMD file for R3D clips.
|
||||
GetUniqueId() --> string # Returns a unique ID for the timeline item
|
||||
LoadBurnInPreset(presetName) --> Bool # Loads user defined data burn in preset for clip when supplied presetName (string). Returns true if successful.
|
||||
GetNodeLabel(nodeIndex) --> string # Returns the label of the node at nodeIndex.
|
||||
CreateMagicMask(mode) --> Bool # Returns True if magic mask was created successfully, False otherwise. mode can "F" (forward), "B" (backward), or "BI" (bidirection)
|
||||
RegenerateMagicMask() --> Bool # Returns True if magic mask was regenerated successfully, False otherwise.
|
||||
Stabilize() --> Bool # Returns True if stabilization was successful, False otherwise
|
||||
SmartReframe() --> Bool # Performs Smart Reframe. Returns True if successful, False otherwise.
|
||||
GetNodeGraph() --> Graph # Returns the clip's node graph object.
|
||||
GetColorGroup() --> ColorGroup # Returns the clip's color group if one exists.
|
||||
AssignToColorGroup(ColorGroup) --> Bool # Returns True if TiItem to successfully assigned to given ColorGroup. ColorGroup must be an existing group in the current project.
|
||||
RemoveFromColorGroup() --> Bool # Returns True if the TiItem is successfully removed from the ColorGroup it is in.
|
||||
ExportLUT(exportType, path) --> Bool # Exports LUTs from tiItem referring to value passed in 'exportType' (enum) for LUT size. Refer to. 'ExportLUT notes' section for possible values.
|
||||
# Saves generated LUT in the provided 'path' (string). 'path' should include the intended file name.
|
||||
# If an empty or incorrect extension is provided, the appropriate extension (.cube/.vlt) will be appended at the end of the path.
|
||||
|
||||
Gallery
|
||||
GetAlbumName(galleryStillAlbum) --> string # Returns the name of the GalleryStillAlbum object 'galleryStillAlbum'.
|
||||
|
|
@ -428,17 +451,63 @@ GalleryStillAlbum
|
|||
GetStills() --> [galleryStill] # Returns the list of GalleryStill objects in the album.
|
||||
GetLabel(galleryStill) --> string # Returns the label of the galleryStill.
|
||||
SetLabel(galleryStill, label) --> Bool # Sets the new 'label' to GalleryStill object 'galleryStill'.
|
||||
ExportStills([galleryStill], folderPath, filePrefix, format) --> Bool # Exports list of GalleryStill objects '[galleryStill]' to directory 'folderPath', with filename prefix 'filePrefix', using file format 'format' (supported formats: dpx, cin, tif, jpg, png, ppm, bmp, xpm).
|
||||
ImportStills([filePaths]) --> Bool # Imports GalleryStill from each filePath in [filePaths] list. True if at least one still is imported successfully. False otherwise.
|
||||
ExportStills([galleryStill], folderPath, filePrefix, format) --> Bool # Exports list of GalleryStill objects '[galleryStill]' to directory 'folderPath', with filename prefix 'filePrefix', using file format 'format' (supported formats: dpx, cin, tif, jpg, png, ppm, bmp, xpm, drx).
|
||||
DeleteStills([galleryStill]) --> Bool # Deletes specified list of GalleryStill objects '[galleryStill]'.
|
||||
|
||||
GalleryStill # This class does not provide any API functions but the object type is used by functions in other classes.
|
||||
|
||||
Graph
|
||||
GetNumNodes() --> int # Returns the number of nodes in the graph
|
||||
SetLUT(nodeIndex, lutPath) --> Bool # Sets LUT on the node mapping the node index provided, 1 <= nodeIndex <= self.GetNumNodes().
|
||||
# The lutPath can be an absolute path, or a relative path (based off custom LUT paths or the master LUT path).
|
||||
# The operation is successful for valid lut paths that Resolve has already discovered (see Project.RefreshLUTList).
|
||||
GetLUT(nodeIndex) --> String # Gets relative LUT path based on the node index provided, 1 <= nodeIndex <= total number of nodes.
|
||||
GetNodeLabel(nodeIndex) --> string # Returns the label of the node at nodeIndex.
|
||||
GetToolsInNode(nodeIndex) --> [toolsList] # Returns toolsList (list of strings) of the tools used in the node indicated by given nodeIndex (int).
|
||||
|
||||
ColorGroup
|
||||
GetName() --> String # Returns the name (string) of the ColorGroup.
|
||||
SetName(groupName) --> Bool # Renames ColorGroup to groupName (string).
|
||||
GetClipsInTimeline(Timeline=CurrTimeline) --> [TimelineItem] # Returns a list of TimelineItem that are in colorGroup in the given Timeline. Timeline is Current Timeline by default.
|
||||
GetPreClipNodeGraph() --> Graph # Returns the ColorGroup Pre-clip graph.
|
||||
GetPostClipNodeGraph() --> Graph # Returns the ColorGroup Post-clip graph.
|
||||
|
||||
List and Dict Data Structures
|
||||
-----------------------------
|
||||
Beside primitive data types, Resolve's Python API mainly uses list and dict data structures. Lists are denoted by [ ... ] and dicts are denoted by { ... } above.
|
||||
As Lua does not support list and dict data structures, the Lua API implements "list" as a table with indices, e.g. { [1] = listValue1, [2] = listValue2, ... }.
|
||||
Similarly the Lua API implements "dict" as a table with the dictionary key as first element, e.g. { [dictKey1] = dictValue1, [dictKey2] = dictValue2, ... }.
|
||||
|
||||
Keyframe Mode information
|
||||
-------------------------
|
||||
This section covers additional notes for the functions Resolve.GetKeyframeMode() and Resolve.SetKeyframeMode(keyframeMode).
|
||||
|
||||
'keyframeMode' can be one of the following enums:
|
||||
- resolve.KEYFRAME_MODE_ALL == 0
|
||||
- resolve.KEYFRAME_MODE_COLOR == 1
|
||||
- resolve.KEYFRAME_MODE_SIZING == 2
|
||||
|
||||
Integer values returned by Resolve.GetKeyframeMode() will correspond to the enums above.
|
||||
|
||||
Cloud Projects Settings
|
||||
--------------------------------------
|
||||
This section covers additional notes for the functions "ProjectManager:CreateCloudProject," "ProjectManager:ImportCloudProject," and "ProjectManager:RestoreCloudProject"
|
||||
|
||||
All three functions take in a {cloudSettings} dict, that have the following keys:
|
||||
* resolve.CLOUD_SETTING_PROJECT_NAME: String, ["" by default]
|
||||
* resolve.CLOUD_SETTING_PROJECT_MEDIA_PATH: String, ["" by default]
|
||||
* resolve.CLOUD_SETTING_IS_COLLAB: Bool, [False by default]
|
||||
* resolve.CLOUD_SETTING_SYNC_MODE: syncMode (see below), [resolve.CLOUD_SYNC_PROXY_ONLY by default]
|
||||
* resolve.CLOUD_SETTING_IS_CAMERA_ACCESS: Bool [False by default]
|
||||
|
||||
Where syncMode is one of the following values:
|
||||
* resolve.CLOUD_SYNC_NONE,
|
||||
* resolve.CLOUD_SYNC_PROXY_ONLY,
|
||||
* resolve.CLOUD_SYNC_PROXY_AND_ORIG
|
||||
|
||||
All three "ProjectManager:CreateCloudProject," "ProjectManager:ImportCloudProject," and "ProjectManager:RestoreCloudProject" require resolve.PROJECT_MEDIA_PATH to be defined. "ProjectManager:CreateCloudProject" also requires resolve.PROJECT_NAME to be defined.
|
||||
|
||||
Looking up Project and Clip properties
|
||||
--------------------------------------
|
||||
This section covers additional notes for the functions "Project:GetSetting", "Project:SetSetting", "Timeline:GetSetting", "Timeline:SetSetting", "MediaPoolItem:GetClipProperty" and
|
||||
|
|
@ -478,6 +547,49 @@ Affects:
|
|||
• x = MediaPoolItem:GetClipProperty('Super Scale') and MediaPoolItem:SetClipProperty('Super Scale', x)
|
||||
• for '2x Enhanced' --> MediaPoolItem:SetClipProperty('Super Scale', 2, sharpnessValue, noiseReductionValue), where sharpnessValue is a float in the range [0.0, 1.0] and noiseReductionValue is a float in the range [0.0, 1.0]
|
||||
|
||||
Auto Caption Settings
|
||||
----------------------
|
||||
This section covers the supported settings for the method Timeline.CreateSubtitlesFromAudio({autoCaptionSettings})
|
||||
|
||||
The parameter setting is a dictionary containing the following keys:
|
||||
* resolve.SUBTITLE_LANGUAGE: languageID (see below), [resolve.AUTO_CAPTION_AUTO by default]
|
||||
* resolve.SUBTITLE_CAPTION_PRESET: presetType (see below), [resolve.AUTO_CAPTION_SUBTITLE_DEFAULT by default]
|
||||
* resolve.SUBTITLE_CHARS_PER_LINE: Number between 1 and 60 inclusive [42 by default]
|
||||
* resolve.SUBTITLE_LINE_BREAK: lineBreakType (see below), [resolve.AUTO_CAPTION_LINE_SINGLE by default]
|
||||
* resolve.SUBTITLE_GAP: Number between 0 and 10 inclusive [0 by default]
|
||||
|
||||
Note that the default values for some keys may change based on values defined for other keys, as per the UI.
|
||||
For example, if the following dictionary is supplied,
|
||||
CreateSubtitlesFromAudio( { resolve.SUBTITLE_LANGUAGE = resolve.AUTO_CAPTION_KOREAN,
|
||||
resolve.SUBTITLE_CAPTION_PRESET = resolve.AUTO_CAPTION_NETFLIX } )
|
||||
the default value for resolve.SUBTITLE_CHARS_PER_LINE will be 16 instead of 42
|
||||
|
||||
languageIDs:
|
||||
* resolve.AUTO_CAPTION_AUTO
|
||||
* resolve.AUTO_CAPTION_DANISH
|
||||
* resolve.AUTO_CAPTION_DUTCH
|
||||
* resolve.AUTO_CAPTION_ENGLISH
|
||||
* resolve.AUTO_CAPTION_FRENCH
|
||||
* resolve.AUTO_CAPTION_GERMAN
|
||||
* resolve.AUTO_CAPTION_ITALIAN
|
||||
* resolve.AUTO_CAPTION_JAPANESE
|
||||
* resolve.AUTO_CAPTION_KOREAN
|
||||
* resolve.AUTO_CAPTION_MANDARIN_SIMPLIFIED
|
||||
* resolve.AUTO_CAPTION_MANDARIN_TRADITIONAL
|
||||
* resolve.AUTO_CAPTION_NORWEGIAN
|
||||
* resolve.AUTO_CAPTION_PORTUGUESE
|
||||
* resolve.AUTO_CAPTION_RUSSIAN
|
||||
* resolve.AUTO_CAPTION_SPANISH
|
||||
* resolve.AUTO_CAPTION_SWEDISH
|
||||
|
||||
presetTypes:
|
||||
* resolve.AUTO_CAPTION_SUBTITLE_DEFAULT
|
||||
* resolve.AUTO_CAPTION_TELETEXT
|
||||
* resolve.AUTO_CAPTION_NETFLIX
|
||||
|
||||
lineBreakTypes:
|
||||
* resolve.AUTO_CAPTION_LINE_SINGLE
|
||||
* resolve.AUTO_CAPTION_LINE_DOUBLE
|
||||
|
||||
Looking up Render Settings
|
||||
--------------------------
|
||||
|
|
@ -531,6 +643,8 @@ exportType can be one of the following constants:
|
|||
- resolve.EXPORT_DOLBY_VISION_VER_4_0
|
||||
- resolve.EXPORT_DOLBY_VISION_VER_5_1
|
||||
- resolve.EXPORT_OTIO
|
||||
- resolve.EXPORT_ALE
|
||||
- resolve.EXPORT_ALE_CDL
|
||||
exportSubtype can be one of the following enums:
|
||||
- resolve.EXPORT_NONE
|
||||
- resolve.EXPORT_AAF_NEW
|
||||
|
|
@ -627,7 +741,8 @@ The supported keys with their accepted values are:
|
|||
- MOTION_EST_STANDARD_BETTER
|
||||
- MOTION_EST_ENHANCED_FASTER
|
||||
- MOTION_EST_ENHANCED_BETTER
|
||||
- MOTION_EST_SPEED_WRAP
|
||||
- MOTION_EST_SPEED_WARP_BETTER
|
||||
- MOTION_EST_SPEED_WARP_FASTER
|
||||
"Scaling" : A value from the following constants
|
||||
- SCALE_USE_PROJECT = 0
|
||||
- SCALE_CROP
|
||||
|
|
@ -659,6 +774,16 @@ as a single argument.
|
|||
|
||||
Getting the values for the keys that uses constants will return the number which is in the constant
|
||||
|
||||
ExportLUT notes
|
||||
---------------
|
||||
The following section covers additional notes for TimelineItem.ExportLUT(exportType, path).
|
||||
|
||||
Supported values for 'exportType' (enum) are:
|
||||
- resolve.EXPORT_LUT_17PTCUBE
|
||||
- resolve.EXPORT_LUT_33PTCUBE
|
||||
- resolve.EXPORT_LUT_65PTCUBE
|
||||
- resolve.EXPORT_LUT_PANASONICVLUT
|
||||
|
||||
Deprecated Resolve API Functions
|
||||
--------------------------------
|
||||
The following API functions are deprecated.
|
||||
|
|
@ -693,7 +818,12 @@ TimelineItem
|
|||
GetFusionCompNames() --> {names...} # Returns a dict of Fusion composition names associated with the timeline item.
|
||||
GetFlags() --> {colors...} # Returns a dict of flag colors assigned to the item.
|
||||
GetVersionNames(versionType) --> {names...} # Returns a dict of version names by provided versionType: 0 - local, 1 - remote.
|
||||
|
||||
GetNumNodes() --> int # Returns the number of nodes in the current graph for the timeline item
|
||||
SetLUT(nodeIndex, lutPath) --> Bool # Sets LUT on the node mapping the node index provided, 1 <= nodeIndex <= total number of nodes.
|
||||
# The lutPath can be an absolute path, or a relative path (based off custom LUT paths or the master LUT path).
|
||||
# The operation is successful for valid lut paths that Resolve has already discovered (see Project.RefreshLUTList).
|
||||
GetLUT(nodeIndex) --> String # Gets relative LUT path based on the node index provided, 1 <= nodeIndex <= total number of nodes.
|
||||
GetNodeLabel(nodeIndex) --> string # Returns the label of the node at nodeIndex.
|
||||
|
||||
Unsupported Resolve API Functions
|
||||
---------------------------------
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
from pathlib import Path
|
||||
|
||||
from ayon_core.pipeline import (
|
||||
load,
|
||||
get_representation_path,
|
||||
)
|
||||
|
||||
from ayon_core.hosts.resolve.api import lib
|
||||
|
||||
|
||||
class LoadEditorialPackage(load.LoaderPlugin):
|
||||
"""Load editorial package to timeline.
|
||||
|
||||
Loading timeline from OTIO file included media sources
|
||||
and timeline structure.
|
||||
"""
|
||||
|
||||
product_types = {"editorial_pkg"}
|
||||
|
||||
representations = {"*"}
|
||||
extensions = {"otio"}
|
||||
|
||||
label = "Load as Timeline"
|
||||
order = -10
|
||||
icon = "ei.align-left"
|
||||
color = "orange"
|
||||
|
||||
def load(self, context, name, namespace, data):
|
||||
files = get_representation_path(context["representation"])
|
||||
|
||||
search_folder_path = Path(files).parent / "resources"
|
||||
|
||||
project = lib.get_current_project()
|
||||
media_pool = project.GetMediaPool()
|
||||
|
||||
# create versioned bin for editorial package
|
||||
version_name = context["version"]["name"]
|
||||
bin_name = f"{name}_{version_name}"
|
||||
lib.create_bin(bin_name)
|
||||
|
||||
import_options = {
|
||||
"timelineName": "Editorial Package Timeline",
|
||||
"importSourceClips": True,
|
||||
"sourceClipsPath": search_folder_path.as_posix(),
|
||||
}
|
||||
|
||||
timeline = media_pool.ImportTimelineFromFile(files, import_options)
|
||||
print("Timeline imported: ", timeline)
|
||||
|
||||
def update(self, container, context):
|
||||
# TODO: implement update method in future
|
||||
pass
|
||||
|
|
@ -16,13 +16,13 @@ class EditorialPackageCreator(TrayPublishCreator):
|
|||
"""Creates instance for OTIO file from published folder.
|
||||
|
||||
Folder contains OTIO file and exported .mov files. Process should publish
|
||||
whole folder as single `editorial_pckg` product type and (possibly) convert
|
||||
whole folder as single `editorial_pkg` product type and (possibly) convert
|
||||
.mov files into different format and copy them into `publish` `resources`
|
||||
subfolder.
|
||||
"""
|
||||
identifier = "editorial_pckg"
|
||||
identifier = "editorial_pkg"
|
||||
label = "Editorial package"
|
||||
product_type = "editorial_pckg"
|
||||
product_type = "editorial_pkg"
|
||||
description = "Publish folder with OTIO file and resources"
|
||||
|
||||
# Position batch creator after simple creators
|
||||
|
|
@ -89,8 +89,8 @@ class EditorialPackageCreator(TrayPublishCreator):
|
|||
def get_detail_description(self):
|
||||
return """# Publish folder with OTIO file and video clips
|
||||
|
||||
Folder contains OTIO file and exported .mov files. Process should
|
||||
publish whole folder as single `editorial_pckg` product type and
|
||||
(possibly) convert .mov files into different format and copy them into
|
||||
Folder contains OTIO file and exported .mov files. Process should
|
||||
publish whole folder as single `editorial_pkg` product type and
|
||||
(possibly) convert .mov files into different format and copy them into
|
||||
`publish` `resources` subfolder.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
"""Produces instance.data["editorial_pckg"] data used during integration.
|
||||
"""Produces instance.data["editorial_pkg"] data used during integration.
|
||||
|
||||
Requires:
|
||||
instance.data["creator_attributes"]["path"] - from creator
|
||||
|
||||
Provides:
|
||||
instance -> editorial_pckg (dict):
|
||||
instance -> editorial_pkg (dict):
|
||||
folder_path (str)
|
||||
otio_path (str) - from dragged folder
|
||||
resource_paths (list)
|
||||
|
|
@ -24,7 +24,7 @@ class CollectEditorialPackage(pyblish.api.InstancePlugin):
|
|||
order = pyblish.api.CollectorOrder - 0.1
|
||||
|
||||
hosts = ["traypublisher"]
|
||||
families = ["editorial_pckg"]
|
||||
families = ["editorial_pkg"]
|
||||
|
||||
def process(self, instance):
|
||||
folder_path = instance.data["creator_attributes"]["folder_path"]
|
||||
|
|
@ -34,14 +34,14 @@ class CollectEditorialPackage(pyblish.api.InstancePlugin):
|
|||
))
|
||||
return
|
||||
|
||||
instance.data["editorial_pckg"] = {}
|
||||
instance.data["editorial_pckg"]["folder_path"] = folder_path
|
||||
instance.data["editorial_pkg"] = {}
|
||||
instance.data["editorial_pkg"]["folder_path"] = folder_path
|
||||
|
||||
otio_path, resource_paths = (
|
||||
self._get_otio_and_resource_paths(folder_path))
|
||||
|
||||
instance.data["editorial_pckg"]["otio_path"] = otio_path
|
||||
instance.data["editorial_pckg"]["resource_paths"] = resource_paths
|
||||
instance.data["editorial_pkg"]["otio_path"] = otio_path
|
||||
instance.data["editorial_pkg"]["resource_paths"] = resource_paths
|
||||
|
||||
def _get_otio_and_resource_paths(self, folder_path):
|
||||
otio_path = None
|
||||
|
|
|
|||
|
|
@ -20,27 +20,27 @@ class ExtractEditorialPckgConversion(publish.Extractor):
|
|||
label = "Extract Editorial Package"
|
||||
order = pyblish.api.ExtractorOrder - 0.45
|
||||
hosts = ["traypublisher"]
|
||||
families = ["editorial_pckg"]
|
||||
families = ["editorial_pkg"]
|
||||
|
||||
def process(self, instance):
|
||||
editorial_pckg_data = instance.data.get("editorial_pckg")
|
||||
editorial_pkg_data = instance.data.get("editorial_pkg")
|
||||
|
||||
otio_path = editorial_pckg_data["otio_path"]
|
||||
otio_path = editorial_pkg_data["otio_path"]
|
||||
otio_basename = os.path.basename(otio_path)
|
||||
staging_dir = self.staging_dir(instance)
|
||||
|
||||
editorial_pckg_repre = {
|
||||
'name': "editorial_pckg",
|
||||
editorial_pkg_repre = {
|
||||
'name': "editorial_pkg",
|
||||
'ext': "otio",
|
||||
'files': otio_basename,
|
||||
"stagingDir": staging_dir,
|
||||
}
|
||||
otio_staging_path = os.path.join(staging_dir, otio_basename)
|
||||
|
||||
instance.data["representations"].append(editorial_pckg_repre)
|
||||
instance.data["representations"].append(editorial_pkg_repre)
|
||||
|
||||
publish_resource_folder = self._get_publish_resource_folder(instance)
|
||||
resource_paths = editorial_pckg_data["resource_paths"]
|
||||
resource_paths = editorial_pkg_data["resource_paths"]
|
||||
transfers = self._get_transfers(resource_paths,
|
||||
publish_resource_folder)
|
||||
|
||||
|
|
@ -61,13 +61,13 @@ class ExtractEditorialPckgConversion(publish.Extractor):
|
|||
source_to_rootless = self._get_resource_path_mapping(instance,
|
||||
transfers)
|
||||
|
||||
otio_data = editorial_pckg_data["otio_data"]
|
||||
otio_data = editorial_pkg_data["otio_data"]
|
||||
otio_data = self._replace_target_urls(otio_data, source_to_rootless)
|
||||
|
||||
opentimelineio.adapters.write_to_file(otio_data, otio_staging_path)
|
||||
|
||||
self.log.info("Added Editorial Package representation: {}".format(
|
||||
editorial_pckg_repre))
|
||||
editorial_pkg_repre))
|
||||
|
||||
def _get_publish_resource_folder(self, instance):
|
||||
"""Calculates publish folder and create it."""
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import os
|
||||
import opentimelineio
|
||||
from opentimelineio.exceptions import UnsupportedSchemaError
|
||||
|
||||
|
||||
import pyblish.api
|
||||
from ayon_core.pipeline import PublishValidationError
|
||||
|
|
@ -17,26 +19,35 @@ class ValidateEditorialPackage(pyblish.api.InstancePlugin):
|
|||
order = pyblish.api.ValidatorOrder - 0.49
|
||||
|
||||
hosts = ["traypublisher"]
|
||||
families = ["editorial_pckg"]
|
||||
families = ["editorial_pkg"]
|
||||
|
||||
def process(self, instance):
|
||||
editorial_pckg_data = instance.data.get("editorial_pckg")
|
||||
if not editorial_pckg_data:
|
||||
editorial_pkg_data = instance.data.get("editorial_pkg")
|
||||
if not editorial_pkg_data:
|
||||
raise PublishValidationError("Editorial package not collected")
|
||||
|
||||
folder_path = editorial_pckg_data["folder_path"]
|
||||
folder_path = editorial_pkg_data["folder_path"]
|
||||
|
||||
otio_path = editorial_pckg_data["otio_path"]
|
||||
otio_path = editorial_pkg_data["otio_path"]
|
||||
if not otio_path:
|
||||
raise PublishValidationError(
|
||||
f"Folder {folder_path} missing otio file")
|
||||
|
||||
resource_paths = editorial_pckg_data["resource_paths"]
|
||||
resource_paths = editorial_pkg_data["resource_paths"]
|
||||
|
||||
resource_file_names = {os.path.basename(path)
|
||||
for path in resource_paths}
|
||||
|
||||
otio_data = opentimelineio.adapters.read_from_file(otio_path)
|
||||
try:
|
||||
otio_data = opentimelineio.adapters.read_from_file(otio_path)
|
||||
except UnsupportedSchemaError as e:
|
||||
raise PublishValidationError(
|
||||
f"Unsupported schema in otio file '{otio_path}'."
|
||||
"Version of your OpenTimelineIO library is too old."
|
||||
"Please update it to the latest version."
|
||||
f"Current version is '{opentimelineio.__version__}', "
|
||||
"but required is at least 0.16.0."
|
||||
) from e
|
||||
|
||||
target_urls = self._get_all_target_urls(otio_data)
|
||||
missing_files = set()
|
||||
|
|
@ -50,7 +61,7 @@ class ValidateEditorialPackage(pyblish.api.InstancePlugin):
|
|||
f"Otio file contains missing files `{missing_files}`.\n\n"
|
||||
f"Please add them to `{folder_path}` and republish.")
|
||||
|
||||
instance.data["editorial_pckg"]["otio_data"] = otio_data
|
||||
instance.data["editorial_pkg"]["otio_data"] = otio_data
|
||||
|
||||
def _get_all_target_urls(self, otio_data):
|
||||
target_urls = []
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
name = "traypublisher"
|
||||
title = "TrayPublisher"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
|
||||
client_dir = "ayon_traypublisher"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue