tellers-timeline

tellers-ai/tellers-timeline

Open-source, cross-language library for reading, writing, validating, and editing a simplified subset of OTIO (OpenTimelineIO) JSON files. The core is written in Rust; bindings are available for Python, JavaScript (WASM), and Dart.

What it implements

  • Timeline, Stack, Tracks — top-level structure matching the OTIO schema
  • Clips — with duration, source (MediaSource), effects, and metadata
  • Gaps — silence/black filler between clips
  • MediaSource — URL-based media reference with start and duration accessors
  • Effects — per-clip effect parameters (volume, position, rich text overlays)
  • Metadata — arbitrary metadata, Tellers-specific data nested under the tellers.ai namespace
  • IDs — optional, auto-generated (48-bit entropy, 12-char strings); can be omitted for portability
  • Time values — seconds as f64

Build and test

Requires just and a Rust toolchain. For Python bindings, also install maturin.

# Build all crates (excludes WASM and Python bindings)
just build-all

# Run all tests (Rust + Python + WASM build check)
just test-all

# Regenerate the JSON Schema from code
just regen-schema

JSON Schema

The library is validated against a JSON Schema (Draft-07) generated from the Rust types. A minimal timeline looks like:

{
  "OTIO_SCHEMA": "Timeline.1",
  "name": "My Edit",
  "tracks": {
    "OTIO_SCHEMA": "Stack.1",
    "children": [
      {
        "OTIO_SCHEMA": "Track.1",
        "kind": "Video",
        "children": [
          {
            "type": "clip",
            "duration": 5.0,
            "source": {
              "url": "https://cdn.example.com/shot1.mp4",
              "start": 0.0,
              "duration": 5.0
            }
          },
          {
            "type": "gap",
            "duration": 0.5
          },
          {
            "type": "clip",
            "duration": 3.2,
            "source": {
              "url": "https://cdn.example.com/shot2.mp4",
              "start": 1.0,
              "duration": 3.2
            }
          }
        ]
      }
    ]
  }
}

The full schema lives at spec/otio.schema.json in the repository and is regenerated with just regen-schema.

Bindings

Python

Built with maturin (PyO3). Run maturin develop from bindings/python to install locally.

# Install with maturin (from the bindings/python directory)
# maturin develop

from tellers_timeline import Timeline, Track, Clip, MediaSource

tl = Timeline(name="My Edit")
track = tl.add_video_track()

clip = Clip(
    duration=5.0,
    source=MediaSource(url="https://cdn.example.com/shot1.mp4", start=0.0, duration=5.0),
)
track.append(clip)

# Serialize to OTIO JSON
print(tl.to_json())

JavaScript (WASM)

Compiled to wasm32-unknown-unknown. Build with cargo build -p tellers-timeline-wasm --target wasm32-unknown-unknown.

// Built as a WASM module — import after running scripts/generate_api.sh
import init, { Timeline } from './tellers_timeline_wasm.js';

await init();

const tl = new Timeline("My Edit");
const track = tl.addVideoTrack();
track.appendClip({ duration: 5.0, source: { url: "https://cdn.example.com/shot1.mp4", start: 0, duration: 5.0 } });

console.log(tl.toJson());

Dart

Dart bindings are available under bindings/dart in the repository.

Track operations

  • Append, insert, move, and delete items on a track
  • Resize clips (trim in/out points)
  • Split a clip at a given time (IDs are kept unique)
  • Add and remove tracks from the stack
  • Mute tracks (Python bindings)