Skip to main content
The CometChat Calls SDK supports recording call sessions. Recordings can be started manually or automatically when the call begins.

Enable Recording Button

Show the recording button in the call UI:
import { CometChatCalls } from '@cometchat/calls-sdk-react-native';

const callSettings = new CometChatCalls.CallSettingsBuilder()
  .showRecordingButton(true)
  .build();

Auto-Start Recording

Start recording automatically when the call begins:
const callSettings = new CometChatCalls.CallSettingsBuilder()
  .showRecordingButton(true)
  .startRecordingOnCallStart(true)
  .build();

Start Recording Programmatically

Start recording during an active call:
CometChatCalls.startRecording();

Stop Recording

Stop an active recording:
CometChatCalls.stopRecording();

Recording Events

Listen for recording state changes:

Using OngoingCallListener

const callListener = new CometChatCalls.OngoingCallListener({
  onRecordingStarted: (data) => {
    console.log('Recording started:', data);
  },
  onRecordingStopped: (data) => {
    console.log('Recording stopped:', data);
  },
});

const callSettings = new CometChatCalls.CallSettingsBuilder()
  .setCallEventListener(callListener)
  .build();

Using addEventListener

const unsubscribeStart = CometChatCalls.addEventListener(
  'onRecordingStarted',
  () => {
    console.log('Recording started');
  }
);

const unsubscribeStop = CometChatCalls.addEventListener(
  'onRecordingStopped',
  () => {
    console.log('Recording stopped');
  }
);

// Cleanup
unsubscribeStart();
unsubscribeStop();

Participant Recording Events

Listen when other participants start or stop recording:
CometChatCalls.addEventListener('onParticipantStartedRecording', (participant) => {
  console.log(`${participant.name} started recording`);
});

CometChatCalls.addEventListener('onParticipantStoppedRecording', (participant) => {
  console.log(`${participant.name} stopped recording`);
});

Recording Button Click Event

Listen for when the recording button is clicked:
CometChatCalls.addEventListener('onRecordingToggleButtonClicked', () => {
  console.log('Recording button clicked');
});

Access Recordings

Recordings are available through the call logs after the call ends. Use the Chat SDK to retrieve recordings:
import { CometChat } from '@cometchat/chat-sdk-react-native';

async function getCallRecordings(sessionId: string) {
  const callLogRequest = new CometChat.CallLogRequestBuilder()
    .setLimit(1)
    .build();

  try {
    const callLogs = await callLogRequest.fetchNext();
    const callLog = callLogs.find((log) => log.sessionId === sessionId);
    
    if (callLog && callLog.recordings) {
      console.log('Recordings:', callLog.recordings);
      return callLog.recordings;
    }
    return [];
  } catch (error) {
    console.error('Error fetching recordings:', error);
    throw error;
  }
}

Recording Object

Each recording contains:
PropertyTypeDescription
ridstringRecording ID
recordingUrlstringURL to download the recording
startTimenumberRecording start timestamp
endTimenumberRecording end timestamp
durationnumberRecording duration in seconds

Complete Example

import React, { useState, useEffect } from 'react';
import { View, TouchableOpacity, Text, StyleSheet } from 'react-native';
import { CometChatCalls } from '@cometchat/calls-sdk-react-native';

function RecordingControls() {
  const [isRecording, setIsRecording] = useState(false);

  useEffect(() => {
    const unsubscribeStart = CometChatCalls.addEventListener(
      'onRecordingStarted',
      () => {
        setIsRecording(true);
      }
    );

    const unsubscribeStop = CometChatCalls.addEventListener(
      'onRecordingStopped',
      () => {
        setIsRecording(false);
      }
    );

    return () => {
      unsubscribeStart();
      unsubscribeStop();
    };
  }, []);

  const toggleRecording = () => {
    if (isRecording) {
      CometChatCalls.stopRecording();
    } else {
      CometChatCalls.startRecording();
    }
  };

  return (
    <TouchableOpacity
      style={[styles.button, isRecording && styles.recordingButton]}
      onPress={toggleRecording}
    >
      <View style={[styles.indicator, isRecording && styles.recordingIndicator]} />
      <Text style={styles.buttonText}>
        {isRecording ? 'Stop Recording' : 'Start Recording'}
      </Text>
    </TouchableOpacity>
  );
}

const styles = StyleSheet.create({
  button: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#333',
    paddingHorizontal: 16,
    paddingVertical: 12,
    borderRadius: 8,
    gap: 8,
  },
  recordingButton: {
    backgroundColor: '#ff4444',
  },
  indicator: {
    width: 12,
    height: 12,
    borderRadius: 6,
    backgroundColor: '#666',
  },
  recordingIndicator: {
    backgroundColor: '#fff',
  },
  buttonText: {
    color: '#fff',
    fontSize: 14,
    fontWeight: '600',
  },
});

export default RecordingControls;