rive-app / rive-app/rive-runtime
Audio output device held open while idle, hijacking multipoint Bluetooth headphones (macOS)
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.2k
- Forks
- 121
- PR merge metrics
- No merged PRs in 30d
Description
Rive Early Access (macOS desktop editor) keeps a CoreAudio output stream open while idle, with no playback happening in the editor. On macOS with multipoint Bluetooth headphones connected to both a Mac and a phone, this makes the headphones switch source to the Mac and pause audio on the phone.
Filing here because the editor has no public tracker and src/audio/audio_engine.cpp looks like the relevant code — happy to be redirected if the editor owns this.
Environment
- Rive Early Access, macOS desktop editor
- macOS Darwin 25.5.0, Apple Silicon
- JBL Tune Flex 2, multipoint, connected to Mac + phone simultaneously
Repro
- Connect multipoint BT headphones to a Mac and a phone at the same time.
- Play audio on the phone.
- Launch Rive Early Access, leave it idle in the background — no playback in the editor.
- Phone audio pauses; the headphones have switched source to the Mac.
- Quit Rive → phone audio works again.
Evidence
After ~24h of uptime with no editor playback, pmset -g assertions:
pid 187(coreaudiod): PreventUserIdleSystemSleep
named: "com.apple.audio.B4-84-D5-D7-AE-2C:output.context.preventuseridlesleep"
Created for PID: 33304 Resources: audio-out B4-84-D5-D7-AE-2C:output
B4:84:D5:D7:AE:2C is the headphones. PID 33304 is /Applications/Rive Early Access.app/Contents/MacOS/Rive Early Access, elapsed 23:45:06. Killing that PID released the audio device immediately and phone playback resumed.
Possible cause
In src/audio/audio_engine.cpp, m_runtimeAudioEngine is a process-lifetime static: AudioEngine::RuntimeEngine(true) creates it on first use and nothing tears it down or calls AudioEngine::stop() when no sounds are playing, so the underlying ma_engine device stays running for the life of the process. That matches the observed behaviour, though I have not confirmed the editor reaches the device through this path.
Expected
The output device is started when audio actually needs to play and stopped once playback ends, so an idle editor holds no audio device. ma_engine_stop() on idle (or uninit after a grace period) would be enough to stop hijacking multipoint headphones.
Side effect
The open stream also holds a PreventUserIdleSystemSleep power assertion, so an idle Rive blocks system sleep for as long as it runs.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/audio/audio_engine.cpp by tracing m_runtimeAudioEngine, AudioEngine::RuntimeEngine(true), and the available stop or teardown paths; confirm whether the editor reaches the device through this code. Reproduce with multipoint Bluetooth headphones on macOS and check pmset assertions. Done means idle Rive no longer holds the output device or prevents sleep, while playback still works.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, macos
- Domain
- audio-video-rtc
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 62/100