11import notifee , { AndroidImportance } from '@notifee/react-native' ;
22import { getRecordingPermissionsAsync , requestRecordingPermissionsAsync } from 'expo-audio' ;
3+ import { Audio } from 'expo-av' ;
34import { Room , RoomEvent } from 'livekit-client' ;
45import { Platform } from 'react-native' ;
56import { create } from 'zustand' ;
@@ -12,44 +13,54 @@ import { headsetButtonService } from '../../services/headset-button.service';
1213import { toggleMicrophone } from '../../utils/microphone-toggle' ;
1314import { useBluetoothAudioStore } from './bluetooth-audio-store' ;
1415
16+ // Helper function to setup audio routing based on selected devices
1517// Helper function to setup audio routing based on selected devices
1618const setupAudioRouting = async ( room : Room ) : Promise < void > => {
1719 try {
1820 const bluetoothStore = useBluetoothAudioStore . getState ( ) ;
19- const { selectedAudioDevices, connectedDevice } = bluetoothStore ;
21+ const { selectedAudioDevices } = bluetoothStore ;
22+ const speaker = selectedAudioDevices . speaker ;
23+ const microphone = selectedAudioDevices . microphone ;
24+
25+ logger . info ( {
26+ message : 'Setting up audio routing' ,
27+ context : {
28+ speakerType : speaker ?. type ,
29+ speakerName : speaker ?. name ,
30+ micType : microphone ?. type ,
31+ } ,
32+ } ) ;
2033
21- // If we have a connected Bluetooth device, prioritize it
22- if ( connectedDevice && connectedDevice . hasAudioCapability ) {
23- logger . info ( {
24- message : 'Using Bluetooth device for audio routing' ,
25- context : { deviceName : connectedDevice . name } ,
26- } ) ;
34+ if ( Platform . OS === 'android' || Platform . OS === 'ios' ) {
35+ // Default configuration for voice call
36+ const audioModeConfig : any = {
37+ allowsRecordingIOS : true ,
38+ staysActiveInBackground : true ,
39+ playsInSilentModeIOS : true ,
40+ shouldDuckAndroid : true ,
41+ // Default to earpiece unless speaker is explicitly selected
42+ playThroughEarpieceAndroid : true ,
43+ } ;
2744
28- // Update selected devices to use Bluetooth
29- const deviceName = connectedDevice . name || 'Bluetooth Device' ;
30- const bluetoothMicrophone = connectedDevice . supportsMicrophoneControl ? { id : connectedDevice . id , name : deviceName , type : 'bluetooth' as const , isAvailable : true } : selectedAudioDevices . microphone ;
45+ // If speaker device is selected (explicitly 'speaker' type), force speaker output
46+ if ( speaker ?. type === 'speaker' ) {
47+ logger . debug ( { message : 'Routing audio to Speakerphone' } ) ;
48+ audioModeConfig . playThroughEarpieceAndroid = false ;
3149
32- const bluetoothSpeaker = {
33- id : connectedDevice . id ,
34- name : deviceName ,
35- type : 'bluetooth' as const ,
36- isAvailable : true ,
37- } ;
50+ // On iOS, we might need to handle this differently if we wanted to force speaker,
51+ // but typically standard routing handles it or AVRoutePickerView is used.
52+ // For Expo AV, we can sometimes influence it.
53+ } else {
54+ logger . debug ( { message : 'Routing audio to Earpiece/Headset' } ) ;
55+ audioModeConfig . playThroughEarpieceAndroid = true ;
56+ }
3857
39- bluetoothStore . setSelectedMicrophone ( bluetoothMicrophone ) ;
40- bluetoothStore . setSelectedSpeaker ( bluetoothSpeaker ) ;
58+ await Audio . setAudioModeAsync ( audioModeConfig ) ;
59+ }
4160
42- // Note: Actual audio routing would be implemented via native modules
43- // This is a placeholder for the audio routing logic
44- logger . debug ( {
45- message : 'Audio routing configured for Bluetooth device' ,
46- } ) ;
47- } else {
48- // Use default audio devices (selected devices or default)
49- logger . debug ( {
50- message : 'Using default audio devices' ,
51- context : { selectedAudioDevices } ,
52- } ) ;
61+ // Handle LiveKit specific device switching if needed (mostly for web/desktop, but good to have)
62+ if ( speaker ?. id && speaker . id !== 'default-speaker' && speaker . type === 'bluetooth' ) {
63+ // logic for specific bluetooth device selection if feasible
5364 }
5465 } catch ( error ) {
5566 logger . error ( {
@@ -466,3 +477,13 @@ export const useLiveKitStore = create<LiveKitState>((set, get) => ({
466477 }
467478 } ,
468479} ) ) ;
480+
481+ // Subscribe to bluetooth store changes to trigger audio routing updates
482+ useBluetoothAudioStore . subscribe ( ( state , prevState ) => {
483+ if ( state . selectedAudioDevices !== prevState . selectedAudioDevices ) {
484+ const room = useLiveKitStore . getState ( ) . currentRoom ;
485+ if ( room ) {
486+ setupAudioRouting ( room ) ;
487+ }
488+ }
489+ } ) ;
0 commit comments