发布

  • feat: SoundCloud support + instant waveform rendering from pre-computed peaks (#158)

    frostbyte_neo 发布于 2026-05-28 15:08:51 +00:00 | 254 次提交 在此版本后已推送到 main

    • feat: add SoundCloud support alongside YouTube

    • chore: sync uv.lock with fastapi !=0.136.3 exclusion

    • feat: pre-compute waveform peaks server-side for instant rendering

    Pipeline now writes peaks.json after stem separation. Frontend fetches
    it on track load and renders overview + footer waveforms immediately,
    before audio is ready to play — eliminating the multi-second WAV decode
    wait. Falls back to client-side decode for old jobs without peaks.json.

    • compute_stem_peaks() in collect.py: soundfile + numpy, 1500 [min,max]
      pairs per stem, atomic write via temp+rename
    • GET /api/jobs/{id}/stems/peaks.json with immutable cache header
    • wireUpAudio async: 3s timeout peaks fetch, stale-token guard
    • 14 new tests (SoundCloud URL validation, peaks endpoint, unit tests)
    • fix: remove unused pytest import in test_pipeline_collect

    • feat: show catalog tracks as unavailable when job data is gone server-side

    When GET /api/jobs/{id} returns 404, mark the track status "unavailable",
    persist it, update the status dot to grey, and dim the track meta. On
    subsequent clicks, surface the error immediately without a server round-trip.

    Closes #157

    • fix: keep mixer visible during track import

    • fix: don't await peaks fetch before Multitrack.create — fixes choppy audio in WKWebView

    • fix: move New folder button below Stem Collections heading

    • fix: defer overview waveform render to canplay to prevent WKWebView audio choppiness

    Pre-computed peaks were rendering overview waveforms ~100ms after Multitrack.create
    via _peaksPromise.then(), blocking the main thread during WKWebView's audio startup
    window and causing buffer underruns. Moves all overview rendering to the canplay
    handler (matching v0.6.0-alpha.6 timing), with a _canplayFired flag to handle the
    edge case where canplay fires before peaks.json resolves.

    • fix: pre-fetch peaks.json in parallel with job data to avoid Safari connection limit

    In v0.6.0-alpha.6, initFooterWaveform fetched original.wav (same URL as a stem),
    so browsers could coalesce the duplicate request and stay within Safari's
    6-connection-per-origin limit. The peaks feature replaced that with a unique
    peaks.json URL, pushing concurrent connections to 7 and causing one stem WAV to
    queue — audio started before that stem was buffered, producing stutter on Safari.

    Fix: start the peaks.json fetch in catalog.js in parallel with the job-data fetch,
    before wireUpAudio is called. By the time Multitrack.create fires its WAV fetches,
    peaks.json is already resolved and its connection slot is free.

    Also adds _canplayFired guard to handle the edge case where canplay fires before
    peaks resolve, and accepts peaksPromise as a parameter in wireUpAudio so no second
    fetch is needed.

    下载附件