Skip to content

Carry the glasses' microphone on the camera stream (iOS) - #50

Merged
gdelataillade merged 3 commits into
rodcone:mainfrom
diegolopezrm:ios-stream-audio
Oct 16, 2026
Merged

gdelataillade merged 3 commits into
rodcone:mainfrom
diegolopezrm:ios-stream-audio

Conversation

@diegolopezrm

@diegolopezrm diegolopezrm commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Adds an audio option to startStreamSession that carries the glasses' microphone on the camera stream (16 kHz mono PCM), exposed through audioFramesStream(), plus requestMicrophonePermission() and getMicrophonePermissionStatus(). I needed it for a voice assistant that's opened with "Hey Meta": iOS won't start recording from the background, and this audio never touches the phone's audio input. iOS only for now; Android's SDK has the same API, but I can't test it on hardware. Tests pass, the example builds, and I've been running the same change on Ray-Ban Meta Gen 3.

startStreamSession(audio: true) asks DAT for 16 kHz mono PCM on the camera
stream and delivers it through the new audioFramesStream() as Uint8List.
New requestMicrophonePermission() and getMicrophonePermissionStatus().

The audio never touches the phone's audio input, so it keeps arriving with
the app backgrounded, where iOS refuses to start an AVAudioSession
recording, and it leaves the glasses on A2DP instead of the 8 kHz
hands-free link. Buffers are copied inside the publisher callback and
delivered on the main thread; the audio listener is cancelled before the
camera stops, per Meta's audio-streaming guidance.

Android ignores the audio flag for now.
@gdelataillade

Copy link
Copy Markdown
Collaborator

@diegolopezrm thanks for the contribution! Will take a look very soon.

@gdelataillade

gdelataillade commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Two lifecycle details worth fixing:

  • MetaWearablesDatPlugin.swift:1068: awaiting audio-listener cancellation before stopping the camera lets an overlapping start return the existing texture ID, which teardown then unregisters; please guard starts against in-flight teardown while preserving cancellation-before-stop ordering, and add regression coverage.
  • AudioFrameStreamHandler.swift:56: queued delivery retains the old sink across cancellation/resubscription, so stale audio can reach a replacement listener; please add a subscription-generation check at delivery time, as in VideoFrameStreamHandler, with regression coverage.

Happy to take another look once these are addressed. Thanks again!

@gdelataillade

Copy link
Copy Markdown
Collaborator

Finally I addressed these issues myself so I could add this PR to the next release today!

@gdelataillade
gdelataillade merged commit bf3f905 into rodcone:main Oct 16, 2026
15 checks passed
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.

2 participants