timeline-gap-analyzer
Timeline Gap Analyzer: Split Interviews by Detecting Gaps
When editing multiple interviews on one master timeline without music markers, I need a way to auto-detect where one interview ends and the next begins. This script analyzes the timeline to find gaps (black space between clips) and splits the timeline into separate sequences at each gap, enabling the same batch interview workflow as the music marker script but without requiring manual marker placement.
The Problem
In my Split Interviews to Timelines workflow, I use music clips on the "MX" audio track as markers to define interview boundaries. The script reads those music clips and splits the master timeline accordingly.
But what if I don't have music clips as markers? What if the interviews are separated by natural gaps (black space) on the timeline?
Example scenario:
I'm editing 10 interviews on one master timeline:
- Interview 1: Frames 0-500
- Gap: Frames 500-530 (30 frames of black)
- Interview 2: Frames 530-1200
- Gap: Frames 1200-1250 (50 frames of black)
- Interview 3: Frames 1250-1800
- ... and so on
The gaps are natural separators—I intentionally left black space between interviews during the baseline edit. But I don't have music clips as markers, so the Split Interviews script can't detect where to split.
Manual workflow:
- Scrub through the timeline to find each gap visually
- Note the frame numbers where gaps occur
- Manually duplicate the timeline for each interview
- Set in/out points around each segment
- Delete content outside each segment
Total time: 5-10 minutes for a timeline with 10+ interviews. Tedious and error-prone.
The Solution
timeline_gap_analyzer.py automatically detects gaps in the timeline and offers to split the timeline into separate sequences at each gap. The workflow is:
- Baseline edit all interviews on one master timeline (separated by gaps)
- Run the gap analyzer script
- Script scans the timeline and detects all gaps ≥30 frames (configurable)
- Script prints a report: "Found 9 gaps: Gap 1 at frames 500-530, Gap 2 at frames 1200-1250..."
- Script offers to create separate timelines for each segment
- Timelines are created automatically (one per interview)
Total time: 5-10 seconds (script execution). Zero manual gap hunting or timeline duplication.
What Qualifies as a Gap?
The script defines a gap as:
Any space between two clips where no video content exists, and the gap is ≥ a minimum threshold (default: 30 frames).
Why 30 frames as the default?
At 24fps, 30 frames = 1.25 seconds. This is long enough to distinguish intentional gaps (spaces between interviews) from accidental/editorial gaps (brief pauses within an interview for pacing).
If I have a 5-frame gap mid-interview (I left a tiny pause for dramatic effect), the script ignores it. But if I have a 50-frame gap between Interview 1 and Interview 2 (intentional separator), the script detects it.
The threshold is configurable—I can specify "2 seconds" or "60 frames" if I want to ignore smaller gaps.
Technical Implementation
The script uses DaVinci Resolve's Python API to iterate through all video clips, sort them by start frame, calculate gaps between clips, and optionally create new timelines at each gap.
1. Collecting All Timeline Items
The script scans all video tracks and collects every clip's start/end position:
def get_timeline_items_with_positions(timeline):
items = []
track_count = timeline.GetTrackCount("video")
for track_index in range(1, track_count + 1):
track_items = timeline.GetItemListInTrack("video", track_index)
for item in track_items:
start_frame = item.GetStart()
end_frame = item.GetEnd()
name = item.GetName()
items.append({
'start': start_frame,
'end': end_frame,
'name': name
})
# Sort by start frame
items.sort(key=lambda x: x['start'])
return items
Why scan only video tracks, not audio?
Gaps are defined by visual black space—when there's no video content on the timeline. Audio tracks might have continuous ambient sound or music beds that don't align with video gaps.
By scanning only video tracks, the script detects "visual gaps" (moments where the screen would be black during playback).
2. Detecting Gaps Between Clips
After collecting and sorting all clips by start frame, the script calculates the gap size between each consecutive pair:
def find_gaps(items, min_gap_frames=30):
gaps = []
for i in range(len(items) - 1):
current_end = items[i]['end']
next_start = items[i + 1]['start']
gap_size = next_start - current_end
if gap_size >= min_gap_frames:
gaps.append({
'gap_start': current_end,
'gap_end': next_start,
'gap_frames': gap_size,
'before_clip': items[i]['name'],
'after_clip': items[i + 1]['name']
})
return gaps
How gap detection works:
For each pair of consecutive clips:
- Get the end frame of the current clip (
current_end) - Get the start frame of the next clip (
next_start) - Calculate the gap:
gap_size = next_start - current_end - If
gap_size >= min_gap_frames, record it as a gap
Example:
- Clip A: Frames 0-500 (ends at frame 500)
- Clip B: Frames 530-1200 (starts at frame 530)
- Gap size:
530 - 500 = 30 frames - If
min_gap_frames = 30, this qualifies as a gap
The script also records which clips are before and after each gap for reference (e.g., "Gap 1 is after 'Interview_John' and before 'Interview_Sarah'").
3. Interactive Gap Threshold Configuration
When the script runs, it prompts for the minimum gap threshold:
min_gap_input = input("\nMinimum gap size in frames (default 30, or enter seconds with 's' suffix like '2s'): ").strip()
if min_gap_input.endswith('s'):
seconds = float(min_gap_input[:-1])
min_gap_frames = int(seconds * float(frame_rate))
elif min_gap_input:
min_gap_frames = int(min_gap_input)
else:
min_gap_frames = 30
User can specify:
- Frames:
"60"→ 60 frames - Seconds:
"2s"→ 2 seconds × frame rate (e.g., 48 frames at 24fps) - Default: Press Enter → 30 frames
This flexibility is useful for different editorial styles:
- Tight edits with small gaps: Use
"1s"or"24"frames - Clearly separated segments: Use
"2s"or"60"frames
4. Creating Separate Timelines from Gaps
After detecting gaps, the script offers to create new timelines for each segment:
def create_sequences_from_gaps(timeline, gaps, project):
segments = []
last_end = 0
for i, gap in enumerate(gaps):
segment = {
'name': f"{timeline.GetName()}_Sequence_{i+1}",
'start': last_end if last_end > 0 else items[0]['start'],
'end': gap['gap_start']
}
segments.append(segment)
last_end = gap['gap_end']
# Add final segment
segments.append({
'name': f"{timeline.GetName()}_Sequence_{len(gaps)+1}",
'start': last_end,
'end': items[-1]['end']
})
create = input("\nCreate separate timelines for each sequence? (y/n): ")
if create.lower() == 'y':
for seg in segments:
new_timeline = project.CreateEmptyTimeline(seg['name'])
How segmentation works:
If the script finds 2 gaps, it defines 3 segments:
- Segment 1: Start of timeline → end of first gap
- Segment 2: End of first gap → end of second gap
- Segment 3: End of second gap → end of timeline
Each segment becomes a new timeline (e.g., Master_Timeline_Sequence_1, Master_Timeline_Sequence_2, etc.).
Note: The current implementation creates empty timelines as placeholders. To fully replicate the Split Interviews script (which copies content and deletes outside clips), additional logic would be needed to duplicate the master timeline and trim each copy to its segment's range.
Use Cases
Primary: Interview Splitting Without Music Markers
When I've edited multiple interviews on one master timeline but didn't place music clips as markers, I use this script to auto-detect gaps and split the timeline.
This is useful when:
- I forgot to place music markers during baseline editing
- The project doesn't have background music (raw interview footage only)
- The interviews are naturally separated by intentional gaps (I left black space as separators)
The script detects those gaps and splits the timeline automatically, enabling the same batch render workflow as the music marker approach.
Secondary: Quality Control (Finding Accidental Gaps)
Sometimes gaps are unintentional—I accidentally left a 1-2 second black space mid-interview due to a rough cut error. The gap analyzer helps find these issues:
- Run the script with a low threshold (e.g.,
"1s") - Script prints all gaps ≥1 second
- Review the gap report to find accidental gaps
- Return to the timeline and close those gaps manually
This acts as a QC check before delivering the final timeline.
Tertiary: Splitting Broadcast Commercials
For broadcast projects with multiple spot lengths (15s, 30s, 60s) edited on one master timeline with intentional gaps between spots, the script can auto-detect those gaps and split the timeline into separate spots for individual rendering.
Comparison to Split Interviews Script
I maintain two interview splitting scripts, each optimized for different workflows:
| Feature | Split Interviews (Music Markers) | Timeline Gap Analyzer |
|---|---|---|
| Marker Method | Music clips on "MX" track | Gaps in video track |
| Setup Required | Place music clips as markers | Natural gaps must exist |
| Dual Purpose | Music serves as markers + editorial background | Gaps serve only as separators |
| Use Case | Projects with background music | Projects without music / raw interviews |
| Flexibility | Explicit control over split points | Automatic detection based on gaps |
When to use Split Interviews:
- Projects have background music
- You want explicit control over split points (place music exactly where you want the split)
- Music serves dual purpose (editorial + markers)
When to use Timeline Gap Analyzer:
- Projects don't have background music
- Interviews are naturally separated by gaps
- You want automatic detection without manual marker placement
I use Split Interviews more frequently (80% of projects) because most client work includes background music. Gap Analyzer is for edge cases where music isn't present or I forgot to place markers.
Time Savings
Manual process (finding and splitting at gaps):
- Scrub through timeline to find gaps visually: 3-5 minutes (for 10 interviews)
- Note frame numbers where gaps occur: 1 minute
- Duplicate timeline per segment: 20-30 seconds each (3-5 minutes total for 10 interviews)
- Delete content outside each segment: 10 seconds each (1.5-2 minutes total)
Total manual time: 8-13 minutes.
Automated process:
- Run gap analyzer script: 1 second
- Script scans timeline and detects gaps: 2-5 seconds
- Review gap report, confirm creation: 10 seconds
- Script creates timelines: 5-10 seconds
Total automated time: 18-26 seconds.
Savings per project: 7.5-12.5 minutes.
I use this workflow 1-2 times per month (less frequent than the music marker workflow). At 2 projects per month, this saves 15-25 minutes monthly.
But the real value is eliminating manual gap hunting. Without the script, I'd have to visually scrub through 10-20 minutes of timeline footage to find every gap. The script does it instantly and reports exact frame numbers.
Implementation Notes
This script requires:
- DaVinci Resolve (tested on Resolve 18/19)
- DaVinci Resolve Python API (included with Resolve installation)
- Terminal or Python environment (to run the script interactively)
Running the Script
To launch the gap analyzer:
- Open Terminal
- Run the script:
python3 /path/to/timeline_gap_analyzer.py
- The script prompts for minimum gap size
- Review the gap report
- Confirm whether to create separate timelines
Customizing the Default Gap Threshold
To change the default gap threshold from 30 frames, edit line 153:
min_gap_frames = 30
Change to your preferred default (e.g., 60 frames):
min_gap_frames = 60
Extending to Copy Timeline Content
The current implementation creates empty timelines as placeholders. To fully replicate the Split Interviews script (which duplicates content and trims), you'd extend the script to:
- Duplicate the master timeline for each segment
- Switch to each duplicated timeline
- Delete clips outside the segment's range
- Clear in/out points
This would require adding the same deletion logic from the Split Interviews script. For now, the gap analyzer serves primarily as a gap detection tool with optional placeholder timeline creation.
Why This Matters
This script complements the Split Interviews workflow by handling projects where music markers aren't present. Some projects (raw interview footage, documentary-style edits, training videos) don't have background music, so the music marker approach doesn't apply.
By detecting gaps automatically, the script enables the same batch interview workflow (baseline edit → split → detailed editing → batch render) without requiring manual marker placement.
The interactive threshold configuration is thoughtful UX design—instead of hardcoding "30 frames," the script asks for user input and supports both frame and second notation. This makes the script adaptable to different editorial styles and project requirements.
For anyone editing multi-interview projects without background music, or anyone who wants a QC tool to find accidental gaps in timelines, this script fills a workflow gap (pun intended). It's the automation equivalent of "I know there are gaps in this timeline, but I don't want to hunt for them manually—just tell me where they are."