Files
gui-video-clipper/chat-summaries/2026-09-21_23-00-styled-burnin-export-progress-summary.md
cottongin 8ad2f1c800 chore: stage all pending work — caption styling, media server, processing modal, docs, summaries
Includes:
- Extended caption styling (font, shadow, dimmed color, bg toggle)
- Media server, subtitle downloader, VTT parser, processing modal
- Waveform tiers, thumbnail/timeline improvements, transport controls
- Hybrid download model, dependency management, clip export enhancements
- 21 chat summaries, 2 implementation plans, 2 design specs

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 10:48:16 -04:00

65 lines
4.0 KiB
Markdown

# Styled Burn-In and Granular Export Progress
**Date:** 2026-09-21 23:00
**Task:** Apply user's caption style settings to burned-in subtitles via ffmpeg's ASS force_style, and add granular per-clip progress reporting during export.
## Changes Made
### 1. CaptionStyle Model (Rust + TS)
- **`src-tauri/src/models.rs`** — Added `CaptionStyle` struct with `font_size`, `text_color`, `background_opacity`, `text_outline`, `position`. Added `caption_style: Option<CaptionStyle>` to `ExportConfig`.
- **`src/lib/bindings/export.ts`** — Added matching `CaptionStyle` interface and `captionStyle: CaptionStyle | null` to `ExportConfig`. Added `clipProgress` event variant to the discriminated union. Added optional `onClipProgress` callback parameter to `exportClips()`.
### 2. ASS force_style in clip_exporter.rs
- **`src-tauri/src/services/clip_exporter.rs`**:
- `hex_to_ass_color()` — Converts CSS hex `#RRGGBB` to ASS `&H00BBGGRR` format.
- `opacity_to_ass_back_colour()` — Converts 0-1 opacity to ASS alpha-prefixed BackColour.
- `caption_style_to_force_style()` — Builds the full ASS force_style string from CaptionStyle (Fontsize, PrimaryColour, BackColour, Outline, Shadow, Alignment, MarginV, BorderStyle).
- `build_ffmpeg_args_burnin_subs()` now accepts `Option<&CaptionStyle>` and appends `:force_style='...'` to the subtitles filter when provided.
- `parse_ffmpeg_time()` — Extracts `time=HH:MM:SS.mm` from ffmpeg stderr progress output.
- `run_ffmpeg_with_progress()` — Runs ffmpeg with piped stderr, parses progress lines, and invokes a callback with 0.0-1.0 percent values.
### 3. Progress Callbacks Throughout Export Pipeline
All four export functions (`export_single_clip`, `export_single_clip_with_subs`, `export_merged`, `export_merged_with_subs`) now accept progress callbacks. They use `run_ffmpeg_with_progress()` instead of `.output()` for the encode step, streaming real-time progress.
### 4. export.rs Command Handler
- **`src-tauri/src/commands/export.rs`** — Added `ClipProgress` event variant with `current`, `total`, `label`, `percent`. Wired progress callbacks for both Individual and Merged export paths. Passes `caption_style` through to the exporter.
### 5. ExportDialog Frontend
- **`src/lib/components/ExportDialog.svelte`**:
- Populates `captionStyle` in config from `preferences.captionSettings` when burn-in is enabled.
- Shows a progress bar with percentage during each clip export.
- Displays note that karaoke word highlighting is preview-only for burn-in.
## Files Modified
| File | Change |
|------|--------|
| `src-tauri/src/models.rs` | Added `CaptionStyle` struct, added field to `ExportConfig` |
| `src-tauri/src/services/clip_exporter.rs` | ASS helpers, force_style, ffmpeg progress streaming, progress callbacks |
| `src-tauri/src/commands/export.rs` | `ClipProgress` event, caption_style passthrough, progress wiring |
| `src/lib/bindings/export.ts` | `CaptionStyle` interface, `clipProgress` event, `onClipProgress` callback |
| `src/lib/components/ExportDialog.svelte` | captionStyle in config, progress bar UI, karaoke note |
## Build Verification
- `cargo check` — passes (only pre-existing warnings)
- `cargo test` — all 43 tests pass
- `svelte-check` — passes (only pre-existing `vite.config.ts` errors)
## Lessons Learned
- ASS color format uses BGR byte order with alpha prefix (`&HAA_BB_GG_RR`), where alpha `00` = opaque and `FF` = transparent (inverted from CSS).
- `BorderStyle=4` in ASS gives an opaque background box behind text (like CSS background), vs `BorderStyle=1` which uses outline+shadow only.
- ffmpeg progress is on stderr, not stdout. The `time=` field is the key metric for computing encode progress percentage.
- For merged exports, progress is reported per-segment during encoding, plus a concat step at the end.
## Follow-Up Items
- Smoke test burn-in export to verify styled subtitles render correctly.
- Karaoke word-by-word animation in burn-in would require converting VTT word timestamps to ASS `\k` override tags — complex and fragile, noted as preview-only limitation.