55 lines
3.2 KiB
Markdown
55 lines
3.2 KiB
Markdown
|
|
# Fix: Video Codec Compatibility + Timeline Pan/Scroll + Minimap
|
||
|
|
|
||
|
|
**Date:** 2026-09-21 12:56
|
||
|
|
**Task:** Fix video playback (black screen despite play state), add timeline panning when zoomed, add minimap overview.
|
||
|
|
|
||
|
|
## Root Causes & Fixes
|
||
|
|
|
||
|
|
### 1. Video playback: WKWebView doesn't support VP9/WebM
|
||
|
|
The downloaded file was VP9+Opus in WebM container (yt-dlp format 399+251). Apple's WKWebView on macOS does NOT support VP9 codec. The `<video>` element accepted `.play()` but had no decodable frames.
|
||
|
|
|
||
|
|
**Fix:** Added `-f "bv*[vcodec^=avc1]+ba[acodec^=mp4a]/bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b"` to the yt-dlp download command in `download_manager.rs`. This selects H.264 (avc1) video + AAC (mp4a) audio, producing an MP4 file playable by WKWebView. Deleted the cached WebM file.
|
||
|
|
|
||
|
|
### 2. Timeline: no scroll/pan when zoomed
|
||
|
|
Mouse wheel only triggered zoom. No way to scroll horizontally when zoomed in.
|
||
|
|
|
||
|
|
**Fix in `Timeline.svelte`:**
|
||
|
|
- **Horizontal scroll → pan:** `deltaX` from trackpad/shift+wheel now calls `panBy()` to shift the visible window
|
||
|
|
- **Vertical scroll → zoom** (unchanged)
|
||
|
|
|
||
|
|
**New `panBy()` in `interactions.ts`:** Computes new `visibleStart`/`visibleEnd` from pixel delta, clamped to `[0, duration]`.
|
||
|
|
|
||
|
|
### 3. Minimap overview bar
|
||
|
|
Added a minimap canvas that appears when zoomed in:
|
||
|
|
- Shows the full waveform at a glance
|
||
|
|
- Highlights the current viewport with a blue border
|
||
|
|
- Dims regions outside the viewport
|
||
|
|
- Click to center viewport, drag to pan
|
||
|
|
- Playhead indicator
|
||
|
|
|
||
|
|
### 4. Other fixes applied this session (cumulative)
|
||
|
|
- **stdout/stderr swap:** yt-dlp sends status messages to stdout, not stderr
|
||
|
|
- **`[Merger]` path parsing:** Correctly captures final merged file path
|
||
|
|
- **"Already downloaded" parsing:** Handles `has already been downloaded` message
|
||
|
|
- **Cache check:** `checkCachedDownload(title)` checks temp dir before invoking yt-dlp
|
||
|
|
- **Parallel processing:** Waveform/thumbnails/keyframes results applied individually as they complete
|
||
|
|
- **Asset protocol scope:** Added `/private/var/**` and `/var/**` for macOS symlink paths
|
||
|
|
|
||
|
|
## Files Changed
|
||
|
|
- `src-tauri/src/services/download_manager.rs` — H.264 format selection
|
||
|
|
- `src/lib/components/Timeline.svelte` — Minimap + horizontal pan support
|
||
|
|
- `src/lib/timeline/interactions.ts` — Added `panBy()` function
|
||
|
|
- `src-tauri/src/commands/video.rs` — Cache check, diagnostic logging
|
||
|
|
- `src-tauri/src/commands/media_analysis.rs` — Diagnostic logging
|
||
|
|
- `src-tauri/src/lib.rs` — Registered `check_cached_download` command
|
||
|
|
- `src-tauri/tauri.conf.json` — Expanded asset protocol scope
|
||
|
|
- `src/lib/stores/videoSession.svelte.ts` — Cache check before download, parallel results
|
||
|
|
- `src/lib/bindings/video.ts` — `checkCachedDownload` binding
|
||
|
|
- `src/lib/components/VideoPlayer.svelte` — Local file playback with progress UI
|
||
|
|
|
||
|
|
## Lessons Learned
|
||
|
|
1. **WKWebView codec support is limited.** VP9/AV1/WebM don't work. Must use H.264+AAC in MP4.
|
||
|
|
2. **macOS `/var` is a symlink to `/private/var`.** Asset protocol scope must cover both paths.
|
||
|
|
3. **`Promise.allSettled` blocks all results until the slowest completes.** Use individual `.then()` chains when you want progressive rendering.
|
||
|
|
4. **yt-dlp sends status to stdout, warnings to stderr.** Not the other way around.
|