Skip to content

Commit 428d9e5

Browse files
Add otio string deserialization
Signed-off-by: Éloïse Brosseau <[email protected]>
1 parent 27fad1a commit 428d9e5

File tree

5 files changed

+95
-3
lines changed

5 files changed

+95
-3
lines changed

docs/rv-packages/rv-otio-reader.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ The RV package is installed in the usual Python package installation location: `
1717
The package also uses a number of files located in `Plugins/SupportFiles/otio_reader` and detailed below.
1818

1919
- `manifest.json`: Provides examples of schemas and hooks used in the import process.
20+
- `annotation_schema.py` An example schema of an annotation.
2021
- `cdlExportHook.py`: An example of exporting an RVLinearize to a custom CDL effect in OTIO.
2122
- `cdlHook.py`: An example of importing a custom CDL effect in OTIO into an RVLinearize node.
2223
- `cdlSchema.py` An example schema of a CDL effect.

src/plugins/rv-packages/otio_reader/PACKAGE

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ modes:
1818
files:
1919
- file: manifest.json
2020
location: SupportFiles/$PACKAGE
21+
- file: annotation_schema.py
22+
location: SupportFiles/$PACKAGE
2123
- file: cdlSchema.py
2224
location: SupportFiles/$PACKAGE
2325
- file: cdlHook.py
@@ -83,6 +85,13 @@ description: |
8385
</p>
8486
</li>
8587

88+
<li>
89+
<p>
90+
annotation_schema.py
91+
An example schema of an annotation.
92+
</p>
93+
</li>
94+
8695
<li>
8796
<p>
8897
cdlHook.py
@@ -260,4 +269,3 @@ description: |
260269
<p>
261270
For pre- and post- hooks, no return value is expected.
262271
</p>
263-
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# *****************************************************************************
2+
# Copyright 2024 Autodesk, Inc. All rights reserved.
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
# *****************************************************************************
7+
8+
"""
9+
For our OTIO output to effectively interface with other programs
10+
using the OpenTimelineIO Python API, our custom schema need to be
11+
specified and registered with the API.
12+
13+
As per OTIO documentation, a class such as this one must be created,
14+
the schema must be registered with a PluginManifest, and the path to that
15+
manifest must be added to $OTIO_PLUGIN_MANIFEST_PATH; then the schema
16+
is ready to be used.
17+
18+
Example:
19+
myObject = otio.schemadef.Annotation.Annotation(name, visible, layers)
20+
"""
21+
22+
import opentimelineio as otio
23+
24+
25+
@otio.core.register_type
26+
class Annotation(otio.schema.Effect):
27+
"""A schema for annotations."""
28+
29+
_serializable_label = "Annotation.1"
30+
_name = "Annotation"
31+
32+
def __init__(
33+
self, name: str = "", visible: bool = True, layers: list | None = None
34+
) -> None:
35+
super().__init__(name=name, effect_name="Annotation.1")
36+
self.visible = visible
37+
self.layers = layers
38+
39+
_visible = otio.core.serializable_field(
40+
"visible", required_type=bool, doc=("Visible: expects either true or false")
41+
)
42+
43+
_layers = otio.core.serializable_field(
44+
"layers", required_type=list, doc=("Layers: expects a list of annotation types")
45+
)
46+
47+
@property
48+
def layers(self) -> list:
49+
return self._layers
50+
51+
@layers.setter
52+
def layers(self, val: list):
53+
self._layers = val
54+
55+
def __str__(self) -> str:
56+
return f"Annotation({self.name}, {self.effect_name}, {self.visible}, {self.layers})"
57+
58+
def __repr__(self) -> str:
59+
return f"otio.schema.Annotation(name={self.name!r}, effect_name={self.effect_name!r}, visible={self.visible!r}, layers={self.layers!r})"

src/plugins/rv-packages/otio_reader/manifest.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
{
22
"OTIO_SCHEMA" : "PluginManifest.1",
33
"schemadefs" : [
4+
{
5+
"OTIO_SCHEMA" : "SchemaDef.1",
6+
"name" : "Annotation",
7+
"execution_scope" : "in process",
8+
"filepath" : "annotation_schema.py"
9+
},
410
{
511
"OTIO_SCHEMA" : "SchemaDef.1",
612
"name" : "CDL",

src/plugins/rv-packages/otio_reader/otio_reader.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,21 @@ class NoNodeFromHook(otio.exceptions.OTIOError):
5959
pass
6060

6161

62+
def read_otio_string(otio_string: str, host_prefix: str | None = None) -> object | None:
63+
"""
64+
Main entry point to expand a given otio string into the current RV session.
65+
66+
Returns the top level node created that represents this otio
67+
timeline.
68+
"""
69+
otio_obj = otio.adapters.read_from_string(otio_string)
70+
timeline = otio_obj["otio"]
71+
72+
context = {"sg_url": host_prefix} if host_prefix else None
73+
74+
return create_rv_node_from_otio(timeline, context), timeline.global_start_time
75+
76+
6277
def read_otio_file(otio_file):
6378
"""
6479
Main entry point to expand a given otio (or file otio can read)
@@ -276,7 +291,7 @@ def _create_track(in_seq, context=None):
276291
return new_seq
277292

278293

279-
def _get_global_transform(tl):
294+
def _get_global_transform(tl) -> dict:
280295
# since there's no global scale in otio, calculate the minimum box size
281296
# that can contain all clips
282297
def find_display_bounds(tl):
@@ -491,9 +506,12 @@ def add_media(media_ref, active_key, cmd, *cmd_args):
491506
return source_group, active_source
492507

493508

494-
def _get_media_path(target_url, context=None):
509+
def _get_media_path(target_url: str, context: dict | None = None) -> str:
495510
context = context or {}
496511

512+
if "sg_url" in context:
513+
return context.get("sg_url") + target_url
514+
497515
if not os.path.isabs(target_url):
498516
# if this is a relative file path, assume relative to the otio file
499517
otio_path = context.get("otio_file")

0 commit comments

Comments
 (0)