Skip to content

fix: 🐛 Finalize iOS recording before returning path; fix file:// URL parsing#498

Open
lavigarg-simform wants to merge 2 commits into
mainfrom
fix/I432_finalise_recording_before_return
Open

fix: 🐛 Finalize iOS recording before returning path; fix file:// URL parsing#498
lavigarg-simform wants to merge 2 commits into
mainfrom
fix/I432_finalise_recording_before_return

Conversation

@lavigarg-simform

@lavigarg-simform lavigarg-simform commented Jun 22, 2026

Copy link
Copy Markdown

Description

On iOS, stopRecording() could return the file path before AVAudioRecorder finished writing the file to disk. stop() finalizes the audio container asynchronously, so reading the file or releasing the recorder immediately produced a truncated/invalid container. The recorded file then failed to load in the player with kAudioFileInvalidFileError ("Failed to prepare player").

This PR makes the following changes:

1. AudioRecorder.swift (iOS) — defer the result until the file is finalized

  • Hold the pending FlutterResult(s) in a stopResults queue instead of returning immediately.
  • Implement the audioRecorderDidFinishRecording(_:successfully:) delegate callback, which fires once the recorder has flushed the file to disk. The result (duration + path) is returned from there via a new finalizeRecording(_:url:path:) helper.
  • Detach the recorder (audioRecorder = nil) before calling stop() so a subsequent startRecording can't redirect the URL/path that this stop is finalizing. The finishing recorder's own URL is used when finalizing.
  • A 2s watchdog (guarded by a stopGeneration counter) force-finalizes if the delegate never fires, so Dart's stop() can't hang forever. A stale timer / the loser of delegate-vs-watchdog becomes a no-op.
  • Re-entrant stop() calls now queue and all resolve with the same finalized result — a second stop() no longer returns an empty map / null path.
  • Guard against an Int(NaN) crash when the container duration is invalid/unfinished (only convert when finite).
  • If the recorder isn't actively recording when stopRecording is called, finalize synchronously (no callback to wait for).

2. AudioPlayer.swift (iOS + macOS) — harden file URL handling

  • URL(string:) mis-parses raw filesystem paths that have no scheme, and truncates file:// URLs at #/?. Now file:// paths have the scheme stripped (and a host segment dropped when present), are percent-decoded, and resolved via URL(fileURLWithPath:); all other paths go straight to URL(fileURLWithPath:). This prevents a nil URL / load failure for plain file paths and for filenames containing #/?.
  • The same fix is applied to the macOS player, which carried the identical URL(string:) bug introduced with macOS support.

Checklist

  • The title of my PR starts with a Conventional Commit prefix (fix:, feat:, docs: etc).
  • I have followed the Contributor Guide when preparing my PR.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation in docs and added dartdoc comments with ///.
  • I have updated/added relevant examples in examples or docs.

Breaking Change?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

Related Issues

Closes #432

@lavigarg-simform lavigarg-simform force-pushed the fix/I432_finalise_recording_before_return branch 2 times, most recently from 6d72878 to eaaf27c Compare June 23, 2026 09:06
lavigarg-simform and others added 2 commits June 23, 2026 14:58
macOS preparePlayer still used URL(string:), which mis-parses raw
filesystem paths and truncates file:// URLs at `#`/`?` — the same bug
already fixed for iOS in this branch. Strip the scheme and percent-decode
for URL(fileURLWithPath:) so plain and file:// paths both load.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lavigarg-simform lavigarg-simform force-pushed the fix/I432_finalise_recording_before_return branch from eaaf27c to d5d029a Compare June 23, 2026 09:33
@lavigarg-simform lavigarg-simform marked this pull request as ready for review June 23, 2026 10:00
@lavigarg-simform lavigarg-simform changed the title fix: 🐛 Ensure recording is finalized before returning file path on iOS fix: 🐛 Finalize iOS recording before returning path; fix file:// URL parsing Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

iOS - PlatformException when preparing player with recorded file

1 participant