Timeline

Timeline — top-level container for tracks, markers, and scene data.

class camtasia.timeline.timeline.ZoomPanKeyframe(time_seconds, scale=1.0, center_x=0.5, center_y=0.5)[source]

Bases: object

A zoom/pan keyframe on the timeline.

time_seconds: float
scale: float = 1.0
center_x: float = 0.5
center_y: float = 0.5
class camtasia.timeline.timeline.Timeline(timeline_data)[source]

Bases: object

Represents the timeline of a Camtasia project.

Parameters:

timeline_data (dict[str, Any]) – The timeline sub-dict from the project JSON.

property tracks: _TrackAccessor

Iterable accessor over Track objects.

property track_count: int

Number of tracks on the timeline.

property total_clip_count: int

Total number of clips across all tracks.

property has_clips: bool

Whether any track has clips.

property total_transition_count: int

Total number of transitions across all tracks.

add_track(name='')[source]

Append a new empty track.

Parameters:

name (str) – Display name for the track.

Return type:

Track

Returns:

The newly created Track.

remove_track(index)[source]

Remove a track by its index and re-number remaining tracks.

Parameters:

index (int) – The track index to remove.

Raises:

KeyError – No track with the given index.

Return type:

None

remove_tracks_by_name(name)[source]

Remove all tracks with the given name. Returns count removed.

Return type:

int

next_clip_id()[source]

Return the next available clip ID across ALL tracks.

Scans every track — including nested group tracks and UnifiedMedia sub-clips — for the maximum clip ID and returns max + 1. Returns 1 for an empty project.

Return type:

int

duplicate_track(source_track_index)[source]

Duplicate a track and all its clips. Returns the new track.

Return type:

Track

move_track(from_index, to_index)[source]

Move a track from one array position to another.

Parameters:
  • from_index (int) – Current array position.

  • to_index (int) – Desired array position.

Return type:

None

move_track_to_back(track_index)[source]

Move a track to position 0 (behind all other tracks).

Return type:

None

move_track_to_front(track_index)[source]

Move a track to the last position (in front of all other tracks).

Return type:

None

find_clip(clip_id)[source]

Find a clip by ID across all tracks.

Returns (track, clip) tuple, or None.

Return type:

tuple | None

reorder_tracks(order)[source]

Reorder tracks by providing current trackIndex values in desired order.

Parameters:

order (list[int]) – List of current trackIndex values in the new order.

Return type:

None

property markers: _TimelineMarkers

Timeline-level markers (from parameters.toc).

property total_duration_ticks: int

Maximum end time across all tracks, in ticks.

Returns:

The tick position of the latest clip end, or 0 if empty.

total_duration_seconds()[source]

Maximum end time across all tracks, in seconds.

Return type:

float

Returns:

Duration in seconds, or 0.0 if the timeline is empty.

property duration_seconds: float

Total timeline duration in seconds.

property total_duration_formatted: str

MM:SS or MM:SS string.

Type:

Total timeline duration as HH

summary()[source]

Human-readable timeline summary.

Return type:

str

property end_seconds: float

End time of the timeline in seconds.

property track_summary: list[dict[str, Any]]

Summary of each track as a list of dicts.

describe()[source]

Human-readable timeline description.

Return type:

str

get_or_create_track(name)[source]

Find a track by name, or create a new one if it doesn’t exist.

Parameters:

name (str) – Display name to search for (exact match).

Return type:

Track

Returns:

The existing or newly created Track.

all_clips()[source]

All clips across all tracks, including nested clips inside Groups/StitchedMedia/UnifiedMedia.

Return type:

list[BaseClip]

property groups: list[Group]

All Group clips across all tracks, including nested groups.

find_track(name)[source]

Find a track by name, or return None.

Return type:

Track | None

property empty_tracks: list[Track]

Return all tracks with no clips.

find_track_by_name(track_name)[source]

Find the first track with the given name, or None.

Parameters:

track_name (str) – Exact track name to search for.

Return type:

Track | None

Returns:

The first matching Track, or None if no track has that name.

property tracks_with_clips: list[Track]

Return only tracks that have clips.

property track_names: list[str]

Names of all tracks.

to_dict()[source]

Return a summary dict of the timeline structure.

Return type:

TimelineSummary

property all_clip_ids: set[int]

Set of all clip IDs across all tracks.

property all_effects: list[tuple[Track, BaseClip, dict]]

All effects across all tracks as (track, clip, effect_dict) tuples.

remove_all_transitions()[source]

Remove all transitions from all tracks. Returns count removed.

Return type:

int

remove_empty_tracks()[source]

Remove all empty tracks. Returns count removed.

Return type:

int

remove_all_empty_tracks()[source]

Remove every track that contains no clips.

Return type:

int

Returns:

Number of tracks removed.

pack_all_tracks()[source]

Pack every track, removing intra-track gaps between clips.

Calls camtasia.operations.layout.pack_track() on each track so clips are repositioned end-to-end with no gaps.

Return type:

int

Returns:

Number of tracks packed (tracks with at least one clip).

remove_short_clips_all_tracks(minimum_duration_seconds)[source]

Remove short clips from all tracks. Returns total count removed.

Return type:

int

clear_all()[source]

Clear all clips and transitions from all tracks.

Return type:

None

add_marker(label, time_seconds)[source]

Add a timeline marker at the given time.

Parameters:
  • label (str) – Display label for the marker.

  • time_seconds (float) – Position in seconds.

Return type:

Marker

Returns:

The newly created Marker.

clips_in_range(start_seconds, end_seconds)[source]

Find all clips that overlap with a time range.

Returns (track, clip) tuples for clips whose time span overlaps [start_seconds, end_seconds].

Return type:

list[tuple[Track, BaseClip]]

find_all_clips_at(time_seconds)[source]

Find all clips at a time point across all tracks.

Return type:

list[tuple[Track, BaseClip]]

clips_of_type(clip_type)[source]

Find all clips of a specific type across all tracks.

Parameters:

clip_type (str) – Clip type string (e.g. ‘AMFile’, ‘IMFile’, ‘Group’).

Return type:

list[tuple[Track, BaseClip]]

Returns:

List of (track, clip) tuples.

property audio_clips: list[tuple[Track, BaseClip]]

All audio clips across all tracks.

property image_clips: list[tuple[Track, BaseClip]]

All image clips across all tracks.

property video_clips: list[tuple[Track, BaseClip]]

All video clips across all tracks.

property zoom_pan_keyframes: list[ZoomPanKeyframe]

Get zoom/pan keyframes from the timeline.

add_zoom_pan(time_seconds, *, scale=1.0, center_x=0.5, center_y=0.5)[source]

Add a zoom/pan keyframe to the timeline.

Parameters:
  • time_seconds (float) – Timeline position.

  • scale (float) – Zoom level (1.0 = 100%, 2.0 = 200%).

  • center_x (float) – Horizontal center 0.0-1.0 (0.5 = center).

  • center_y (float) – Vertical center 0.0-1.0 (0.5 = center).

Return type:

ZoomPanKeyframe

clear_zoom_pan()[source]

Remove all zoom/pan keyframes.

Return type:

None

property gain: float

Audio gain level for the timeline.

property legacy_attenuate_audio_mix: bool

Whether legacy audio attenuation mixing is enabled.

property background_color: list[int]

Background color as an RGBA list.

property caption_attributes: CaptionAttributes

Caption styling configuration.

validate_structure()[source]

Check timeline structural invariants.

Returns a list of issue descriptions (empty = valid).

Return type:

list[str]

flatten_to_track(target_track_name='Flattened')[source]

Copy all clips from all tracks onto a single target track.

Creates a new track and copies all clips to it. Original tracks are not modified. Clips keep their original timing.

Parameters:

target_track_name (str) – Name for the target track.

Return type:

Track

Returns:

The target track with all clips.

shift_all(seconds)[source]

Shift all clips on all tracks by the given number of seconds.

Positive values move clips forward, negative moves backward. Clips are clamped to not go before time 0.

Return type:

None

apply_to_all_clips(fn)[source]

Apply a function to every clip on every track. Returns count.

Return type:

int

reverse_track_order()[source]

Reverse the order of all tracks.

Return type:

None

sort_tracks_by_name()[source]

Sort tracks alphabetically by name.

Return type:

None

insert_gap(position_seconds, gap_duration_seconds)[source]

Insert a gap at a position across ALL tracks, shifting subsequent clips.

Return type:

None

remove_gap(position_seconds, gap_duration_seconds)[source]

Remove a gap at a position across ALL tracks, pulling subsequent clips back.

Return type:

None

property longest_track: Track | None

The track with the greatest end time, or None if empty.

normalize_all_tracks()[source]

Normalize timing on all tracks so each starts at time 0.

Return type:

None

property clip_density: float

Ratio of total clip duration to timeline duration (0.0-1.0+).

Track on the timeline — wraps a single track dict and its attributes.

class camtasia.timeline.track.Track(attributes, data, _all_tracks=None)[source]

Bases: object

A track on the timeline.

Wraps both the track data dict (from csml.tracks) and the corresponding entry in trackAttributes.

Parameters:
  • attributes (dict[str, Any]) – The trackAttributes record for this track.

  • data (dict[str, Any]) – The track dict from csml.tracks.

property name: str

Track name from trackAttributes ident.

rename(new_name)[source]

Rename this track.

Return type:

None

property index: int

Track index (position in the track list).

property clip_count: int

Number of clips on this track.

find_clip(clip_id)[source]

Find a clip by ID, or return None.

Return type:

BaseClip | None

property audio_muted: bool

Whether the track’s audio is muted.

property video_hidden: bool

Whether the track’s video is hidden.

property magnetic: bool

Whether the track has magnetic clip snapping enabled.

property solo: bool

Whether the track is soloed for exclusive playback.

mute()[source]

Mute this track’s audio.

Return type:

None

unmute()[source]

Unmute this track’s audio.

Return type:

None

hide()[source]

Hide this track’s video.

Return type:

None

show()[source]

Show this track’s video.

Return type:

None

property is_muted: bool

Alias for audio_muted.

property is_hidden: bool

Alias for video_hidden.

property is_solo: bool

Alias for solo.

property is_magnetic: bool

Alias for magnetic.

property is_locked: bool

Whether the track is locked against editing.

clear()[source]

Remove all clips and transitions from this track.

Also clears transitions inside Group clips’ internal tracks to prevent dangling clip-ID references in the saved JSON.

Return type:

None

property clips: _ClipAccessor

Iterable accessor over typed clip objects on this track.

property clip_ids: list[int]

List of all clip IDs on this track.

property clip_ids_sorted: list[int]

Clip IDs sorted by start time.

property medias: _ClipAccessor

Alias for clips (backward compatibility).

property transitions: TransitionList

Track-level transitions between clips.

property has_transitions: bool

Whether this track has any transitions between clips.

property transition_count: int

Number of transitions on this track.

property total_transition_duration_seconds: float

Total duration of all transitions on this track in seconds.

Sums the duration field (in ticks) of every transition dict and converts to seconds using the Camtasia edit rate.

property markers: MarkerList

Per-media markers (TOC keyframes in track parameters).

add_clip(clip_type, source_id, start, duration, **kwargs)[source]

Create a clip dict and append it to this track.

Parameters:
  • clip_type (str | ClipType) – The _type value (e.g. 'AMFile', 'IMFile').

  • source_id (int | None) – Source bin ID, or None for callouts/groups.

  • start (int) – Timeline position in ticks.

  • duration (int) – Playback duration in ticks.

  • **kwargs (Any) – Additional fields merged into the clip dict.

Return type:

BaseClip

Returns:

The newly created typed clip object.

insert_clip_at(clip_type, source_id, position_seconds, duration_seconds)[source]

Insert a clip at a position, shifting subsequent clips forward.

Combines add_clip with ripple_insert behavior.

Return type:

BaseClip

remove_clip(clip_id)[source]

Remove a clip by its ID.

Parameters:

clip_id (int) – The unique clip ID to remove.

Raises:

KeyError – No clip with the given ID exists on this track.

Return type:

None

remove_clips_by_type(clip_type)[source]

Remove all clips of a specific type. Returns count removed.

Return type:

int

remove_all_clips()[source]

Remove all clips but preserve the track. Returns count removed.

Return type:

int

ungroup_clip(clip_id)[source]

Ungroup a Group clip, placing its internal clips on this track.

The Group clip is removed and each of its internal clips is assigned a fresh ID and appended to this track.

Parameters:

clip_id (int) – The id of the Group clip to ungroup.

Return type:

list[BaseClip]

Returns:

List of newly placed clips on this track.

Raises:

KeyError – If no Group clip with the given ID exists.

move_clip_to_track(clip_id, target_track)[source]

Move a clip from this track to another track.

The clip is removed from this track and a deep copy (with a new ID) is appended to the target track’s media list.

Parameters:
  • clip_id (int) – The unique clip ID to move.

  • target_track (Track) – The destination track.

Return type:

BaseClip

Returns:

The newly created clip on the target track.

Raises:

KeyError – No clip with the given ID exists on this track.

remove_short_clips(minimum_duration_seconds)[source]

Remove all clips shorter than the given duration. Returns count removed.

Return type:

int

add_image(source_id, start_seconds, duration_seconds, **kwargs)[source]

Add an image clip (IMFile) to the track.

Parameters:
  • source_id (int) – Source bin ID for the image.

  • start_seconds (float) – Timeline position in seconds.

  • duration_seconds (float) – Playback duration in seconds.

  • **kwargs (Any) – Additional fields merged into the clip dict.

Return type:

IMFile

Returns:

The newly created IMFile clip.

add_audio(source_id, start_seconds, duration_seconds, **kwargs)[source]

Add an audio clip (AMFile) to the track.

Parameters:
  • source_id (int) – Source bin ID for the audio.

  • start_seconds (float) – Timeline position in seconds.

  • duration_seconds (float) – Playback duration in seconds.

  • **kwargs (Any) – Additional fields merged into the clip dict.

Return type:

AMFile

Returns:

The newly created AMFile clip.

add_video(source_id, start_seconds, duration_seconds, **kwargs)[source]

Add a video clip (VMFile) to the track.

Parameters:
  • source_id (int) – Source bin ID for the video.

  • start_seconds (float) – Timeline position in seconds.

  • duration_seconds (float) – Playback duration in seconds.

  • **kwargs (Any) – Additional fields merged into the clip dict.

Return type:

VMFile

Returns:

The newly created VMFile clip.

add_callout(text, start_seconds, duration_seconds, font_name='Arial', font_weight='Normal', font_size=96.0, **kwargs)[source]

Add a text callout clip to the track.

Parameters:
  • text (str) – The callout text content.

  • start_seconds (float) – Timeline position in seconds.

  • duration_seconds (float) – Playback duration in seconds.

  • font_name (str) – Font family name.

  • font_weight (str) – Font weight (e.g. 'Regular', 'Bold').

  • font_size (float) – Font size in points.

  • **kwargs (Any) – Additional fields merged into the clip dict.

Return type:

Callout

Returns:

The newly created Callout clip.

add_callout_from_builder(builder, start_seconds, duration_seconds)[source]

Add a callout using a CalloutBuilder configuration.

Return type:

Callout

add_title(text, start_seconds, duration_seconds, preset='centered', **kwargs)[source]

Add a title callout with preset styling.

Parameters:
  • text (str) – The title text content.

  • start_seconds (float) – Timeline position in seconds.

  • duration_seconds (float) – Playback duration in seconds.

  • preset (str) – Preset name. Currently only 'centered' is supported.

  • **kwargs (Any) – Additional fields merged into the clip dict.

Return type:

Callout

Returns:

The newly created Callout clip for further customization.

Raises:

ValueError – If the preset name is not recognized.

add_lower_third(title, subtitle, start_seconds, duration_seconds, title_color=None, accent_color=None, *, font_weight=900, scale=None, template_ident='Right Angle Lower Third')[source]

Add a Right Angle Lower Third title template to the track.

Parameters:
  • title (str) – Main heading text (replaces ‘Your Name Here’).

  • subtitle (str) – Body text (replaces ‘Lorem ipsum…’).

  • start_seconds (float) – Timeline position in seconds.

  • duration_seconds (float) – Playback duration in seconds.

  • title_color (tuple[int, int, int, int] | None) – Optional RGBA tuple (r, g, b, a) 0-255 for the title text fgColor.

  • accent_color (tuple[float, float, float] | None) – Optional (r, g, b) floats 0.0-1.0 for the accent line fill color.

  • font_weight (int) – Font weight for the title text (default 900).

  • scale (float | None) – Uniform scale for the outer Group (default None leaves the template scale unchanged).

  • template_ident (str) – Identity string for the outer Group (default 'Right Angle Lower Third').

Return type:

Group

Returns:

The newly created Group clip.

add_group(start_seconds, duration_seconds, internal_tracks=None, **kwargs)[source]

Add a Group clip to the track.

Parameters:
  • start_seconds (float) – Timeline position in seconds.

  • duration_seconds (float) – Playback duration in seconds.

  • internal_tracks (list[dict[str, Any]] | None) – List of internal track dicts. If None, an empty tracks list is created.

  • **kwargs (Any) – Additional fields merged into the clip dict.

Return type:

Group

Returns:

The newly created Group clip.

group_clips(clip_ids)[source]

Group the specified clips into a new Group clip.

The clips are removed from this track and placed inside a new Group clip at the earliest clip’s start position.

Parameters:

clip_ids (list[int]) – List of clip IDs to group together.

Return type:

Group

Returns:

The newly created Group containing the specified clips.

Raises:

KeyError – No clips found with the given IDs.

add_screen_recording(source_id, start_seconds, duration_seconds, background_source_id=1)[source]

Add a Camtasia Rev screen recording Group to the track.

Creates a Group with the standard Rev structure:

  • Track 0: VMFile shader background

  • Track 1: UnifiedMedia with ScreenVMFile video + AMFile audio

Parameters:
  • source_id (int) – Source bin ID for the .trec media entry.

  • start_seconds (float) – Timeline position in seconds.

  • duration_seconds (float) – Playback duration in seconds.

  • background_source_id (int) – Source bin ID for the background shader (defaults to 1).

Return type:

Group

Returns:

The newly created Group clip.

add_transition(name, left_clip, right_clip, duration_seconds=0.5)[source]

Add a named transition between two clips on this track.

Parameters:
  • name (str) – Transition type name (e.g. 'FadeThroughBlack').

  • left_clip (BaseClip) – The clip on the left side.

  • right_clip (BaseClip) – The clip on the right side.

  • duration_seconds (float) – Transition duration in seconds.

Return type:

Transition

Returns:

The newly created Transition.

add_fade_through_black(left_clip, right_clip, duration_seconds=0.5)[source]

Add a FadeThroughBlack transition between two clips.

Parameters:
  • left_clip (BaseClip) – The clip on the left side.

  • right_clip (BaseClip) – The clip on the right side.

  • duration_seconds (float) – Transition duration in seconds.

Return type:

Transition

Returns:

The newly created Transition.

add_image_sequence(source_ids, start_seconds, duration_per_image_seconds, transition_seconds=0.0, transition_name='FadeThroughBlack')[source]

Add a sequence of image clips, optionally with transitions.

Parameters:
  • source_ids (list[int]) – Source bin IDs for each image.

  • start_seconds (float) – Timeline position of the first image.

  • duration_per_image_seconds (float) – Duration of each image clip.

  • transition_seconds (float) – Transition duration between images (0 = none).

  • transition_name (str) – Transition type name.

Return type:

list[IMFile]

Returns:

List of created IMFile clips.

add_freeze_frame(source_clip, at_seconds, freeze_duration_seconds)[source]

Add a freeze frame from a source clip at a specific time.

Creates an image clip that shows a single frame from the source, placed at the specified time point.

Parameters:
  • source_clip (BaseClip) – The clip to capture a frame from.

  • at_seconds (float) – Timeline time (in seconds) of the frame to freeze.

  • freeze_duration_seconds (float) – How long the freeze frame should last.

Return type:

BaseClip

Returns:

The newly created freeze-frame clip.

Raises:

ValueError – If the source clip has no source ID or the computed media offset is negative.

extend_clip(clip_id, *, extend_seconds)[source]

Extend or shorten a clip’s duration.

Positive values extend, negative values shorten.

Parameters:
  • clip_id (int) – ID of the clip to extend.

  • extend_seconds (float) – Seconds to add (positive) or remove (negative).

Raises:
Return type:

None

reorder_clips(clip_ids)[source]

Reorder clips by ID list, packing them end-to-end starting at 0.

All transitions on the track are cleared. Raises ValueError if the provided IDs don’t exactly match the current clip IDs.

Parameters:

clip_ids (list[int]) – Clip IDs in the desired order.

Return type:

None

sort_clips()[source]

Sort clips by start time.

Return type:

None

reverse_clip_order()[source]

Reverse the order of clips while keeping them packed end-to-end.

Clips are sorted by their current start time, then placed back in reverse order so the last clip becomes first. All transitions are cleared because the adjacency relationships change.

Return type:

None

property first_clip: BaseClip | None

First clip by start time, or None if track is empty.

property last_clip: BaseClip | None

Last clip by end time, or None if track is empty.

property is_empty: bool

True if this track has no clips.

clips_at(time_seconds)[source]

Return all clips that span the given time point.

Return type:

list[BaseClip]

split_at_time(time_seconds)[source]

Split all clips that span the given time point. Returns count split.

Delegates to split_all_clips_at().

Return type:

int

split_all_clips_at(time_seconds)[source]

Split every clip that spans the given time point.

Iterates all clips returned by clips_at() and calls split_clip() on each. Clips where the split point falls exactly on the start or end boundary are silently skipped (since they cannot be split there).

Parameters:

time_seconds (float) – Absolute timeline position in seconds at which to split.

Return type:

int

Returns:

The number of clips that were actually split.

find_clip_at(time_seconds)[source]

Return the first clip at the given time, or None.

Return type:

BaseClip | None

property total_duration_seconds: float

Total duration of all clips on this track in seconds.

property total_clip_duration_ticks: int

Sum of all clip durations in ticks.

property average_clip_duration_seconds: float

Average clip duration in seconds, or 0.0 if empty.

property duration_seconds: float

Total duration of all clips (alias for total_duration_seconds).

gaps()[source]

Find gaps between clips on this track.

Returns list of (start_seconds, end_seconds) tuples for each gap.

Return type:

list[tuple[float, float]]

property total_gap_seconds: float

Total gap time between clips in seconds.

property first_gap: tuple[float, float] | None

The first gap between clips, or None if no gaps exist.

property largest_gap: tuple[float, float] | None

The largest gap between clips, or None if no gaps exist.

find_gaps_longer_than(threshold_seconds)[source]

Find gaps between clips that exceed the given duration threshold.

Parameters:

threshold_seconds (float) – Minimum gap duration in seconds to include.

Return type:

list[tuple[float, float]]

Returns:

List of (gap_start, gap_end) tuples in seconds for gaps exceeding the threshold.

overlaps()[source]

Find overlapping clips on this track.

Returns list of (clip_id_a, clip_id_b) tuples for overlapping pairs.

Return type:

list[tuple[int, int]]

filter_clips(predicate)[source]

Return clips matching a predicate function.

Return type:

list[BaseClip]

filter_and_remove(predicate)[source]

Remove all clips matching the predicate. Returns count removed.

Return type:

int

keep_only(predicate)[source]

Keep only clips matching the predicate, remove the rest. Returns count removed.

Return type:

int

clips_between(range_start_seconds, range_end_seconds)[source]

Return all clips that fall entirely within the given time range.

Return type:

list[BaseClip]

property muted_clips: list[BaseClip]

Return clips whose audio is muted (gain == 0).

property audio_clips: list[BaseClip]

Return all audio clips on this track.

property video_clips: list[BaseClip]

Return all video clips on this track.

property visible_clips: list[BaseClip]

All non-audio clips on this track.

property image_clips: list[BaseClip]

Return all image clips on this track.

property clip_types: set[str]

Set of unique clip types on this track.

property clip_count_by_type: dict[str, int]

Count of clips grouped by type.

property keyframed_clips: list[BaseClip]

All clips that have keyframe animations.

property effect_names: set[str]

Set of unique effect names across all clips on this track.

find_clips_with_effect(effect_name)[source]

Find all clips that have a specific effect applied.

Return type:

list[BaseClip]

find_clips_without_effects()[source]

Find all clips that have no effects applied.

Return type:

list[BaseClip]

end_time_ticks()[source]

End time of the last clip on this track, in ticks.

Return type:

int

end_time_seconds()[source]

Return the end time of the last clip on this track in seconds.

Return type:

float

Returns:

Maximum start + duration across all clips, in seconds. Returns 0.0 if the track has no clips.

property total_end_seconds: float

End time of the last clip in seconds.

set_segment_speeds(clip_id, segments)[source]

Split a clip into segments with per-segment playback speeds.

Splits the clip at the boundaries defined by each segment’s timeline duration, then sets the appropriate scalar on each piece so it plays at the requested speed.

Internally handles the Camtasia-specific scalar formula, mediaStart accumulation, VMFile scalar compensation, and clipSpeedAttribute metadata.

Parameters:
  • clip_id (int) – ID of the clip to split and speed-adjust.

  • segments (list[tuple[float, float]]) – List of (timeline_duration_seconds, speed) tuples. speed is a multiplier where 1.0 means the clip’s original playback rate, 2.0 means twice as fast, 0.5 means half speed, etc. The sum of all timeline_duration_seconds must equal the clip’s current duration.

Return type:

list

Returns:

List of the resulting clip objects (one per segment).

trim_clip(clip_id, *, trim_start_seconds=0.0, trim_end_seconds=0.0)[source]

Trim a clip’s start and/or end.

Positive trim_start removes from the beginning (clip starts later, mediaStart advances). Positive trim_end removes from the end (clip ends earlier, duration decreases).

Parameters:
  • clip_id (int) – ID of the clip to trim.

  • trim_start_seconds (float) – Seconds to trim from the start.

  • trim_end_seconds (float) – Seconds to trim from the end.

Return type:

None

duplicate_clip(clip_id, *, offset_seconds=0.0)[source]

Duplicate a clip on this track.

Creates a deep copy of the clip with a new ID, placed immediately after the original (or offset by offset_seconds).

Parameters:
  • clip_id (int) – ID of the clip to duplicate.

  • offset_seconds (float) – Time offset from the original’s end (default 0).

Return type:

BaseClip

Returns:

The new clip.

move_clip(clip_id, new_start_seconds)[source]

Move a clip to a new timeline position.

Parameters:
  • clip_id (int) – ID of the clip to move.

  • new_start_seconds (float) – New start position in seconds.

Return type:

None

split_clip(clip_id, split_at_seconds)[source]

Split a clip into two halves at a timeline position.

The left half keeps the original clip dict (mutated in place). The right half is a deep copy inserted immediately after.

For Group clips, internal tracks are deep-copied unchanged — the Group’s mediaStart/mediaDuration act as a viewing window into the internal timeline.

Parameters:
  • clip_id (int) – ID of the clip to split.

  • split_at_seconds (float) – Absolute timeline position in seconds.

Return type:

tuple

Returns:

Tuple of (left_clip, right_clip) as typed clip objects.

Raises:
  • KeyError – No clip with the given ID on this track.

  • ValueError – Split point is outside the clip’s time range.

swap_clips(clip_id_a, clip_id_b)[source]

Swap the timeline positions of two clips.

Exchanges the start times of the two clips.

Return type:

None

merge_adjacent_clips(clip_id_a, clip_id_b)[source]

Merge two adjacent clips into one by extending the first.

The first clip’s duration is extended to cover both clips. The second clip is removed. Transitions between them are removed.

Parameters:
  • clip_id_a (int) – ID of the first (earlier) clip.

  • clip_id_b (int) – ID of the second (later) clip to merge into the first.

Return type:

BaseClip

Returns:

The extended first clip.

Raises:

KeyError – Either clip not found.

replace_clip(clip_id, new_clip_data)[source]

Replace a clip with new data, preserving the timeline position.

The new clip inherits the original’s start time and gets a new ID.

Parameters:
  • clip_id (int) – ID of the clip to replace.

  • new_clip_data (dict) – Dict for the replacement clip (from clone() or manual construction).

Return type:

BaseClip

Returns:

The new clip.

summary()[source]

Human-readable track summary.

Return type:

str

describe()[source]

Human-readable track description.

Return type:

str

apply_to_all(fn)[source]

Apply a function to every clip on this track. Returns count.

Return type:

int

set_opacity(value)[source]

Set opacity for all clips on this track.

Return type:

None

set_volume(value)[source]

Set volume for all clips on this track.

Return type:

None

to_list()[source]

Return a list of clip summary dicts.

Return type:

list[dict[str, Any]]

remove_all_effects()[source]

Remove all effects from all clips on this track. Returns count.

Return type:

int

clip_at_index(clip_index)[source]

Return the clip at the given positional index (sorted by start time).

Return type:

BaseClip

clip_before(time_seconds)[source]

Return the last clip that ends before the given time, or None.

Return type:

BaseClip | None

clip_after(time_seconds)[source]

Return the first clip that starts after the given time, or None.

Return type:

BaseClip | None

normalize_timing()[source]

Shift all clips so the first clip starts at time 0.

Return type:

None

align_clips_to_start()[source]

Move all clips so they start sequentially from time 0 with no gaps.

Return type:

None

property total_media_duration_seconds: float

Sum of all clip durations (may differ from end_time if there are gaps).

distribute_evenly(gap_seconds=0.0)[source]

Distribute clips evenly with equal gaps between them.

Return type:

None

insert_gap(at_seconds, gap_duration_seconds)[source]

Insert a gap at the specified time, pushing all subsequent clips forward.

Return type:

None

remove_gap_at(at_seconds)[source]

Remove a gap at the specified time by pulling subsequent clips backward.

Finds the gap that contains at_seconds and shifts all clips that start at or after the gap’s end backward by the gap’s duration. Does nothing if no gap exists at the given time.

Return type:

None

shift_all_clips(offset_seconds)[source]

Shift all clips on this track by the given offset.

Positive values move clips forward, negative moves backward. Clips are clamped to not go before time 0.

Return type:

None

scale_all_durations(factor)[source]

Scale all clip durations by a factor (e.g., 2.0 = double length).

Return type:

None

partition_by_type()[source]

Group clips by their type, returning a dict of type -> clip list.

Return type:

dict[str, list[BaseClip]]