Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
os: [ubuntu-latest, macos-latest, windows-latest]
otio-version: ["extract_adapters"]
otio-version: ["0.17.0]
# TODO Once we have landed extracted adapters we replace otio-version
#otio-version: ["0.15.0", "main"]

Expand All @@ -46,10 +46,8 @@ jobs:
python -m pip install --upgrade pip
if [[ "${{ matrix.otio-version }}" == "main" ]]; then
pip install "git+https://github.com/AcademySoftwareFoundation/OpenTimelineIO.git"
elif [[ "${{ matrix.otio-version }}" == "extract_adapters" ]]; then
pip install "git+https://github.com/AcademySoftwareFoundation/OpenTimelineIO.git@${{ matrix.otio-version }}"
else
pip install -V OpenTimelineIO==${{ matrix.otio-version }}
pip install OpenTimelineIO>=${{ matrix.otio-version }} --pre --only-binary :all:
fi
pip install flake8 pytest pytest-cov
shell: bash
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ license = { file="LICENSE" }
readme = "README.md"
requires-python = ">=3.7"
dependencies = [
"opentimelineio >= 0.15.0"
"opentimelineio >= 0.17.0.dev1"
]

classifiers = [
Expand Down
52 changes: 52 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import re
from pathlib import Path

from pytest import fixture
from opentimelineio import adapters, plugins

import otio_cmx3600_adapter.cmx_3600


@fixture
def cmx_adapter():
# Use OTIO's native plugin loading system
# This verifies that the adapter is being correctly registered and
# discovered by OTIO.
# But it also means the tests require you to install the adapter before
# running the tests.
manifest = plugins.ActiveManifest()

adapter = next(
adapter for adapter in manifest.adapters if adapter.name == "cmx_3600"
)

# Assert that the loaded adapter is the local one.
assert Path(adapter.module_abs_path()) == Path(
otio_cmx3600_adapter.cmx_3600.__file__
)
return adapter


@fixture
def assertJsonEqual():
"""Convert to json and compare that (more readable)."""

def compare(known, test_result):
known_str = adapters.write_to_string(known, "otio_json")
test_str = adapters.write_to_string(test_result, "otio_json")

def strip_trailing_decimal_zero(s):
return re.sub(r'"(value|rate)": (\d+)\.0', r'"\1": \2', s)

assert strip_trailing_decimal_zero(known_str) == strip_trailing_decimal_zero(
test_str
)

return compare


@fixture
def assertIsOTIOEquivalentTo():
"""Test using the 'is equivalent to' method on SerializableObject"""

return lambda known, test_result: known.is_equivalent_to(test_result) is True
143 changes: 60 additions & 83 deletions tests/test_cdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

# python
import os
import unittest

import pytest
import opentimelineio as otio

__doc__ = """Test CDL support in the EDL adapter."""
Expand All @@ -13,95 +13,76 @@
CDL_EXAMPLE_PATH = os.path.join(SAMPLE_DATA_DIR, "cdl.edl")


class CDLAdapterTest(unittest.TestCase):
def test_cdl_read(self):
edl_path = CDL_EXAMPLE_PATH
timeline = otio.adapters.read_from_file(edl_path)
self.assertTrue(timeline is not None)
self.assertEqual(len(timeline.tracks), 1)
self.assertEqual(len(timeline.tracks[0]), 2)
for clip in timeline.tracks[0]:
# clip = timeline.tracks[0][0]
self.assertEqual(
clip.name,
"ZZ100_501 (LAY3)"
)
self.assertEqual(
clip.source_range.duration,
otio.opentime.from_timecode("00:00:01:07", 24)
)
cdl = clip.metadata.get("cdl", {})
self.assertEqual(
cdl.get("asc_sat"),
0.9
)
self.assertEqual(
list(cdl.get("asc_sop").get("slope")),
[0.1, 0.2, 0.3]
)
self.assertEqual(
list(cdl.get("asc_sop").get("offset")),
[1.0000, -0.0122, 0.0305]
)
self.assertEqual(
list(cdl.get("asc_sop").get("power")),
[1.0000, 0.0000, 1.0000]
)

def test_cdl_read_with_commas(self):
# This EDL was generated with Premiere Pro using the CDL master effect
# on a clip
cdl = """TITLE: Sequence 01
def test_cdl_read(cmx_adapter):
edl_path = CDL_EXAMPLE_PATH
timeline = cmx_adapter.read_from_file(edl_path)
assert timeline is not None
assert len(timeline.tracks) == 1
assert len(timeline.tracks[0]) == 2
for clip in timeline.tracks[0]:
# clip = timeline.tracks[0][0]
assert clip.name == "ZZ100_501 (LAY3)"
assert clip.source_range.duration == otio.opentime.from_timecode(
"00:00:01:07", 24
)
cdl = clip.metadata.get("cdl", {})
assert cdl.get("asc_sat") == 0.9
assert list(cdl.get("asc_sop").get("slope")) == [0.1, 0.2, 0.3]
assert list(cdl.get("asc_sop").get("offset")) == [1.0000, -0.0122, 0.0305]
assert list(cdl.get("asc_sop").get("power")) == [1.0000, 0.0000, 1.0000]


def test_cdl_read_with_commas(cmx_adapter):
# This EDL was generated with Premiere Pro using the CDL master effect
# on a clip
cdl = """TITLE: Sequence 01
FCM: NON-DROP FRAME

000001 A006C014_1701069O V C 04:34:41:13 04:34:41:16 00:00:00:00 00:00:00:03
* FROM CLIP NAME: A006C014_1701069O_LOG_NO_LUT.mov
* ASC_SOP: (1.1549, 1.1469, 1.1422000000000001)(-0.067799999999999999, -0.055500000000000001, -0.032300000000000002)(1.1325000000000001, 1.1351, 1.1221000000000001)
* ASC_SAT: 1.2988
""" # noqa: E501
timeline = otio.adapters.read_from_string(cdl, "cmx_3600")

clip = timeline.tracks[0][0]
cdl_metadata = clip.metadata["cdl"]

ref_sop_values = {
"slope": [
1.1549,
1.1469,
1.1422000000000001,
],
"offset": [
-0.067799999999999999,
-0.055500000000000001,
-0.032300000000000002,
],
"power": [
1.1325000000000001,
1.1351,
1.1221000000000001,
],
}

self.assertAlmostEqual(cdl_metadata["asc_sat"], 1.2988)
for function in ("slope", "offset", "power"):
comparisons = zip(
cdl_metadata["asc_sop"][function], ref_sop_values[function]
)
for value_comp, ref_comp in comparisons:
self.assertAlmostEqual(
value_comp, ref_comp, msg=f"mismatch in {function}"
)

def test_cdl_round_trip(self):
original = """TITLE: Example_Screening.01
timeline = cmx_adapter.read_from_string(cdl)

clip = timeline.tracks[0][0]
cdl_metadata = clip.metadata["cdl"]

ref_sop_values = {
"slope": [
1.1549,
1.1469,
1.1422000000000001,
],
"offset": [
-0.067799999999999999,
-0.055500000000000001,
-0.032300000000000002,
],
"power": [
1.1325000000000001,
1.1351,
1.1221000000000001,
],
}

assert cdl_metadata["asc_sat"] == pytest.approx(1.2988)
for function in ("slope", "offset", "power"):
comparisons = zip(cdl_metadata["asc_sop"][function], ref_sop_values[function])
for value_comp, ref_comp in comparisons:
assert value_comp == pytest.approx(ref_comp), f"mismatch in {function}"


def test_cdl_round_trip(cmx_adapter):
original = """TITLE: Example_Screening.01

001 AX V C 01:00:04:05 01:00:05:12 00:00:00:00 00:00:01:07
* FROM CLIP NAME: ZZ100_501 (LAY3)
*ASC_SOP (0.1 0.2 0.3) (1.0 -0.0122 0.0305) (1.0 0.0 1.0)
*ASC_SAT 0.9
* SOURCE FILE: ZZ100_501.LAY3.01
"""
expected = """TITLE: Example_Screening.01
expected = """TITLE: Example_Screening.01

001 ZZ100501 V C 01:00:04:05 01:00:05:12 00:00:00:00 00:00:01:07
* FROM CLIP NAME: ZZ100_501 (LAY3)
Expand All @@ -110,10 +91,6 @@ def test_cdl_round_trip(self):
*ASC_SAT 0.9
* SOURCE FILE: ZZ100_501.LAY3.01
"""
timeline = otio.adapters.read_from_string(original, "cmx_3600")
output = otio.adapters.write_to_string(timeline, "cmx_3600")
self.assertMultiLineEqual(expected, output)


if __name__ == '__main__':
unittest.main()
timeline = cmx_adapter.read_from_string(original)
output = cmx_adapter.write_to_string(timeline)
assert expected == output
Loading