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

4.0 KiB

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.