# Fix Caption Export Bugs (Round 2) ## Task Three bugs in the caption export implementation needed fixing after the initial burn-in/mux feature was added. ## Bug 1: Burn-in filter syntax error **Symptom**: ffmpeg error `No option name near '/var/.../sanitized.vtt'` **Root cause**: `format!("subtitles='{}'", path)` passed literal single quotes to ffmpeg via `Command::args()`. Since there's no shell to strip them, ffmpeg tried to open `'sanitized.vtt'` (with quotes in the filename). **Fix**: Changed to `format!("subtitles={}", path)` — no quotes needed when passing args directly. ## Bug 2: Wrong output duration (1:43 instead of 32s) **Symptom**: Exported clip was 103 seconds instead of 32 seconds. **Root cause**: Both subtitle functions used `-to end_time` with output seeking (`-ss`/`-to` after `-i`). After `-ss` discards initial frames and the muxer resets PTS to 0, `-to 103` means "output 103 seconds" rather than "stop at input timestamp 103". **Fix**: Replaced `-to end_time` with `-t duration` (`clip.end_time - clip.start_time`) in both `build_ffmpeg_args_mux_subs` and `build_ffmpeg_args_burnin_subs`. `-t` is unambiguous. ## Bug 3: Muxed subtitles invisible in VLC **Symptom**: Subtitle track exists in the file but selecting it in VLC shows nothing. **Root cause**: With output seeking, video PTS was reset to 0 by the muxer, but subtitle cues retained their original absolute timestamps (e.g., 71s-103s). The player sees subtitle cues at 71s but the video is only 32s long. **Fix**: Two-part strategy change: 1. Added `trim_and_sanitize_vtt()` function that extracts cues within the clip's time range and shifts all timestamps to start from 0. 2. Switched `build_ffmpeg_args_mux_subs` to use **input seeking** (`-ss`/`-t` before `-i`) for speed. The pre-trimmed VTT timestamps already start from 0, matching the video output. 3. Burn-in mode (`build_ffmpeg_args_burnin_subs`) retains **output seeking** since the `subtitles` filter needs to see the original absolute timestamps from the VTT. ## Changes Made ### `src-tauri/src/services/clip_exporter.rs` - Removed single quotes from `subtitles=` filter value - Changed `-to end` to `-t duration` in both subtitle builder functions - Added `trim_and_sanitize_vtt()` with VTT timestamp parsing/shifting - Added helper functions: `parse_vtt_timestamp_line()`, `parse_vtt_ts()`, `format_vtt_timestamp()` - Switched `build_ffmpeg_args_mux_subs` to input seeking with pre-trimmed VTT - Updated `export_single_clip_with_subs` to use trimmed VTT for mux, sanitized VTT for burn-in - Updated all related tests (43 tests pass) ## Lessons Learned - `Command::args()` in Rust bypasses the shell entirely — shell-style quoting (single quotes) becomes literal characters in the argument. Never quote paths for ffmpeg filters when using `Command::args()`. - ffmpeg's `-to` is ambiguous with output seeking — it may refer to post-PTS-reset time rather than input time. `-t duration` is always safe. - When using input seeking on video (`-ss` before `-i`), subtitle PTS from a separate input must match the reset PTS (~0). Pre-trimming the VTT with shifted timestamps is the reliable approach. ## Follow-up None — all three user-reported bugs are addressed.