-
-
Notifications
You must be signed in to change notification settings - Fork 60
Add audio output device/port selection for Android and iOS/macOS #191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: jfversluis <[email protected]>
Co-authored-by: jfversluis <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds the ability to select a preferred audio output device on Android, allowing users to route audio to specific outputs (e.g., phone speaker) even when other devices like Bluetooth are connected. This addresses the use case where alert sounds should play through the device speaker rather than connected Bluetooth car audio.
Key Changes:
- Added
AudioOutputDeviceenum with common Android audio device types (Speaker, Earpiece, Bluetooth, USB, etc.) - Implemented
SetPreferredOutputDevice()method inAudioPlayerthat uses Android's MediaPlayer API to route audio - Added documentation explaining the feature requirements and usage
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| AudioPlayerOptions.android.cs | Adds PreferredOutputDevice property to configure audio routing |
| AudioPlayer.android.cs | Implements device routing logic and integrates it into all constructors |
| AudioOutputDevice.android.cs | Defines enum mapping to Android's AudioDeviceType |
| audio-player.md | Documents the new feature with examples and device options |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot address comments |
Co-authored-by: jfversluis <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot please address comments |
Co-authored-by: jfversluis <[email protected]>
|
@copilot is there something like this for iOS as well? If not thats fine, if there is, can you implement it for that too? |
Co-authored-by: jfversluis <[email protected]>
Yes! iOS/macOS support has been implemented in commit f4c1475. iOS uses
Both platforms now support forcing audio to the device speaker even when Bluetooth is connected. The documentation includes cross-platform examples showing how to use both APIs together. |
|
@copilot build error D:\a\Plugin.Maui.Audio\Plugin.Maui.Audio\src\Plugin.Maui.Audio\AudioPlayer\AudioOutputPort.macios.cs(18,12): error CS0266: Cannot implicitly convert type 'ulong' to 'int'. An explicit conversion exists (are you missing a cast?) [D:\a\Plugin.Maui.Audio\Plugin.Maui.Audio\src\Plugin.Maui.Audio\Plugin.Maui.Audio.csproj::TargetFramework=net9.0-maccatalyst] |
Co-authored-by: jfversluis <[email protected]>
Fixed in commit 1de9db7. Changed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| player = new MediaPlayer(); | ||
|
|
||
| ConfigureAudioAttributes(audioPlayerOptions); | ||
|
|
Copilot
AI
Oct 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent whitespace: Line 189 contains trailing whitespace (tab character) that should be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit df9c0be. Removed trailing whitespace.
| #pragma warning disable CA1416 // We already check for API 28+ above | ||
| var targetDevice = devices.FirstOrDefault(d => d.Type == targetDeviceType); | ||
| #pragma warning restore CA1416 | ||
|
|
Copilot
AI
Oct 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pragma warning disable/restore is unnecessary here. The entire method already has an API 28+ check at line 239-242 with an early return, and the FirstOrDefault operation itself doesn't have API level restrictions. The warning suppression should be removed.
| #pragma warning disable CA1416 // We already check for API 28+ above | |
| var targetDevice = devices.FirstOrDefault(d => d.Type == targetDeviceType); | |
| #pragma warning restore CA1416 | |
| var targetDevice = devices.FirstOrDefault(d => d.Type == targetDeviceType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit df9c0be. Removed unnecessary pragma warning directives.
|
|
||
| var error = audioSession.OverrideOutputAudioPort(portOverride, out NSError? nsError); | ||
|
|
||
| if (!error || nsError != null) |
Copilot
AI
Oct 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error checking logic is incorrect. The OverrideOutputAudioPort method returns a bool indicating success (true) or failure (false), and sets nsError on failure. The condition should be if (!error) or if (nsError != null), not both with OR. Currently, when the operation succeeds (error=true, nsError=null), the warning is still logged.
| if (!error || nsError != null) | |
| if (!error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit df9c0be. Changed to if (!error) for correct boolean error checking.
|
@copilot address comments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…gma, fix error check Co-authored-by: jfversluis <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <[email protected]>
Feature: Add audio output device/port selection for Android and iOS/macOS ✅
This PR implements the ability to select audio output device/channel on Android and iOS/macOS, allowing users to route audio to specific outputs (e.g., phone speaker instead of Bluetooth).
✅ All Tasks Completed:
Implementation Summary
New Files:
AudioOutputDevice.android.cs- Enum with 10 device types for Android (Speaker, Earpiece, WiredHeadset, WiredHeadphones, BluetoothA2dp, BluetoothSco, UsbDevice, UsbAccessory, AuxLine, Default)AudioOutputPort.macios.cs- Enum with 2 port options for iOS/macOS (Speaker, Default) using ulong underlying typeModified Files:
AudioPlayerOptions.android.cs- Added PreferredOutputDevice propertyAudioPlayerOptions.macios.cs- Added PreferredOutputPort propertyAudioPlayer.android.cs- Added SetPreferredOutputDevice() and ConfigureAudioAttributes() methods, updated all constructors with consistent initialization orderAudioPlayer.macios.cs- Added SetPreferredOutputPort() method with correct error handling, integrated into PreparePlayer()audio-player.md- Added comprehensive documentation with Android, iOS/macOS, and cross-platform examplesTechnical Details:
Android:
iOS/macOS:
Common:
Usage Examples
Android:
iOS/macOS:
Cross-Platform:
Requirements:
Quality Assurance:
✅ Build: Successful (Android target verified)
✅ Code Review: Completed, all feedback addressed
✅ Security: No vulnerabilities (CodeQL)
✅ Documentation: Complete with Android, iOS, and cross-platform examples
✅ Code Quality: Eliminated duplication with shared method, clean code style
✅ Consistency: Standardized initialization order across constructors
✅ Backward Compatibility: Maintained
✅ Cross-Platform: Both Android and iOS/macOS implementations
✅ Type Safety: Fixed enum type compatibility for iOS/macOS
✅ Error Handling: Correct boolean logic for iOS error checking
Original prompt
💡 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.