Fix iOS AudioSession OSStatus error -50

- Remove 'defaultToSpeaker' from audioCategoryOptions (conflicts with some iOS versions)
- Use 'videoChat' mode instead of 'voiceChat' for speaker output
- Reorder operations: set config first, start session, then configure output
- Keep audioCategoryOptions minimal to avoid param conflicts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Sergei 2026-01-22 09:36:20 -08:00
parent ac6d458aae
commit 42e3f389f7

View File

@ -51,29 +51,31 @@ export async function configureAudioForVoiceCall(): Promise<void> {
if (Platform.OS === 'ios') { if (Platform.OS === 'ios') {
// iOS-specific configuration // iOS-specific configuration
// IMPORTANT: Use 'videoChat' mode instead of 'voiceChat' to enable speaker by default
// voiceChat + defaultToSpeaker causes OSStatus error -50 on some iOS versions
console.log('[AudioSession] Step 1: Setting Apple audio config...'); console.log('[AudioSession] Step 1: Setting Apple audio config...');
await AudioSession.setAppleAudioConfiguration({ await AudioSession.setAppleAudioConfiguration({
audioCategory: 'playAndRecord', audioCategory: 'playAndRecord',
// Note: removed 'allowBluetoothA2DP' - it's incompatible with playAndRecord // Only use options that are safe with playAndRecord category
// on some iOS versions and causes "status -50" error. // Removed 'defaultToSpeaker' - it conflicts with some iOS versions
// 'allowBluetooth' (HFP profile) is sufficient for voice calls. // Instead, using 'videoChat' mode which defaults to speaker
audioCategoryOptions: [ audioCategoryOptions: [
'allowBluetooth', 'allowBluetooth',
'defaultToSpeaker',
'mixWithOthers', 'mixWithOthers',
], ],
audioMode: 'voiceChat', // Use 'videoChat' instead of 'voiceChat' - it enables speaker by default
audioMode: 'videoChat',
}); });
console.log('[AudioSession] Step 2: Setting default output...'); console.log('[AudioSession] Step 2: Starting audio session...');
await AudioSession.startAudioSession();
console.log('[AudioSession] Step 3: Setting default output to speaker...');
await AudioSession.configureAudio({ await AudioSession.configureAudio({
ios: { ios: {
defaultOutput: 'speaker', defaultOutput: 'speaker',
}, },
}); });
console.log('[AudioSession] Step 3: Starting audio session...');
await AudioSession.startAudioSession();
} else if (Platform.OS === 'android') { } else if (Platform.OS === 'android') {
// Android-specific configuration // Android-specific configuration
// IMPORTANT: Using 'music' stream type to force output to speaker // IMPORTANT: Using 'music' stream type to force output to speaker
@ -154,18 +156,15 @@ export async function reconfigureAudioForPlayback(): Promise<void> {
} }
if (Platform.OS === 'ios') { if (Platform.OS === 'ios') {
// Just reconfigure the same settings - this "refreshes" the audio routing // Reconfigure with same safe settings - this "refreshes" the audio routing
await AudioSession.setAppleAudioConfiguration({ await AudioSession.setAppleAudioConfiguration({
audioCategory: 'playAndRecord', audioCategory: 'playAndRecord',
// Note: removed 'allowBluetoothA2DP' - it's incompatible with playAndRecord
// on some iOS versions and causes "status -50" error.
// 'allowBluetooth' (HFP profile) is sufficient for voice calls.
audioCategoryOptions: [ audioCategoryOptions: [
'allowBluetooth', 'allowBluetooth',
'defaultToSpeaker',
'mixWithOthers', 'mixWithOthers',
], ],
audioMode: 'voiceChat', // Use 'videoChat' - defaults to speaker
audioMode: 'videoChat',
}); });
} else if (Platform.OS === 'android') { } else if (Platform.OS === 'android') {
// Reconfigure Android audio to ensure speaker output // Reconfigure Android audio to ensure speaker output
@ -209,22 +208,20 @@ export async function setAudioOutput(useSpeaker: boolean): Promise<void> {
} }
if (Platform.OS === 'ios') { if (Platform.OS === 'ios') {
// iOS: Configure audio output // iOS: Update configuration based on desired output
// Use 'videoChat' mode for speaker, 'voiceChat' for earpiece
await AudioSession.setAppleAudioConfiguration({
audioCategory: 'playAndRecord',
audioCategoryOptions: ['allowBluetooth', 'mixWithOthers'],
audioMode: useSpeaker ? 'videoChat' : 'voiceChat',
});
// Also set default output
await AudioSession.configureAudio({ await AudioSession.configureAudio({
ios: { ios: {
defaultOutput: useSpeaker ? 'speaker' : 'earpiece', defaultOutput: useSpeaker ? 'speaker' : 'earpiece',
}, },
}); });
// Also update the full configuration to ensure it takes effect
// Note: removed 'allowBluetoothA2DP' - causes "status -50" error
await AudioSession.setAppleAudioConfiguration({
audioCategory: 'playAndRecord',
audioCategoryOptions: useSpeaker
? ['allowBluetooth', 'defaultToSpeaker', 'mixWithOthers']
: ['allowBluetooth', 'mixWithOthers'],
audioMode: 'voiceChat',
});
} else if (Platform.OS === 'android') { } else if (Platform.OS === 'android') {
// Android: Switch stream type to control speaker/earpiece // Android: Switch stream type to control speaker/earpiece
// - 'music' stream goes to speaker by default // - 'music' stream goes to speaker by default