# Hybrid Download Model + Auto-Defocus URL Input ## Task Description Two user-requested improvements: 1. **Hybrid download model**: Download a low-resolution (≤360p H.264+AAC) version for immediate preview/scrubbing/waveform/thumbnail generation, while downloading the best available quality in the background for export. Clips are cut from the best-quality file. 2. **Auto-defocus URL input**: After pasting a URL and triggering submit, blur the input field so keyboard shortcuts (I, O, etc.) don't accidentally modify the URL. ## Changes Made ### Session State Refactor (`src/lib/stores/videoSession.svelte.ts`) - Replaced single `localFilePath`/`downloadProgress`/`downloadStatus` with dual-track state: - `previewFilePath`/`previewProgress`/`previewStatus` — for the 360p preview - `exportFilePath`/`exportProgress`/`exportStatus` — for the best-quality export - Preview format: `bv*[vcodec^=avc1][height<=360]+ba[acodec^=mp4a]/b[ext=mp4][height<=360]/worst[ext=mp4]/worst` - Export format: `bv*+ba/b` (best available, any codec since ffmpeg handles export) - `beginDownload()` now: 1. Checks cache for preview → downloads if needed → triggers post-processing (waveform, thumbnails, keyframes) 2. Checks cache for export → downloads in background (fire-and-forget) - Files stored in separate subdirectories: `video-clipper/preview/` and `video-clipper/export/` ### Rust Backend (`src-tauri/src/commands/video.rs`) - `start_download` now accepts `format_spec` and `variant` parameters - `check_cached_download` now accepts a `variant` parameter to check the correct subdirectory - Helper `variant_dir()` builds `$TEMP/video-clipper/{variant}/` paths - Diagnostic logging includes variant name for easier debugging ### Download Manager (`src-tauri/src/services/download_manager.rs`) - `start_download` now accepts `format_spec: &str` parameter instead of hardcoding format selection - Format string passed through from the frontend call ### Frontend Bindings (`src/lib/bindings/video.ts`) - `startDownload` now takes `formatSpec` and `variant` parameters - `checkCachedDownload` now takes a `variant` parameter ### VideoPlayer (`src/lib/components/VideoPlayer.svelte`) - Uses `previewFilePath`/`previewStatus` instead of old single-track fields - Download progress shows "Downloading preview…" label ### ExportDialog (`src/lib/components/ExportDialog.svelte`) - Uses `exportFilePath`/`exportStatus`/`exportProgress` for export readiness - Shows "Downloading best quality (X%)…" while export download is in progress ### StatusBar (`src/lib/components/StatusBar.svelte`) - Shows dual progress: preview download → export download → ready to export - Contextual status messages for each download phase ### UrlInput (`src/lib/components/UrlInput.svelte`) - Added `bind:this={inputEl}` reference to input element - `blurInput()` called at the start of `handleSubmit()` — defocuses immediately on paste/enter - Keyboard shortcuts (I, O, etc.) now work immediately after submitting a URL ## Lessons Learned - Storing preview and export files in separate subdirectories (`preview/`, `export/`) keeps cache management clean and avoids filename collisions between quality variants. - Fire-and-forget pattern for background export download (`.catch()` at call site) keeps the preview flow responsive without blocking on the best-quality download. - The `variant` parameter threading from frontend → Rust command → download manager keeps the API clean and extensible for future quality tiers. ## Follow-Up Items - Consider showing export download progress in the timeline/player area as a subtle indicator - The export format `bv*+ba/b` may download VP9/WebM — this is fine for ffmpeg export but won't play in WKWebView. The preview file handles playback. - Old flat `video-clipper/` cache was cleared; users with existing caches in the old location won't get cache hits (harmless — just re-downloads)