|
2 | 2 |
|
3 | 3 | ## Overview
|
4 | 4 |
|
5 |
| -This document describes OpenTimelineIO's file bundle formats, otiod and otioz. The intent is that they make it easier to package and send or archive OpenTimelineIO data and associated media. |
| 5 | +This document describes OpenTimelineIO's file bundle formats, `otiod` and `otioz`, as well as how to use the internal adapters that read and write them. |
6 | 6 |
|
7 |
| -## Source Timeline |
| 7 | +The OTIOZ/D File Bundle formats package OpenTimelineIO data and associated media into a single file. This can be useful for sending, archiving and interchange of a single unit that collects cut information and media together. |
8 | 8 |
|
9 |
| -For creating otio bundles, an OTIO file is used as input, whose media references are composed only of `ExternalReference` that have a target_url field pointing at a media file with a unique basename, because file bundles have a flat namespace for media. For example, if there are media references that point at: |
| 9 | +## OTIOZ/D File Bundle Format Details |
10 | 10 |
|
11 |
| -`/project_a/academy_leader.mov` |
| 11 | +There are two encodings for OTIO file bundles, OTIOZ and OTIOD. OTIOD is an encoding in the file system that uses a directory hierarchy of files. OTIOZ is the identical structure packed into a single .zip file, currently using the python `zipfile` library. Both contain a content.otio entry at the top level which contains the cut information for the bundle. |
12 | 12 |
|
13 |
| -and: |
| 13 | +### Structure |
14 | 14 |
|
15 |
| -`/project_b/academy_leader.mov` |
| 15 | +File bundles have a consistent structure: |
16 | 16 |
|
17 |
| -Because the basename of both files is `academy_leader.mov`, this will be an error. The adapters have different policies for how to handle media references. See below for more information. |
| 17 | +OTIOD: |
| 18 | + |
| 19 | +``` |
| 20 | +something.otiod (directory) |
| 21 | +├── content.otio (file) |
| 22 | +└── media (directory) |
| 23 | + ├── media1 (file) |
| 24 | + ├── media2 (file) |
| 25 | + └── media3 (file) |
| 26 | +``` |
18 | 27 |
|
19 |
| -### URL Format |
| 28 | +OTIOZ (adds the version.txt file and is encoded in a zipfile): |
20 | 29 |
|
21 |
| -The file bundle adapters expect the `target_url` field of the `media_reference` to be in one of two forms (as produced by python's urlparse library): |
| 30 | +``` |
| 31 | +something.otioz (zipfile) |
| 32 | +├── content.otio (compressed file) |
| 33 | +├── version.txt (compressed file) |
| 34 | +└── media (directory) |
| 35 | + ├── media1 (uncompressed file) |
| 36 | + ├── media2 (uncompressed file) |
| 37 | + ├── media3 (uncompressed file) |
| 38 | + └── ... (uncompressed files) |
| 39 | +``` |
22 | 40 |
|
23 |
| -- absolute path: "file:///path/to/some/file" (encodes "/path/to/some/file") |
24 |
| -- relative path: "path/to/some/file" (assumes the path is relative to the current working directory when invoking the adapter). |
| 41 | +### content.otio file |
| 42 | + |
| 43 | +This is an OpenTimelineIO file whose media references are either `MissingReference`s, or `ExternalReference`s with target_urls that are relative paths pointing into the `media` directory. |
25 | 44 |
|
26 |
| -## Structure |
| 45 | +### version.txt file |
27 | 46 |
|
28 |
| -File bundles, regardless of how they're encoded, have a consistent structure: |
| 47 | +This file encodes the otioz version of the file, with no other text, in the form: |
29 | 48 |
|
30 | 49 | ```
|
31 |
| -something.otioz |
32 |
| -├── content.otio |
33 |
| -├── version |
34 |
| -└── media |
35 |
| - ├── media1 |
36 |
| - ├── media2 |
37 |
| - └── media3 |
| 50 | +1.0.0 |
38 | 51 | ```
|
39 | 52 |
|
| 53 | +### "media" Directory |
40 | 54 |
|
41 |
| -### content.otio file |
| 55 | +The `media` directory contains all the media files that the `ExternalReference`s `target_url`s in the `content.otio` point at, in a flat structure. Each media file must have a unique basename, but can be encoded in whichever codec/container the user wishes (otio is unable to decode or encode the media files). |
42 | 56 |
|
43 |
| -This is a normal OpenTimelineIO whose media references are either ExternalReferences with relative target_urls pointing into the `media` directory or `MissingReference`. |
| 57 | +## Adapter Usage |
44 | 58 |
|
45 |
| -### version.txt file |
| 59 | +## Read Adapter Behavior |
46 | 60 |
|
47 |
| -This file encodes the otioz version of the file, in the form 1.0.0. |
| 61 | +When a bundle is read from disk using the OpenTimelineIO Python API (using the adapters.read_from_* functions), only the `content.otio` file is read and parsed. |
48 | 62 |
|
49 |
| -### Media Directory |
| 63 | +For example, to view the timeline (not the media) of an otioz file in `otioview`, you can run: |
50 | 64 |
|
51 |
| -The media directory contains all the media files in a flat structure. They must have unique basenames, but can be encoded in whichever codec/container the user wishes (otio is unable to decode or encode the media files). |
| 65 | +`otioview sommething.otioz` |
52 | 66 |
|
53 |
| -## Read Behavior |
| 67 | +Because this will _only_ read the `content.otio` from the bundle, it is usually a fast operation to run. None of the media is decoded or unzipped during this process. |
54 | 68 |
|
55 |
| -When a bundle is read from disk, the `content.otio` file is extracted from the bundle and returned. For example, to view the timeline (not the media) of an otioz file in `otioview`, you can run: |
| 69 | +### extract_to_directory Optional Argument |
56 | 70 |
|
57 |
| -`otioview sommething.otioz` |
| 71 | +extract_to_directory: if a value other than `None` is passed in, will extract the contents of the bundle into the directory at the path passed into the `extract_to_directory` argument. For the OTIOZ adapter, this will unzip the associated media. |
58 | 72 |
|
59 |
| -This will _only_ read the `content.otio` from the bundle, so is usually a fast operation to run. |
| 73 | +### absolute_media_reference_paths Optional Argument |
60 | 74 |
|
61 |
| -## MediaReferencePolicy |
| 75 | +The OTIOD adapter additionally has an argument `absolute_media_reference_paths` which will convert all the media references in the bundle to be absolute paths if `True` is passed. Default is `False`. |
62 | 76 |
|
63 |
| -When building a file bundle using the OTIOZ/OTIOD adapters, you can set the 'media reference policy', which is described by an enum in the file_bundle_utils module. The policies can be: |
| 77 | +### Read Adapter Example |
64 | 78 |
|
65 |
| -- (default) ErrorIfNotFile: will raise an exception if a media reference is found that is of type `ExternalReference` but that does not point at a `target_url`. |
66 |
| -- MissingIfNotFile: will replace any media references that meet the above condition with a `MissingReference`, preserving the original media reference in the metadata of the new `MissingReference`. |
67 |
| -- AllMissing: will replace all media references with `MissingReference`, preserving the original media reference in metadata on the new object. |
| 79 | +Extract the contents of the bundle and convert to an rv playlist: |
68 | 80 |
|
69 |
| -When running in `AllMissing` mode, no media will be put into the bundle. |
| 81 | +`otioconvert -i /var/tmp/some_file.otioz -a extract_to_directory=/var/tmp/example_directory -o /var/tmp/example_directory/some_file.rv` |
70 | 82 |
|
71 |
| -## OTIOD |
| 83 | +## Write Adapter |
72 | 84 |
|
73 |
| -The OTIOD adapter will build a bundle in a directory stucture on disk. The adapter will gather up all the files it can and copy them to the destination directory, and then build the `.otio` file with local relative path references into that directory. |
| 85 | +### Source Timeline Constraints |
74 | 86 |
|
75 |
| -## OTIOZ |
| 87 | +For creating otio bundles using the provided python adapter, an OTIO file is used as input. There are some constraints on the source timeline. |
76 | 88 |
|
77 |
| -The OTIOZ adapter will build a bundle into a zipfile (using the zipfile library). The adapter will write media into the zip file uncompressed and the content.otio with compression. |
| 89 | +#### Unique Basenames |
78 | 90 |
|
79 |
| -### Optional Arguments: |
| 91 | +Because file bundles have a flat namespace for media, and media will be copied into the bundle, the `ExternalReference` media references in the source OTIO must have a target_url fields pointing at media files with unique basenames. |
80 | 92 |
|
81 |
| -- Read: |
82 |
| - - extract_to_directory: if a value other than `None` is passed in, will extract the contents of the bundle into the directory at the path passed into the `extract_to_directory` argument. |
| 93 | +For example, if there are media references that point at: |
83 | 94 |
|
84 |
| -## Example usage in otioconvert |
| 95 | +`/project_a/academy_leader.mov` |
85 | 96 |
|
86 |
| -### Convert an otio into a zip bundle |
| 97 | +and: |
| 98 | + |
| 99 | +`/project_b/academy_leader.mov` |
| 100 | + |
| 101 | +Because the basename of both files is `academy_leader.mov`, this will be an error. The adapters have different policies for how to handle media references. See below for more information. |
| 102 | + |
| 103 | +#### Expected Source Timeline External Reference URL Format |
| 104 | + |
| 105 | +The file bundle adapters expect the `target_url` field of any `media_reference`s in the source timeline to be in one of two forms (as produced by python's [urlparse](https://docs.python.org/3/library/urllib.parse.html) library): |
| 106 | + |
| 107 | +- absolute path: "file:///path/to/some/file" (encodes "/path/to/some/file") |
| 108 | +- relative path: "path/to/some/file" (the path is relative to the current working directory of the command running the adapter on the source timeline). |
| 109 | + |
| 110 | +### MediaReferencePolicy Option |
| 111 | + |
| 112 | +When building a file bundle using the OTIOZ/OTIOD adapters, you can set the 'media reference policy', which is described by an enum in the file_bundle_utils module. The policies can be: |
| 113 | + |
| 114 | +- (default) `ErrorIfNotFile`: will raise an exception if a media reference is found that is of type `ExternalReference` but that does not point at a `target_url`. |
| 115 | +- `MissingIfNotFile`: will replace any media references that meet the above condition with a `MissingReference`, preserving the original media reference in the metadata of the new `MissingReference`. |
| 116 | +- `AllMissing`: will replace all media references with `MissingReference`, preserving the original media reference in metadata on the new object. |
| 117 | + |
| 118 | +When running in `AllMissing` mode, no media will be put into the bundle. |
| 119 | + |
| 120 | +To use this argument with `otioconvert` from the commandline, you can use the `-A` flag with the argument name `media_policy`: |
| 121 | + |
| 122 | +``` |
| 123 | +otioconvert -i <some_file> -o path/to/output_file.otioz -A media_policy="AllMissing" |
| 124 | +``` |
87 | 125 |
|
88 |
| -`otioconvert -i somefile.otio -o /var/tmp/somefile.otioz` |
| 126 | +### Write Adapter Example |
89 | 127 |
|
90 |
| -### Extract the contents of the bundle and convert to an rv playlist |
| 128 | +Convert an otio into a zip bundle: |
91 | 129 |
|
92 |
| -`otioconvert -i /var/tmp/somefile.otioz -a extract_to_directory=/var/tmp/somefile -o /var/tmp/somefile/somefile.rv` |
| 130 | +`otioconvert -i some_file.otio -o /var/tmp/some_file.otioz` |
0 commit comments