render_timeline

Render an OTIO Timeline to a Video File

Description

Lowers a rotio (OpenTimelineIO) Timeline to a single ffmpeg invocation and renders it. The video track’s clips are concatenated in order; an optional separate audio track is mapped over them; a framing transform (scale + pad, from metadata$cornball$framing) and an optional caption burn (from a caption track referencing an .ass/.srt file) are applied.

Usage

render_timeline(timeline, output, media_dir = NULL, overwrite = TRUE,
                dry_run = FALSE)

Arguments

  • timeline: A rotio Timeline, or a path to a .otio file.
  • output: Path for the output video file.
  • media_dir: Base directory for resolving relative media urls. Defaults to the timeline file’s directory when timeline is a path, otherwise NULL (urls used as-is).
  • overwrite: If TRUE (default), overwrite the output file.
  • dry_run: If TRUE, return the ffmpeg command string without executing. Note: concatenation of multiple video clips, still/sequence pre-renders, and layout composition still run, since they produce intermediates the final command depends on.

Details

The video track is lowered honoring per-clip source_range trims and Transitions: a transition between two clips becomes a dissolve over exactly its duration, fed by the incoming clip’s head handle (the media before its source range – for chained generation, the conditioning-head replay). Only transitions with out_offset == 0 are lowered (the cornductor bundle shape: the outgoing clip has no tail handle). Gaps and overlapping layers are not lowered yet.

Still-image clips (a media reference targeting a .png/.jpg/ …) are pre-rendered into video via still_clip at the source_range’s rate, honoring cornball.* motion effects on the clip (Ken Burns pan/zoom; the schema lives in system.file("schema", "cornball-effects.md", package = "compost")). A still-image clip must carry a source_range. ImageSequenceReference clips are pre-rendered via frames_clip at the reference’s rate; motion effects are not applied to sequences. Effects the renderer cannot honor degrade to a static clip with a warning; effects outside the cornball. namespace are ignored silently.

When the timeline carries metadata$cornball$layout (schema in system.file("schema", "cornball-layout.md", package = "compost")), tracks whose cornball$role matches a layout slot are each assembled like the content track and composed onto the canvas via compose_layout – muted, painted in slot order, with the content track bound to the visual slot as the timing reference. The framing transform is suppressed when composing (the layout defines the canvas). A layout the renderer cannot honor – schema too new, a slot’s track missing, or a roled track without a slot – degrades to the plain single-stream render with one warning.

Caption tracks are identified by metadata$cornball$role == "caption" or a name containing “caption”. When the primary video track has a single clip that already carries its own audio (the talking-head case), no separate audio track is needed.

Value

Invisibly returns the output path. If dry_run, returns the command string for the final render pass.

Examples

render_timeline("AAA/20260131/t41_n22_intro/timeline.otio",
                "AAA/20260131/t41_n22_intro/video.mp4")