Files
gui-video-clipper/chat-summaries/2026-09-21_20-01-fix-hq-waveform-audio-summary.md
cottongin 8ad2f1c800 chore: stage all pending work — caption styling, media server, processing modal, docs, summaries
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>
2026-09-22 10:48:16 -04:00

3.1 KiB

Fix HQ Upgrade, Audio Playback, and Waveform

Date: 2026-09-21 20:01 Task: Fix three bugs reported after the previous batch of changes

Changes Made

1. Waveform Truncation Fix

File: src-tauri/src/services/waveform_generator.rs

Root cause: compute_peaks used peaks.resize(target_count, 0.0) to pad the peaks array to exactly target_count entries. But when chunk_size = ceil(samples / target_count) rounds up (e.g., 201439 samples / 200000 target = chunk_size 2), the actual number of chunks produced is far less than target_count (100720 vs 200000). The resize pads ~50% of the array with zeros, compressing the real waveform into the first half and leaving the rest flat.

Fix: Removed the peaks.resize(target_count, 0.0) call. The downstream rendering code already handles arrays of any length — the peak count from chunking is the correct count.

2. Export Format Fix (HQ Upgrade Black Screen)

File: src/lib/stores/videoSession.svelte.ts

Root cause: EXPORT_FORMAT = 'bv*+ba/b' allowed yt-dlp to pick the best format regardless of codec — which resulted in AV1+Opus in WebM. WKWebView on macOS cannot decode AV1 or Opus, so upgrading to the HQ preview produced a black screen with no playback.

Fix: Changed EXPORT_FORMAT to 'bv*[vcodec^=avc1]+ba[acodec^=mp4a]/b[ext=mp4]/best[ext=mp4]' to force H.264+AAC in MP4, matching what WKWebView can play. Deleted the cached .webm export file so the next run re-downloads in the correct format.

3. Volume Controls + Audio Diagnostics

File: src/lib/components/VideoPlayer.svelte

  • Added volume and isMuted state variables with reactive sync to the video element
  • Added mute toggle button (speaker emoji) and volume slider in a new bottom controls bar
  • Added diagnostic console.log in handleLoadedData to print muted, volume, readyState, audioTracks length, and dimensions — this will help trace the audio issue if it persists
  • Reorganized the bottom overlay: volume controls on the left, CC/settings on the right

Lessons Learned

  • When samples.chunks(chunk_size) is used with a chunk_size > 1, the number of resulting chunks is ceil(samples / chunk_size), which is strictly less than target_count when chunk_size = ceil(samples / target_count). Never pad with zeros — it corrupts the waveform mapping to time.
  • yt-dlp's bv*+ba/b format spec can pick any codec. On macOS, always constrain to H.264+AAC for WKWebView compatibility.
  • The audio issue may be related to mixed content (HTTPS frontend loading HTTP media) — the diagnostic logging added here will help isolate whether the issue is mute state, volume, or something lower-level in WebKit.

Verification

  • cargo build: OK (only pre-existing warnings)
  • cargo test: 37 tests pass
  • npm run check: OK (only pre-existing vite.config.ts errors)

Follow-up

  • Run npx tauri dev and verify waveform renders across the full timeline
  • Verify HQ upgrade no longer produces a black screen
  • Check console output from handleLoadedData diagnostic to trace audio issue
  • If audio still doesn't play, investigate mixed content blocking in WKWebView