TT-7228bc adjust iPhone playing#337
Merged
Merged
Conversation
added 2 commits
May 28, 2026 09:15
What changed in MediaRecord.tsx handleLoadAudio:532-555 now wraps the whole load sequence in a single try/catch: - If getGoodUrl() throws (waitForIt timeout — the main root cause), the catch calls blobError(ts.mediaError) which sets loading=false and shows the localized "Error loading audio" message. - Same for any throw from loadBlobAsync. - The thrown error is logged via logError/bugsnag so future failures aren't silent. - Hardcoded English error strings replaced with ts.mediaError. What this should fix on iOS for the tester - Symptom 3 (infinite loading on Record-step revisit) — addressed directly. - Symptom 1 (Play disabled after upload) — same root cause; should clear once load completes or fails. - Symptom 2 (Audio tab toggles silent) — not addressed by this fix. That's a separate iOS Safari Web Audio gesture issue in MediaPlayer/HiddenPlayer that needs its own ticket.
What changed - WSAudioPlayer.tsx:handlePlayStatus — added an idempotent early-return when play === playingRef.current (except when a region replay is intended). This lets the same handler be hit twice — once synchronously from the click, once via the state chain — without double-toggling. - HiddenPlayer.tsx — accepts and forwards a controlsRef to its inner WSAudioPlayer. - MediaPlayer.tsx:handlePlayPause — owns a wsControlsRef, passes it down to HiddenPlayer, and calls wsControlsRef.current?.togglePlay() synchronously inside the click handler before the React state updates run. Why this fixes Symptom 2 togglePlay → togglePlayStatus → handlePlayStatus → wsTogglePlay → setPlayingx → wavesurferRef.current.play() are all synchronous. Calling it inside the click keeps wavesurfer.play() inside the user-gesture context iOS Safari requires for AudioContext resume. The pre-existing state-driven chain (with its 100ms setTimeout in usePlayerLogic) still runs but now hits the idempotent guard and no-ops. Pause works the same way (Safari doesn't gate pause on user gesture, so the existing chain is fine, but the synchronous call simplifies it). Caveats - This only fixes the click-driven play in MediaPlayer (the path the bug report describes — the Audio tab). The prop-driven path (parent sets requestPlay=true programmatically) was never going to play on iOS Safari anyway, since Safari blocks autoplay without a gesture. - I left the 100ms setTimeout in usePlayerLogic alone — it predates this work and the comment hints at a race; removing it is a separate decision.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adjusts WaveSurfer-backed audio playback behavior, especially for iPhone/iOS playback gesture handling and media load failure reporting.
Changes:
- Adds idempotency handling in
WSAudioPlayerplay status updates. - Exposes hidden WaveSurfer controls through
HiddenPlayerintoMediaPlayer. - Updates
MediaRecordblob loading error handling and logging.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/renderer/src/components/WSAudioPlayer.tsx |
Avoids redundant play-status toggles unless replaying a selected region. |
src/renderer/src/components/MediaRecord.tsx |
Wraps URL/blob loading in a single try/catch and logs media load failures. |
src/renderer/src/components/MediaPlayer.tsx |
Calls hidden WaveSurfer controls directly during the play button click path. |
src/renderer/src/components/HiddenPlayer.tsx |
Threads an optional WaveSurfer controls ref through to WSAudioPlayer. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
sarahentzel
approved these changes
May 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes silent audio playback on iOS Safari by ensuring AudioContext.resume() happens synchronously within the user gesture. The core problem is that React state-driven playback introduces async hops (including a 100ms setTimeout) that lose the user gesture context, causing iOS Safari to silently block audio.
The fix:
Separately, error handling in MediaRecord is improved with proper logging and localized error messages.