Skip to main content

Documentation Index

Fetch the complete documentation index at: https://cometchat-22654f5b-v5-calling-sdk-enhancement-react-native.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

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

ModeConstantDescription
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:
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:
const sessionSettings = {
  hideAudioModeButton: false,
};

Listen for Audio Mode Changes

Subscribe to audio mode change events:
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:
PropertyTypeDescription
typestringMode type (SPEAKER, EARPIECE, BLUETOOTH, HEADPHONES)
selectedbooleanWhether this mode is currently active

Complete Example

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