> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-agent-in-group-react-v6.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Audio Modes

> Configure CometChat Calls SDK v5 audio modes on React Native for speakers, earpiece, Bluetooth, routing, and call audio behavior.

The CometChat Calls SDK supports multiple audio output modes on mobile devices. Users can switch between speaker, earpiece, Bluetooth, and wired headphones.

## Available Audio Modes

| Mode       | Constant       | Description                        |
| ---------- | -------------- | ---------------------------------- |
| Speaker    | `'SPEAKER'`    | Phone speaker (loudspeaker)        |
| Earpiece   | `'EARPIECE'`   | Phone earpiece (for private calls) |
| Bluetooth  | `'BLUETOOTH'`  | Connected Bluetooth device         |
| Headphones | `'HEADPHONES'` | Wired headphones                   |

## Set Default Audio Mode

Configure the default audio mode when creating call settings:

```tsx theme={null}
import { CometChatCalls } from '@cometchat/calls-sdk-react-native';

const sessionSettings = {
  audioMode: 'SPEAKER',
};
```

## Show Audio Mode Button

Enable the audio mode button in the call UI:

```tsx theme={null}
const sessionSettings = {
  hideAudioModeButton: false,
};
```

## Listen for Audio Mode Changes

Subscribe to audio mode change events:

```tsx theme={null}
CometChatCalls.addEventListener('onAudioModeChanged', (mode) => {
  console.log('Audio mode changed to:', mode);
  // mode: 'SPEAKER' | 'EARPIECE' | 'BLUETOOTH' | 'HEADPHONES'
});
```

## Audio Mode Object

When receiving audio mode updates, each mode object contains:

| Property   | Type    | Description                                                  |
| ---------- | ------- | ------------------------------------------------------------ |
| `type`     | string  | Mode type (`SPEAKER`, `EARPIECE`, `BLUETOOTH`, `HEADPHONES`) |
| `selected` | boolean | Whether this mode is currently active                        |

## Complete Example

```tsx theme={null}
import React, { useState, useEffect } from 'react';
import { View, TouchableOpacity, Text, StyleSheet, Modal, FlatList } from 'react-native';
import { CometChatCalls } from '@cometchat/calls-sdk-react-native';

type AudioMode = 'SPEAKER' | 'EARPIECE' | 'BLUETOOTH' | 'HEADPHONES';

interface AudioModeOption {
  type: AudioMode;
  label: string;
  icon: string;
}

const audioModeOptions: AudioModeOption[] = [
  { type: 'SPEAKER', label: 'Speaker', icon: '🔊' },
  { type: 'EARPIECE', label: 'Earpiece', icon: '📱' },
  { type: 'BLUETOOTH', label: 'Bluetooth', icon: '🎧' },
  { type: 'HEADPHONES', label: 'Headphones', icon: '🎵' },
];

function AudioModeSelector() {
  const [currentMode, setCurrentMode] = useState<AudioMode>('SPEAKER');
  const [availableModes, setAvailableModes] = useState<AudioMode[]>(['SPEAKER', 'EARPIECE']);
  const [modalVisible, setModalVisible] = useState(false);

  useEffect(() => {
    const unsubscribe = CometChatCalls.addEventListener(
      'onAudioModeChanged',
      (mode: AudioMode) => {
        setCurrentMode(mode);
      }
    );

    return () => unsubscribe();
  }, []);

  const selectMode = (mode: AudioMode) => {
    // The SDK handles audio mode switching through the UI
    // This is for display purposes
    setCurrentMode(mode);
    setModalVisible(false);
  };

  const getCurrentModeOption = () => {
    return audioModeOptions.find((opt) => opt.type === currentMode) || audioModeOptions[0];
  };

  const renderModeOption = ({ item }: { item: AudioModeOption }) => {
    const isAvailable = availableModes.includes(item.type);
    const isSelected = currentMode === item.type;

    return (
      <TouchableOpacity
        style={[
          styles.modeOption,
          isSelected && styles.selectedOption,
          !isAvailable && styles.disabledOption,
        ]}
        onPress={() => isAvailable && selectMode(item.type)}
        disabled={!isAvailable}
      >
        <Text style={styles.modeIcon}>{item.icon}</Text>
        <Text
          style={[
            styles.modeLabel,
            isSelected && styles.selectedLabel,
            !isAvailable && styles.disabledLabel,
          ]}
        >
          {item.label}
        </Text>
        {isSelected && <Text style={styles.checkmark}>✓</Text>}
      </TouchableOpacity>
    );
  };

  return (
    <View>
      <TouchableOpacity
        style={styles.button}
        onPress={() => setModalVisible(true)}
      >
        <Text style={styles.buttonIcon}>{getCurrentModeOption().icon}</Text>
        <Text style={styles.buttonText}>{getCurrentModeOption().label}</Text>
      </TouchableOpacity>

      <Modal
        visible={modalVisible}
        transparent
        animationType="slide"
        onRequestClose={() => setModalVisible(false)}
      >
        <View style={styles.modalOverlay}>
          <View style={styles.modalContent}>
            <Text style={styles.modalTitle}>Audio Output</Text>
            <FlatList
              data={audioModeOptions}
              keyExtractor={(item) => item.type}
              renderItem={renderModeOption}
            />
            <TouchableOpacity
              style={styles.closeButton}
              onPress={() => setModalVisible(false)}
            >
              <Text style={styles.closeButtonText}>Close</Text>
            </TouchableOpacity>
          </View>
        </View>
      </Modal>
    </View>
  );
}

const styles = StyleSheet.create({
  button: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#333',
    paddingHorizontal: 16,
    paddingVertical: 12,
    borderRadius: 8,
    gap: 8,
  },
  buttonIcon: {
    fontSize: 18,
  },
  buttonText: {
    color: '#fff',
    fontSize: 14,
    fontWeight: '600',
  },
  modalOverlay: {
    flex: 1,
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
    justifyContent: 'flex-end',
  },
  modalContent: {
    backgroundColor: '#1a1a1a',
    borderTopLeftRadius: 20,
    borderTopRightRadius: 20,
    padding: 20,
  },
  modalTitle: {
    color: '#fff',
    fontSize: 18,
    fontWeight: '600',
    marginBottom: 16,
    textAlign: 'center',
  },
  modeOption: {
    flexDirection: 'row',
    alignItems: 'center',
    padding: 16,
    borderRadius: 8,
    marginBottom: 8,
    backgroundColor: '#333',
  },
  selectedOption: {
    backgroundColor: '#6851D6',
  },
  disabledOption: {
    opacity: 0.5,
  },
  modeIcon: {
    fontSize: 24,
    marginRight: 12,
  },
  modeLabel: {
    flex: 1,
    color: '#fff',
    fontSize: 16,
  },
  selectedLabel: {
    fontWeight: '600',
  },
  disabledLabel: {
    color: '#666',
  },
  checkmark: {
    color: '#fff',
    fontSize: 18,
  },
  closeButton: {
    marginTop: 16,
    padding: 16,
    alignItems: 'center',
  },
  closeButtonText: {
    color: '#6851D6',
    fontSize: 16,
    fontWeight: '600',
  },
});

export default AudioModeSelector;
```

## Platform Considerations

### iOS

* Audio mode switching is handled automatically by iOS based on connected devices
* Bluetooth devices appear when connected
* Headphones are detected when plugged in

### Android

* Requires `MODIFY_AUDIO_SETTINGS` permission
* Bluetooth requires `BLUETOOTH` and `BLUETOOTH_CONNECT` permissions
* Audio routing may vary by device manufacturer

## Related Documentation

* [Session Settings](/calls/react-native/session-settings) - Configure default audio mode
* [Events](/calls/react-native/events) - Audio mode events
* [Actions](/calls/react-native/actions) - Audio control methods
