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>
3.6 KiB
Fix: Video Playback, Waveform, and Thumbnails Not Working
Date: 2026-09-21 12:21
Task: Diagnose and fix three user-reported issues after downloading a video: no playback, waveform/thumbnails stuck at "Generating...", scrubbing doesn't update the player frame.
Root Causes
1. [Merger] line path not parsed (Primary Bug)
When yt-dlp downloads video+audio separately and merges them, it outputs:
[download] Destination: /path/to/file.f399.mp4 ← intermediate
[download] Destination: /path/to/file.f251.webm ← intermediate
[Merger] Merging formats into "/path/to/file.webm" ← final merged file
The old parsing used line.split(": ").nth(1) for all three cases. This works for [download] Destination: lines (which have : delimiter) but fails for [Merger] lines (which use into "path" format — no : ). As a result, last_file_path pointed to a deleted intermediate file. Both triggerPostDownloadProcessing(path) and session.localFilePath received the wrong path, causing:
- All ffmpeg post-processing (waveform, thumbnails, keyframes) to fail with file-not-found
- The video player to reference a non-existent file
2. Stream URL doesn't work in Tauri webview
The yt-dlp -g stream URL (googlevideo.com) has anti-hotlinking protections (referer/IP checks) that block playback in a Tauri/WKWebView context. The <video> element was present but silently failed to load the source.
3. "Already downloaded" case not handled
When yt-dlp finds an existing file, it outputs [download] /path/file.webm has already been downloaded — a format that matches neither Destination: nor Merger patterns. So re-loading the same URL would result in localFilePath = "".
Changes Made
src-tauri/src/commands/video.rs
- Fixed
[Merger]parsing: Replaced the brokensplit(": ")approach withtrim_start_matches("[Merger] Merging formats into ").trim().trim_matches('"'). - Added "already downloaded" parsing: New branch for
has already been downloadedusingstrip_prefix/strip_suffixto extract the path.
src/lib/components/VideoPlayer.svelte
- Switched to local file for playback: Uses
convertFileSrc(session.localFilePath)via Tauri's asset protocol once download is complete, instead of the unreliable stream URL. - Added download progress UI: Shows a progress bar with percentage while downloading, instead of a broken black video area.
- Added video error handling:
onerror/onloadeddatahandlers with an overlay error message. - Import: Added
convertFileSrcfrom@tauri-apps/api/core.
Lessons Learned
yt-dlpstderr output formats are inconsistent.[download] Destination:uses:delimiter,[Merger]usesinto "path", and "already downloaded" embeds the path mid-sentence. Each needs its own parser.- googlevideo.com stream URLs don't work in embedded webviews due to anti-hotlinking. The design's "hybrid streaming preview" approach needs a local proxy or must fall back to showing download progress until the file is available locally.
- Always test with cached files. The "already downloaded" edge case only surfaces on the second load of the same URL.
Follow-up Items
- Add progress indicators for post-download processing (waveform/thumbnail/keyframe extraction can take minutes on long videos)
- Consider pre-download preview via local proxy or lower-quality quick download
- The waveform extraction uses
aresample=8000(sample rate) which produces ~26M samples for a 54-min video — consider optimizing to reduce to target count directly - Add error surfacing for failed post-download processing (currently silent
console.error)