-
Notifications
You must be signed in to change notification settings - Fork 315
Example RV OTIO reading application plugin #565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ssteinbach
merged 5 commits into
AcademySoftwareFoundation:master
from
avrata:rv_application_plugin
Sep 24, 2019
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
86342a8
Example RV OTIO reading application plugin
avrata 6637439
Linting
avrata d7d8550
Merge branch 'master' of github.com:PixarAnimationStudios/OpenTimelin…
avrata f7af52c
Now adding metadata to all nodes created in RV if the associated otio…
avrata 2785a65
Cleaner list comprehension for source RV paths.
avrata File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
contrib/opentimelineio_contrib/application_plugins/rv/example_otio_reader/PACKAGE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package: Example OTIO Reader | ||
| author: Robyn Rindge | ||
| organization: Pixar Animation Studios | ||
| contact: opentimelineio@pixar.com | ||
| version: 1.0 | ||
| url: http://opentimeline.io | ||
| rv: 4.0.8 | ||
|
|
||
| modes: | ||
| - file: example_otio_reader_plugin.py | ||
| load: immediate | ||
| - file: otio_reader.py | ||
| location: Python | ||
|
|
||
|
|
||
| description: | | ||
| <p> | ||
| Example plugin that can read files supported by otio from within rv. This is | ||
| meant only as proof of concept. | ||
| </p> | ||
| <p> | ||
| To create the package run: | ||
| </p> | ||
| <p> | ||
| zip example_otio_reader_plugin-1.0.rvpkg PACKAGE example_otio_reader_plugin.py otio_reader.py | ||
| </p> |
168 changes: 168 additions & 0 deletions
168
...melineio_contrib/application_plugins/rv/example_otio_reader/example_otio_reader_plugin.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| """ | ||
| Example plugin showing how otio files can be loaded into an RV context | ||
| """ | ||
| # | ||
| # Copyright 2019 Pixar Animation Studios | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "Apache License") | ||
| # with the following modification; you may not use this file except in | ||
| # compliance with the Apache License and the following modification to it: | ||
| # Section 6. Trademarks. is deleted and replaced with: | ||
| # | ||
| # 6. Trademarks. This License does not grant permission to use the trade | ||
| # names, trademarks, service marks, or product names of the Licensor | ||
| # and its affiliates, except as required to comply with Section 4(c) of | ||
| # the License and to reproduce the content of the NOTICE file. | ||
| # | ||
| # You may obtain a copy of the Apache License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the Apache License with the above modification is | ||
| # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| # KIND, either express or implied. See the Apache License for the specific | ||
| # language governing permissions and limitations under the Apache License. | ||
| # | ||
|
|
||
| import os | ||
|
|
||
| from rv import commands | ||
| from rv import rvtypes | ||
|
|
||
| import opentimelineio as otio | ||
|
|
||
| import otio_reader | ||
|
|
||
|
|
||
| class Mode(object): | ||
| sleeping = 1 | ||
| loading = 2 | ||
| processing = 3 | ||
|
|
||
|
|
||
| class ExampleOTIOReaderPlugin(rvtypes.MinorMode): | ||
| def __init__(self): | ||
| super(ExampleOTIOReaderPlugin, self).__init__() | ||
| self.init("example_otio_reader", | ||
| [("incoming-source-path", | ||
| self.incoming_source_path, | ||
| "Catch otio supported files and return movieproc"), | ||
| ("source-group-complete", | ||
| self.source_group_complete, | ||
| "Expand otio supported files (synchronous load)"), | ||
| ("after-progressive-loading", | ||
| self.after_progressive_loading, | ||
| "Expand otio supported files (asynchronous load)")], | ||
| None) | ||
|
|
||
| # Start as sleeping | ||
| self.mode = Mode.sleeping | ||
|
|
||
| def incoming_source_path(self, event): | ||
| """ | ||
| Detects if a file supported by otio is being loaded, and replaces | ||
| it with an empty movie proc containing an otioFile tag. This will be | ||
| replaced in expand_sources(). | ||
| """ | ||
| event.reject() | ||
|
|
||
| parts = event.contents().split(';') | ||
| in_path = parts[0] | ||
| _, ext = os.path.splitext(in_path) | ||
| if ext: | ||
| ext = ext[1:] | ||
|
|
||
| if ext in otio.adapters.suffixes_with_defined_adapters(read=True): | ||
| self.mode = Mode.loading | ||
| movieproc = 'blank,otioFile={}.movieproc'.format(in_path) | ||
| event.setReturnContent(movieproc) | ||
|
|
||
| def after_progressive_loading(self, event): | ||
| """ | ||
| After progress loading event, is used for asynchronous addSource | ||
| file loading. | ||
| """ | ||
| event.reject() | ||
|
|
||
| if self.mode != Mode.loading: | ||
| return | ||
| self.mode = Mode.processing | ||
| self.expand_sources() | ||
|
|
||
| def source_group_complete(self, event): | ||
| """ | ||
| Source group complete event, is used for synchronous addSource | ||
| file loading. | ||
| """ | ||
| event.reject() | ||
| if self.mode == Mode.sleeping: | ||
| # this plugin isn't doing anything | ||
| return | ||
|
|
||
| if self.mode == Mode.processing: | ||
| # already processing otio | ||
| return | ||
|
|
||
| if commands.loadTotal() > 0: | ||
| # async load | ||
| return | ||
|
|
||
| self.mode = Mode.processing | ||
| self.expand_sources() | ||
|
|
||
| def expand_sources(self): | ||
| """ | ||
| Expand any movie movieproc otioFile sources. | ||
| """ | ||
| # disable caching for load speed | ||
| cache_mode = commands.cacheMode() | ||
| commands.setCacheMode(commands.CacheOff) | ||
|
|
||
| try: | ||
| # find sources with a movieproc with an otioFile=foo.otio tag | ||
| default_inputs, _ = commands.nodeConnections('defaultSequence') | ||
| for src in commands.nodesOfType('RVSource'): | ||
| src_group = commands.nodeGroup(src) | ||
| if src_group not in default_inputs: | ||
| # not in default sequence, already processed | ||
| continue | ||
|
|
||
| # get the source file name | ||
| paths = [info['file'] for info in | ||
| commands.sourceMediaInfoList(src) if 'file' in info] | ||
| for info_path in paths: | ||
| # Looking for: 'blank,otioFile=/foo.otio.movieproc' | ||
| parts = info_path.split("=", 1) | ||
avrata marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| itype = parts[0] | ||
| if not itype.startswith('blank,otioFile'): | ||
| continue | ||
| # remove the .movieproc extension | ||
| path, _ = os.path.splitext(parts[1]) | ||
|
|
||
| # remove temp movieproc source from current view, and all | ||
| # the default views | ||
| _remove_source_from_views(src_group) | ||
|
|
||
| result = otio_reader.read_otio_file(path) | ||
| commands.setViewNode(result) | ||
| break | ||
| finally: | ||
| # turn cache mode back on and go back to sleep | ||
| commands.setCacheMode(cache_mode) | ||
| self.mode = Mode.sleeping | ||
|
|
||
|
|
||
| def _remove_source_from_views(source_group): | ||
| """ | ||
| Remove a source group from all views. | ||
| """ | ||
| for view in commands.viewNodes(): | ||
| view_inputs = commands.nodeConnections(view)[0] | ||
| if source_group in view_inputs: | ||
| view_inputs.remove(source_group) | ||
| commands.setNodeInputs(view, view_inputs) | ||
|
|
||
|
|
||
| def createMode(): | ||
| return ExampleOTIOReaderPlugin() | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.