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>
1.5 KiB
1.5 KiB
Fix Captions Missing Due to CORS
Task
Captions/subtitles were not appearing at all - the CC button and settings button were invisible because parsedCues was always empty.
Root Cause
The local media server (axum on http://127.0.0.1:<random_port>) had no CORS headers. The frontend WebView runs at a different origin (http://localhost:1420 in dev, tauri://localhost in prod). While <video> elements can load cross-origin media without CORS (they use "no-cors" mode), the fetch() call used to load the VTT caption file was blocked by the browser's same-origin policy.
The fetch() silently failed (caught by .catch()), setting parsedCues = [], which meant the {#if parsedCues.length > 0} conditional in VideoPlayer.svelte never rendered the CC controls.
Changes Made
src-tauri/Cargo.toml: Added"cors"feature totower-httpdependency.src-tauri/src/services/media_server.rs: AddedCorsLayer::permissive()to the axum router, enabling cross-originfetch()from the WebView.
Lessons Learned
<video src="...">does NOT require CORS for basic playback - the browser loads media in "no-cors" mode. Butfetch()to the same URL WILL be blocked without CORS headers. This discrepancy is why video/audio played fine but caption loading silently failed.- When a
fetch()fails silently in a.catch()handler, there's no visible error in the UI — only in the browser DevTools console. Adding CORS from the start would have prevented this class of issues.
Follow-up
None - this was a targeted 2-file fix.