Skip to content

Commit d70f08b

Browse files
committed
📦 Improve: Expose Timeline.findClips
1 parent b0856e8 commit d70f08b

File tree

5 files changed

+370
-0
lines changed

5 files changed

+370
-0
lines changed

Sources/objc/include/opentimelineio.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ CxxTimeRange timeline_range_of_child(CxxRetainer* self, CxxRetainer* child, CxxE
202202
NSArray* timeline_audio_tracks(CxxRetainer* self);
203203
NSArray* timeline_video_tracks(CxxRetainer* self);
204204

205+
NSArray* timeline_find_clips(CxxRetainer* self, CxxErrorStruct* cxxErr);
206+
205207
// MARK: - Track
206208
NSString* track_get_kind(CxxRetainer* self);
207209
void track_set_kind(CxxRetainer* self, NSString*);

Sources/objc/opentimelineio.mm

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,15 @@ CxxTimeRange timeline_range_of_child(CxxRetainer* self, CxxRetainer* child, CxxE
717717
return array;
718718
}
719719

720+
NSArray* timeline_find_clips(CxxRetainer* self, CxxErrorStruct* cxxErr) {
721+
auto array = [NSMutableArray new];
722+
_AutoErrorHandler aeh(cxxErr);
723+
for (auto t: SO_cast<otio::Timeline>(self)->find_clips(&aeh.error_status)) {
724+
[array addObject: [NSValue valueWithPointer: t]];
725+
}
726+
return array;
727+
}
728+
720729
// MARK: - Track
721730
NSString* track_get_kind(CxxRetainer* self) {
722731
return make_nsstring(SO_cast<otio::Track>(self)->kind());

Sources/swift/Timeline.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ public class Timeline : SerializableObjectWithMetadata {
7777
return try OTIOError.returnOrThrow { TimeRange(timeline_range_of_child(self, child, &$0)) }
7878
}
7979

80+
public func findClips() throws -> [Clip] {
81+
let children_array = try OTIOError.returnOrThrow { timeline_find_clips(self, &$0) }
82+
var result = [Clip]()
83+
for child in children_array {
84+
if let nsptr = child as? NSValue, let cxxPtr = nsptr.pointerValue {
85+
result.append(SerializableObject.findOrCreate(cxxPtr: cxxPtr) as! Clip)
86+
}
87+
}
88+
return result
89+
}
90+
8091
override internal init(_ cxxPtr: CxxSerializableObjectPtr) {
8192
super.init(cxxPtr)
8293
}

Tests/OpenTimelineIOTests/testTimeline.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import XCTest
1010
import Foundation
1111

1212
final class testTimeline: XCTestCase {
13+
enum Error: Swift.Error {
14+
case SetupFailed(String)
15+
}
16+
1317
override func setUpWithError() throws {
1418
}
1519

@@ -78,5 +82,46 @@ final class testTimeline: XCTestCase {
7882
XCTFail("Cannot read OTIO file `\(timelineInputPath)`: \(error)")
7983
}
8084
}
85+
86+
func testTimelineFindClips() throws {
87+
// SETUP
88+
let timeline = try timeline(from: "data/nested_example.otio")
89+
90+
// EXERCISE
91+
let clips = try timeline.findClips()
92+
93+
// VERIFY
94+
XCTAssertEqual(
95+
clips.map(\.name),
96+
[
97+
"Normal Clip 1",
98+
"Clip Inside A Stack 1",
99+
"Normal Clip 2",
100+
"Clip Inside A Stack 2",
101+
"Normal Clip 3",
102+
"Clip Inside A Track",
103+
"Normal Clip 4"
104+
]
105+
)
106+
}
107+
108+
func timeline(from inputFilePath: String) throws -> Timeline {
109+
guard let timelineInputPath = Bundle.module.path(forResource: inputFilePath, ofType: "") else {
110+
throw Error.SetupFailed("Missing test data `\(inputFilePath)`")
111+
}
112+
113+
do {
114+
let otio = try SerializableObject.fromJSON(filename: timelineInputPath)
115+
116+
guard let timeline = otio as? Timeline else {
117+
throw Error.SetupFailed("Could not create Timeline object from \(timelineInputPath)")
118+
}
119+
120+
return timeline
121+
122+
} catch let error {
123+
throw Error.SetupFailed("Cannot read OTIO file `\(timelineInputPath)`: \(error)")
124+
}
125+
}
81126

82127
}

0 commit comments

Comments
 (0)