Skip to content

Commit e2d4387

Browse files
committed
Docs: Added documentation for adapter hook system
Signed-off-by: Tim Lehr <[email protected]>
1 parent b98d1cd commit e2d4387

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

docs/tutorials/write-a-hookscript.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,92 @@ def hook_function(in_timeline, argument_map=None):
126126
```
127127

128128
Please note that if a "post adapter write hook" changes `in_timeline` in any way, the api will not automatically update the already serialized file. The changes will only exist in the in-memory object, because the hook runs _after_ the file is serialized to disk.
129+
130+
## Implementing Adapter-specific hooks
131+
132+
While OTIO ships with a set of pre-defined hooks (e.g. `pre_adapter_write`), you can also define your own hooks in your adapter.
133+
These can be useful to give the user more fine-grained control over the execution of your adapter and make it work for their specific workflow.
134+
A good example is media embedding within Avids AAF files: Depending on the workflow, media references might have to be transcoded to be compatible with the AAF format.
135+
To achieve this, the AAF adapter could define a hook which users can leverage to transcode the files before embedding is attempted.
136+
137+
To define a custom hook in your adapter, you need to implement the `adapter_hook_names` function in your adapter module.
138+
You can define as many hooks as you like, but try to use the native hooks where possible to keep the API consistent.
139+
140+
```python
141+
# my_aaf_adapter.py
142+
143+
def read_from_file(self, filepath, **kwargs):
144+
...
145+
146+
def write_to_file(self, timeline, filepath, **kwargs):
147+
...
148+
149+
def adapter_hook_names() -> List[str]:
150+
"""Returns names of custom hooks implemented by this adapter."""
151+
return [
152+
"my_custom_adapter_hook"
153+
]
154+
```
155+
156+
The new hooks also need to be added to the adapter plugin manifest.
157+
158+
```json
159+
{
160+
"OTIO_SCHEMA" : "PluginManifest.1",
161+
"adapters" : [
162+
{
163+
"OTIO_SCHEMA" : "Adapter.1",
164+
"name" : "My AAF Adapter",
165+
"execution_scope" : "in process",
166+
"filepath" : "adapters/my_aaf_adapter.py",
167+
"suffixes" : ["aaf"]
168+
}
169+
],
170+
"hook_scripts" : [
171+
{
172+
"OTIO_SCHEMA" : "HookScript.1",
173+
"name" : "script_attached_to_custom_adapter_hook",
174+
"filepath" : "my_custom_adapter_hook_script.py"
175+
}
176+
],
177+
"hooks" : {
178+
"pre_adapter_write" : [],
179+
"post_adapter_read" : [],
180+
"post_adapter_write" : [],
181+
"post_media_linker" : [],
182+
"my_custom_adapter_hook" : ["script_attached_to_custom_adapter_hook"]
183+
}
184+
}
185+
```
186+
187+
A custom hook script might look like this:
188+
189+
```python
190+
# my_custom_adapter_hook_script.py
191+
192+
def hook_function(timeline, custom_argument, argument_map=None):
193+
# Do something with the timeline
194+
print(
195+
f"Running custom adapter hook with custom argument value '{custom_argument}'"
196+
f"and argument map: {argument_map}"
197+
)
198+
return timeline
199+
```
200+
201+
Attached hook scripts can then be run anywhere using the `otio.hooks.run` function:
202+
203+
```python
204+
# my_aaf_adapter.py
205+
206+
def write_to_file(self, timeline, filepath, **kwargs):
207+
# Do something
208+
...
209+
# Run custom hook script with it's custom arguments and pass hook_argument_map along
210+
otio.hooks.run(
211+
"my_custom_adapter_hook", timeline,
212+
custom_argument="some_value",
213+
argument_map=kwargs.get("hook_argument_map", {})
214+
)
215+
...
216+
# Do something more
217+
```

0 commit comments

Comments
 (0)