-
-
Notifications
You must be signed in to change notification settings - Fork 38
Story Clip Mode
Story Clip is a multi-source narrative assembly pipeline designed for campaigns (e.g., brand briefs) where you need to take specific scenes from various video sources and combine them into a cohesive story.
Unlike the standard auto-clipping mode (which uses AI to find highlights), Story Clip mode lets you manually define exactly which scenes to use, from which videos, and in what order.
- Multi-Source β Combine segments from YouTube, TikTok, Instagram, Google Drive, or local files
- Automatic Normalization β Different resolutions and FPS are normalized seamlessly
- Hook + Highlight β Each clip generates two separate outputs: a teaser hook and the main content
- Auto-Transcription β Whisper transcription runs automatically and is cached for reference
- Clean Output β Videos are produced without subtitles or text overlays by default
- Idempotent Downloads β Already-downloaded files are never re-downloaded
python main.py --story-mode \
--story-recipe story_recipe.json \
--sources-json sources.json| Flag | Description |
|---|---|
--skip-download |
Skip downloads if all source videos are already cached |
--story-output-dir |
Custom output directory (default: outputs/story_clips) |
--ratio |
Override the global render ratio (default from recipe) |
1. Load Sources (sources.json)
β
2. Download & Cache (outputs/story_cache/)
β
3. Transcribe (Faster-Whisper β cached transcripts)
β
4. Load Recipe (story_recipe.json)
β
5. Assembly (FFmpeg trim β normalize β concat)
β
6. Output Manifest (story_manifest.json)
Register all raw video sources here. Each source needs an id, name, url, and platform.
| Platform | Value |
|---|---|
| YouTube | youtube |
| TikTok | tiktok |
instagram |
|
| Google Drive | gdrive |
| Local File | local |
{
"$schema": "sources_v1",
"sources": [
{
"id": "speaker_a",
"name": "Speaker A β Main Interview",
"url": "https://www.youtube.com/watch?v=ABC123",
"platform": "youtube"
},
{
"id": "broll_city",
"name": "City B-Roll Stock",
"url": "https://www.tiktok.com/@user/video/1234567890",
"platform": "tiktok"
},
{
"id": "local_intro",
"name": "Custom Intro Animation",
"url": "/path/to/intro.mp4",
"platform": "local"
}
]
}This file is your digital director. Define the exact sequence of scenes for each clip.
{
"$schema": "story_recipe_v1",
"project_name": "Campaign Name",
"default_settings": {
"ratio": "9:16"
},
"clips": [
{
"clip_id": 1,
"title": "Clip Title",
"hook": {
"scenes": [
{
"source_id": "speaker_a",
"start": 0.0,
"end": 5.0,
"label": "Attention-grabbing quote"
}
]
},
"highlight": {
"scenes": [
{
"source_id": "speaker_a",
"start": 30.0,
"end": 45.0,
"label": "Main content section"
},
{
"source_id": "broll_city",
"start": 2.0,
"end": 6.0,
"label": "City establishing shot"
}
],
"transition": "cut"
}
}
]
}| Field | Required | Description |
|---|---|---|
source_id |
β | References the id from sources.json
|
start |
β | Start time in seconds (decimal) |
end |
β | End time in seconds (decimal) |
label |
β | Description of the scene (for tracking) |
| Type | Description |
|---|---|
cut |
Hard cut between scenes |
smooth / crossfade
|
0.5 second dissolve transition |
outputs/
βββ story_cache/ # Downloaded source videos (persistent cache)
β βββ speaker_a.mp4
β βββ broll_city.mp4
β βββ *_transcript.json # Whisper transcriptions
βββ story_clips/ # Final assembled clips
β βββ clip_1/
β β βββ hook_1.mp4 # Teaser/hook video
β β βββ highlight_1.mp4 # Main story video
β βββ clip_2/
β βββ hook_2.mp4
β βββ highlight_2.mp4
βββ story_manifest.json # Status report for all clips
-
Fast Iteration β Since all sources are cached, if clip timing feels off, just change
start/endin the recipe and re-run. No re-downloading needed. -
Use Labels β Always fill in the
labelfield so you can track story context without replaying raw videos. -
Read Transcripts β Check the auto-generated
*_transcript.jsonfiles instory_cache/to find exact timestamps for quotes and moments. -
Skip Downloads β After your first run, use
--skip-downloadto speed up iteration:python main.py --story-mode --skip-download --story-recipe story_recipe.json
The repository includes sample configuration files in example/story/:
-
sources.sample.jsonβ Example source registry -
story_recipe.sample.jsonβ Example recipe
- Getting Started β General setup
- CLI Reference β All Story Clip flags