[PR #222] Multi-mic selection with audio mixer integration #224

Open
opened 2026-03-02 04:00:48 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/eerimoq/moblin/pull/222
Author: @Copilot
Created: 2/8/2026
Status: 🔄 Open

Base: mainHead: copilot/add-audio-mixer-support


📝 Commits (5)

  • 71fbaa6 Initial plan
  • 3730652 Integrate AudioMixer into AudioUnit for multi-mic mixing support
  • ff5381e Address code review: remove force unwrap, simplify conditionals, improve test coverage
  • 5666926 Change mic selection UI to support selecting multiple mics
  • 07c3c58 Address review: use priority-ordered mic list when finding next mic after deselect

📊 Changes

8 files changed (+405 additions, -33 deletions)

View changed files

📝 Moblin/Media/HaishinKit/Media/Audio/AudioUnit.swift (+179 -22)
📝 Moblin/Media/HaishinKit/Media/Processor.swift (+16 -0)
📝 Moblin/Various/Media.swift (+16 -0)
📝 Moblin/Various/Model/ModelAudio.swift (+76 -0)
📝 Moblin/View/ControlBar/QuickButton/QuickButtonMicView.swift (+5 -9)
📝 Moblin/View/Settings/Audio/AudioSettingsView.swift (+11 -1)
📝 Moblin/View/Stream/Overlay/StreamOverlayLeftView.swift (+11 -1)
📝 MoblinTests/AudioMixerSuite.swift (+91 -0)

📄 Description

The app only supports one mic at a time. This adds an audio mixer that mixes one or more mics into a single output stream, and updates the UI to allow multi-mic selection.

Audio mixer integration (AudioUnit.swift)

  • Integrates the existing (unused) AudioMixer class into the audio pipeline
  • When >1 source is registered, lazily starts the mixer with a periodic timer rendering mixed output to the encoder
  • Converts between CMSampleBuffer and AVAudioPCMBuffer at the mixer boundary
  • Falls back to the existing direct single-source path when ≤1 source is active — zero behavior change for single-mic users
  • Exposes addMixerSource/removeMixerSource/addMixerBuiltinSource/removeMixerBuiltinSource through Processor and Media

Multi-mic selection model (ModelAudio.swift)

  • Mic class gains selectedMicIds: Set<String> and isSelected(mic:)
  • manualToggleMicById toggles mics in/out of the mixer via addMicToMixer/removeMicFromMixer helpers that dispatch to the correct mixer API per mic type (builtin, RTMP, SRTLA, RIST, media player)
  • Existing selectMic (auto-switch, scene override) resets to single-mic mode for backward compat

UI changes

  • QuickButtonMicView: Single-select checkmark → multi-select toggle (circle / checkmark.circle.fill), calls manualToggleMicById. Removed swipe-to-delete.
  • AudioSettingsView / StreamOverlayLeftView: Show comma-separated names of all selected mics
// Usage from app code
media.addMixerBuiltinSource()           // built-in mic
media.addMixerSource(sourceId: rtmpId)  // network camera mic
media.removeMixerSource(sourceId: rtmpId)

Tests (AudioMixerSuite.swift)

  • Added three-input mixing test and dynamic add/remove test

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/eerimoq/moblin/pull/222 **Author:** [@Copilot](https://github.com/apps/copilot-swe-agent) **Created:** 2/8/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `copilot/add-audio-mixer-support` --- ### 📝 Commits (5) - [`71fbaa6`](https://github.com/eerimoq/moblin/commit/71fbaa6b2e75c46edb05d1b6b1895bf4227797cb) Initial plan - [`3730652`](https://github.com/eerimoq/moblin/commit/3730652c029c8680070082854cb882d97b4957c2) Integrate AudioMixer into AudioUnit for multi-mic mixing support - [`ff5381e`](https://github.com/eerimoq/moblin/commit/ff5381e8f387d69739cf0c6a4bad4eafbe259030) Address code review: remove force unwrap, simplify conditionals, improve test coverage - [`5666926`](https://github.com/eerimoq/moblin/commit/5666926f2b8e6fcd2633e8ab7762c4618fec124f) Change mic selection UI to support selecting multiple mics - [`07c3c58`](https://github.com/eerimoq/moblin/commit/07c3c586df996bfc158991a80fb1f813c1df33a4) Address review: use priority-ordered mic list when finding next mic after deselect ### 📊 Changes **8 files changed** (+405 additions, -33 deletions) <details> <summary>View changed files</summary> 📝 `Moblin/Media/HaishinKit/Media/Audio/AudioUnit.swift` (+179 -22) 📝 `Moblin/Media/HaishinKit/Media/Processor.swift` (+16 -0) 📝 `Moblin/Various/Media.swift` (+16 -0) 📝 `Moblin/Various/Model/ModelAudio.swift` (+76 -0) 📝 `Moblin/View/ControlBar/QuickButton/QuickButtonMicView.swift` (+5 -9) 📝 `Moblin/View/Settings/Audio/AudioSettingsView.swift` (+11 -1) 📝 `Moblin/View/Stream/Overlay/StreamOverlayLeftView.swift` (+11 -1) 📝 `MoblinTests/AudioMixerSuite.swift` (+91 -0) </details> ### 📄 Description The app only supports one mic at a time. This adds an audio mixer that mixes one or more mics into a single output stream, and updates the UI to allow multi-mic selection. ### Audio mixer integration (`AudioUnit.swift`) - Integrates the existing (unused) `AudioMixer` class into the audio pipeline - When >1 source is registered, lazily starts the mixer with a periodic timer rendering mixed output to the encoder - Converts between `CMSampleBuffer` and `AVAudioPCMBuffer` at the mixer boundary - Falls back to the existing direct single-source path when ≤1 source is active — zero behavior change for single-mic users - Exposes `addMixerSource`/`removeMixerSource`/`addMixerBuiltinSource`/`removeMixerBuiltinSource` through `Processor` and `Media` ### Multi-mic selection model (`ModelAudio.swift`) - `Mic` class gains `selectedMicIds: Set<String>` and `isSelected(mic:)` - `manualToggleMicById` toggles mics in/out of the mixer via `addMicToMixer`/`removeMicFromMixer` helpers that dispatch to the correct mixer API per mic type (builtin, RTMP, SRTLA, RIST, media player) - Existing `selectMic` (auto-switch, scene override) resets to single-mic mode for backward compat ### UI changes - **`QuickButtonMicView`**: Single-select checkmark → multi-select toggle (`circle` / `checkmark.circle.fill`), calls `manualToggleMicById`. Removed swipe-to-delete. - **`AudioSettingsView`** / **`StreamOverlayLeftView`**: Show comma-separated names of all selected mics ```swift // Usage from app code media.addMixerBuiltinSource() // built-in mic media.addMixerSource(sourceId: rtmpId) // network camera mic media.removeMixerSource(sourceId: rtmpId) ``` ### Tests (`AudioMixerSuite.swift`) - Added three-input mixing test and dynamic add/remove test <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/moblin#224
No description provided.