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:
objectA zoom/pan keyframe on the timeline.
- class camtasia.timeline.timeline.Timeline(timeline_data)[source]¶
Bases:
objectRepresents the timeline of a Camtasia project.
- property tracks: _TrackAccessor¶
Iterable accessor over Track objects.
- remove_tracks_by_name(name)[source]¶
Remove all tracks with the given name. Returns count removed.
- Return type:
- 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. Returns1for an empty project.- Return type:
- duplicate_track(source_track_index)[source]¶
Duplicate a track and all its clips. Returns the new track.
- Return type:
- move_track_to_back(track_index)[source]¶
Move a track to position 0 (behind all other tracks).
- Return type:
- move_track_to_front(track_index)[source]¶
Move a track to the last position (in front of all other tracks).
- Return type:
- find_clip(clip_id)[source]¶
Find a clip by ID across all tracks.
Returns (track, clip) tuple, or None.
- reorder_tracks(order)[source]¶
Reorder tracks by providing current trackIndex values in desired order.
- 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:
- Returns:
Duration in seconds, or 0.0 if the timeline is empty.
- all_clips()[source]¶
All clips across all tracks, including nested clips inside Groups/StitchedMedia/UnifiedMedia.
- 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:
- remove_all_empty_tracks()[source]¶
Remove every track that contains no clips.
- Return type:
- 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:
- 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:
- 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].
- 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:
- Return type:
- property caption_attributes: CaptionAttributes¶
Caption styling configuration.
- validate_structure()[source]¶
Check timeline structural invariants.
Returns a list of issue descriptions (empty = valid).
- 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.
- 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:
- apply_to_all_clips(fn)[source]¶
Apply a function to every clip on every track. Returns count.
- Return type:
- insert_gap(position_seconds, gap_duration_seconds)[source]¶
Insert a gap at a position across ALL tracks, shifting subsequent clips.
- Return type:
- remove_gap(position_seconds, gap_duration_seconds)[source]¶
Remove a gap at a position across ALL tracks, pulling subsequent clips back.
- Return type:
Track on the timeline — wraps a single track dict and its attributes.
- class camtasia.timeline.track.Track(attributes, data, _all_tracks=None)[source]¶
Bases:
objectA track on the timeline.
Wraps both the track data dict (from
csml.tracks) and the corresponding entry intrackAttributes.- Parameters:
Whether the track’s video is hidden.
- property is_muted: bool¶
Alias for
audio_muted.
Alias for
video_hidden.
- 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:
- property clips: _ClipAccessor¶
Iterable accessor over typed clip objects on this track.
- property medias: _ClipAccessor¶
Alias for
clips(backward compatibility).
- property transitions: TransitionList¶
Track-level transitions between clips.
- property total_transition_duration_seconds: float¶
Total duration of all transitions on this track in seconds.
Sums the
durationfield (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:
- Return type:
- 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:
- remove_clips_by_type(clip_type)[source]¶
Remove all clips of a specific type. Returns count removed.
- Return type:
- remove_all_clips()[source]¶
Remove all clips but preserve the track. Returns count removed.
- Return type:
- 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.
- 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.
- remove_short_clips(minimum_duration_seconds)[source]¶
Remove all clips shorter than the given duration. Returns count removed.
- Return type:
- add_image(source_id, start_seconds, duration_seconds, **kwargs)[source]¶
Add an image clip (IMFile) to the track.
- add_audio(source_id, start_seconds, duration_seconds, **kwargs)[source]¶
Add an audio clip (AMFile) to the track.
- add_video(source_id, start_seconds, duration_seconds, **kwargs)[source]¶
Add a video clip (VMFile) to the track.
- 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:
- 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:
- add_title(text, start_seconds, duration_seconds, preset='centered', **kwargs)[source]¶
Add a title callout with preset styling.
- Parameters:
- Return type:
- 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 textfgColor.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 (defaultNoneleaves the template scale unchanged).template_ident (
str) – Identity string for the outer Group (default'Right Angle Lower Third').
- Return type:
- 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:
- Return type:
- 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.
- 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:
- Return type:
- 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:
- Return type:
- 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:
- Return type:
- 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:
- Return type:
- 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:
- Return type:
- 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:
- Raises:
KeyError – Clip not found.
ValueError – Would result in zero or negative duration.
- Return type:
- 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.
- 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:
- 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:
- split_all_clips_at(time_seconds)[source]¶
Split every clip that spans the given time point.
Iterates all clips returned by
clips_at()and callssplit_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).
- gaps()[source]¶
Find gaps between clips on this track.
Returns list of (start_seconds, end_seconds) tuples for each gap.
- 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.
- overlaps()[source]¶
Find overlapping clips on this track.
Returns list of (clip_id_a, clip_id_b) tuples for overlapping pairs.
- filter_and_remove(predicate)[source]¶
Remove all clips matching the predicate. Returns count removed.
- Return type:
- keep_only(predicate)[source]¶
Keep only clips matching the predicate, remove the rest. Returns count removed.
- Return type:
- clips_between(range_start_seconds, range_end_seconds)[source]¶
Return all clips that fall entirely within the given time range.
- end_time_seconds()[source]¶
Return the end time of the last clip on this track in seconds.
- Return type:
- Returns:
Maximum
start + durationacross all clips, in seconds. Returns0.0if the track has no clips.
- 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,
mediaStartaccumulation, VMFile scalar compensation, andclipSpeedAttributemetadata.- 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 where1.0means the clip’s original playback rate,2.0means twice as fast,0.5means half speed, etc. The sum of all timeline_duration_seconds must equal the clip’s current duration.
- Return type:
- 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).
- 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).
- 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/mediaDurationact as a viewing window into the internal timeline.- Parameters:
- Return type:
- 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:
- 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.
- 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.
- remove_all_effects()[source]¶
Remove all effects from all clips on this track. Returns count.
- Return type:
- clip_at_index(clip_index)[source]¶
Return the clip at the given positional index (sorted by start time).
- Return type:
- align_clips_to_start()[source]¶
Move all clips so they start sequentially from time 0 with no gaps.
- Return type:
- 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:
- insert_gap(at_seconds, gap_duration_seconds)[source]¶
Insert a gap at the specified time, pushing all subsequent clips forward.
- Return type:
- 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:
- 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: