Call Recording Quickstart

This quickstart gets you started with Call Recording for voice and video calls. To start using the Call Recording APIs, you must have a call in place. Make sure you're familiar with Calling client SDK and/or Call Automation to build the end-user calling experience.

Sample Code

You can download the sample app from GitHub

Prerequisites

  • You need an Azure account with an active subscription.
  • Deploy a Communication Service resource. Record your resource connection string.
  • Subscribe to events via Azure Event Grid.
  • Download the .NET SDK

Before you start

Call Recording APIs use exclusively the serverCallIdto initiate recording. There are a couple of methods you can use to fetch the serverCallId depending on your scenario:

Call Automation scenarios

  • When using Call Automation, you have two options to get the serverCallId:
    1. Once a call is created, a serverCallId is returned as a property of the CallConnected event after a call has been established. Learn how to Get CallConnected event from Call Automation SDK.
    2. Once you answer the call or a call is created the serverCallId is returned as a property of the AnswerCallResult or CreateCallResult API responses respectively.

Calling SDK scenarios

  • When using Calling Client SDK, you can retrieve the serverCallId by using the getServerCallId method on the call. Use this example to learn how to Get serverCallId from the Calling Client SDK.

Let's get started with a few simple steps!

1. Create a Call Automation client

Call Recording APIs are part of the Azure Communication Services Call Automation libraries. Thus, it's necessary to create a Call Automation client. To create a call automation client, you use your Communication Services connection string and pass it to CallAutomationClient object.

CallAutomationClient callAutomationClient = new CallAutomationClient("<ACSConnectionString>");

2. Start recording session with StartRecordingOptions using 'StartAsync' API

Use the serverCallId received during initiation of the call.

  • RecordingContent is used to pass the recording content type. Use audio
  • RecordingChannel is used to pass the recording channel type. Use mixed or unmixed.
  • RecordingFormat is used to pass the format of the recording. Use wav.
StartRecordingOptions recordingOptions = new StartRecordingOptions(new ServerCallLocator("<ServerCallId>")) 
{
    RecordingContent = RecordingContent.Audio,
    RecordingChannel = RecordingChannel.Unmixed,
    RecordingFormat = RecordingFormat.Wav,
    RecordingStateCallbackUri = new Uri("<CallbackUri>");
};
Response<RecordingStateResult> response = await callAutomationClient.GetCallRecording()
.StartAsync(recordingOptions);

2.1. Start Recording - Bring Your Own Azure Blob Store

Start Recording with your own Azure Blob Storage defined to store the recording file once recording is complete.

StartRecordingOptions recordingOptions = new StartRecordingOptions(new ServerCallLocator("<ServerCallId>"))
{
   RecordingContent = RecordingContent.Audio,
   RecordingChannel = RecordingChannel.Unmixed,
   RecordingFormat = RecordingFormat.Wav,
   RecordingStateCallbackUri = new Uri("<CallbackUri>"),
   RecordingStorage = RecordingStorage.CreateAzureBlobContainerRecordingStorage(new Uri("<YOUR_STORAGE_CONTAINER_URL>"))
};
Response<RecordingStateResult> response = await callAutomationClient.GetCallRecording()
.StartAsync(recordingOptions);

2.2. Start recording session with Pause mode enabled using 'StartAsync' API

Note

Recordings will need to be resumed for recording file to be generated.

StartRecordingOptions recordingOptions = new StartRecordingOptions(new ServerCallLocator("<ServerCallId>")) 
{
    RecordingContent = RecordingContent.Audio,
    RecordingChannel = RecordingChannel.Unmixed,
    RecordingFormat = RecordingFormat.Wav,
    PauseOnStart = true,
    RecordingStateCallbackUri = new Uri("<CallbackUri>");
};
Response<RecordingStateResult> response = await callAutomationClient.GetCallRecording()
.StartAsync(recordingOptions);

2.3. Only for Unmixed - Specify a user on channel 0

To produce unmixed audio recording files, you can use the AudioChannelParticipantOrdering functionality to specify which user you want to record on channel 0. The rest of the participants are assigned to a channel as they speak. If you use RecordingChannel.Unmixed but don't use AudioChannelParticipantOrdering, Call Recording assigns channel 0 to the first participant speaking.

StartRecordingOptions recordingOptions = new StartRecordingOptions(new ServerCallLocator("<ServerCallId>")) 
{
    RecordingContent = RecordingContent.Audio,
    RecordingChannel = RecordingChannel.Unmixed,
    RecordingFormat = RecordingFormat.Wav,
    RecordingStateCallbackUri = new Uri("<CallbackUri>"),
    AudioChannelParticipantOrdering = { new CommunicationUserIdentifier("<ACS_USER_MRI>") }
    
};
Response<RecordingStateResult> response = await callAutomationClient.GetCallRecording().StartAsync(recordingOptions);

2.4. Only for Unmixed - Specify channel affinity

var channelAffinity = new ChannelAffinity(new CommunicationUserIdentifier("<ACS_USER_MRI>")) { Channel = 0};
StartRecordingOptions recordingOptions = new StartRecordingOptions(new ServerCallLocator("<ServerCallId>"))
{
   RecordingContent = RecordingContent.Audio,
   RecordingChannel = RecordingChannel.Unmixed,
   RecordingFormat = RecordingFormat.Wav,
   RecordingStateCallbackUri = new Uri("<CallbackUri>"),
   ChannelAffinity = new List<ChannelAffinity>{ channelAffinity }
};
Response<RecordingStateResult> response = await callAutomationClient.GetCallRecording().StartAsync(recordingOptions);

The StartAsync API response contains the recordingId of the recording session.

3. Stop recording session using 'StopAsync' API

Use the recordingId received in response of StartAsync.

var stopRecording = await callAutomationClient.GetCallRecording().StopAsync(recordingId);

4. Pause recording session using 'PauseAsync' API

Use the recordingId received in response of StartAsync.

var pauseRecording = await callAutomationClient.GetCallRecording ().PauseAsync(recordingId);

5. Resume recording session using 'ResumeAsync' API

Use the recordingId received in response of StartAsync.

var resumeRecording = await callAutomationClient.GetCallRecording().ResumeAsync(recordingId);

6. Download recording File using 'DownloadToAsync' API

Use an Azure Event Grid web hook or other triggered action should be used to notify your services when the recorded media is ready for download.

An Event Grid notification Microsoft.Communication.RecordingFileStatusUpdated is published when a recording is ready for retrieval, typically a few minutes after the recording process has completed (for example, meeting ended, recording stopped). Recording event notifications include contentLocation and metadataLocation, which are used to retrieve both recorded media and a recording metadata file.

Example of the event schema:

{
    "id": string, // Unique guid for event
    "topic": string, // /subscriptions/{subscription-id}/resourceGroups/{group-name}/providers/Microsoft.Communication/communicationServices/{communication-services-resource-name}
    "subject": string, // /recording/call/{call-id}/serverCallId/{serverCallId}
    "data": {
        "recordingStorageInfo": {
            "recordingChunks": [
                {
                    "documentId": string, // Document id for the recording chunk
                    "contentLocation": string, //Azure Communication Services URL where the content is located
                    "metadataLocation": string, // Azure Communication Services URL where the metadata for this chunk is located
                    "deleteLocation": string, // Azure Communication Services URL to use to delete all content, including recording and metadata.
                    "index": int, // Index providing ordering for this chunk in the entire recording
                    "endReason": string, // Reason for chunk ending: "SessionEnded", "ChunkMaximumSizeExceeded”, etc.
                }
            ]
        },
        "recordingStartTime": string, // ISO 8601 date time for the start of the recording
        "recordingDurationMs": int, // Duration of recording in milliseconds
        "sessionEndReason": string // Reason for call ending: "CallEnded", "InitiatorLeft”, etc.
    },
    "eventType": string, // "Microsoft.Communication.RecordingFileStatusUpdated"
    "dataVersion": string, // "1.0"
    "metadataVersion": string, // "1"
    "eventTime": string // ISO 8601 date time for when the event was created
}

Use DownloadToAsync API for downloading the recorded media.

var recordingDownloadUri = new Uri(contentLocation);
var response = await callAutomationClient.GetCallRecording().DownloadToAsync(recordingDownloadUri, fileName);

The downloadLocation for the recording can be fetched from the contentLocation attribute of the recordingChunk. DownloadToAsync method downloads the content into provided filename.

7. Delete recording content using 'DeleteAsync' API

Use DeleteAsync API for deleting the recording content (for example, recorded media, metadata)

var recordingDeleteUri = new Uri(deleteLocation);
var response = await callAutomationClient.GetCallRecording().DeleteAsync(recordingDeleteUri);

Sample Code

You can download the sample app from GitHub

Prerequisites

  • You need an Azure account with an active subscription.
  • Deploy a Communication Service resource. Record your resource connection string.
  • Subscribe to events via Azure Event Grid.
  • Download the Java SDK

Before you start

Call Recording APIs use exclusively the serverCallIdto initiate recording. There are a couple of methods you can use to fetch the serverCallId depending on your scenario:

Call Automation scenarios

  • When using Call Automation, you have two options to get the serverCallId:
    1. Once a call is created, a serverCallId is returned as a property of the CallConnected event after a call has been established. Learn how to Get CallConnected event from Call Automation SDK.
    2. Once you answer the call or a call is created the serverCallId is returned as a property of the AnswerCallResult or CreateCallResult API responses respectively.

Calling SDK scenarios

  • When using Calling Client SDK, you can retrieve the serverCallId by using the getServerCallId method on the call. Use this example to learn how to Get serverCallId from the Calling Client SDK.

Let's get started with a few simple steps!

1. Create a Call Automation client

Call Recording APIs are part of the Azure Communication Services Call Automation libraries. Thus, it's necessary to create a Call Automation client. To create a call automation client, you'll use your Communication Services connection string and pass it to CallAutomationClient object.

CallAutomationClient callAutomationClient = new CallAutomationClientBuilder()
            .connectionString("<acsConnectionString>")
            .buildClient();

2. Start recording session with StartRecordingOptions using 'startWithResponse' API

Use the serverCallId received during initiation of the call.

  • RecordingContent is used to pass the recording content type. Use AUDIO
  • RecordingChannel is used to pass the recording channel type. Use MIXED or UNMIXED.
  • RecordingFormat is used to pass the format of the recording. Use WAV.
StartRecordingOptions recordingOptions = new StartRecordingOptions(new ServerCallLocator("<serverCallId>"))
                    .setRecordingChannel(RecordingChannel.UNMIXED)
                    .setRecordingFormat(RecordingFormat.WAV)
                    .setRecordingContent(RecordingContent.AUDIO)
                    .setRecordingStateCallbackUrl("<recordingStateCallbackUrl>");

Response<RecordingStateResult> response = callAutomationClient.getCallRecording()
.startWithResponse(recordingOptions, null);

2.1. Start Recording - Bring Your Own Azure Blob Store

Start Recording session with your own Azure Blob Storage to store the recording file once recording is complete.

       StartRecordingOptions recordingOptions = new StartRecordingOptions(callLocator)
       .setRecordingChannel(RecordingChannel.MIXED)
       .setRecordingContent(RecordingContent.AUDIO_VIDEO)
       .setRecordingFormat(RecordingFormat.MP4)
       .setRecordingStorage(new AzureBlobContainerRecordingStorage("<YOUR_STORAGE_CONTAINER_URL>"));
 
       // //start recording
       RecordingStateResult result = callRecording.start(recordingOptions);

2.2. Start recording session with Pause mode enabled using 'StartAsync' API

Note

Recordings will need to be resumed for recording file to be generated.

StartRecordingOptions recordingOptions = new StartRecordingOptions(new ServerCallLocator("<serverCallId>"))
                    .setRecordingChannel(RecordingChannel.UNMIXED)
                    .setRecordingFormat(RecordingFormat.WAV)
                    .setRecordingContent(RecordingContent.AUDIO)
                    .setRecordingStateCallbackUrl("<recordingStateCallbackUrl>")
                    .setPauseOnStart(true)
                    .setAudioChannelParticipantOrdering(List.of(new CommunicationUserIdentifier("<participantMri>")));

Response<RecordingStateResult> response = callAutomationClient.getCallRecording()
.startWithResponse(recordingOptions, null);

2.3. Only for Unmixed - Specify a user on channel 0

To produce unmixed audio recording files, you can use the AudioChannelParticipantOrdering functionality to specify which user you want to record on channel 0. The rest of the participants will be assigned to a channel as they speak. If you use RecordingChannel.Unmixed but don't use AudioChannelParticipantOrdering, Call Recording will assign channel 0 to the first participant speaking.

StartRecordingOptions recordingOptions = new StartRecordingOptions(new ServerCallLocator("<serverCallId>"))
                    .setRecordingChannel(RecordingChannel.UNMIXED)
                    .setRecordingFormat(RecordingFormat.WAV)
                    .setRecordingContent(RecordingContent.AUDIO)
                    .setRecordingStateCallbackUrl("<recordingStateCallbackUrl>")
                    .setAudioChannelParticipantOrdering(List.of(new CommunicationUserIdentifier("<participantMri>")));

Response<RecordingStateResult> response = callAutomationClient.getCallRecording()
.startWithResponse(recordingOptions, null);

2.4. Only for Unmixed - Specify channel affinity

ChannelAffinity channelAffinity = new ChannelAffinity()
.setParticipant(new PhoneNumberIdentifier("RECORDING_ID"))
.setChannel(0);
List<ChannelAffinity> channelAffinities = Arrays.asList(channelAffinity);

StartRecordingOptions startRecordingOptions = new StartRecordingOptions(new ServerCallLocator(SERVER_CALL_ID))
   .setRecordingChannel(RecordingChannel.UNMIXED)
   .setRecordingFormat(RecordingFormat.WAV)
   .setRecordingContent(RecordingContent.AUDIO)
   .setRecordingStateCallbackUrl("<recordingStateCallbackUrl>")
   .setChannelAffinity(channelAffinities);
Response<RecordingStateResult> response = callAutomationClient.getCallRecording()
.startRecordingWithResponse(recordingOptions, null);

The startWithResponse API response contains the recordingId of the recording session.

3. Stop recording session using 'stopWithResponse' API

Use the recordingId received in response of startWithResponse.

Response<Void> response = callAutomationClient.getCallRecording()
               .stopWithResponse(response.getValue().getRecordingId(), null);

4. Pause recording session using 'pauseWithResponse' API

Use the recordingId received in response of startWithResponse.

Response<Void> response = callAutomationClient.getCallRecording()
              .pauseWithResponse(response.getValue().getRecordingId(), null);

5. Resume recording session using 'resumeWithResponse' API

Use the recordingId received in response of startWithResponse.

Response<Void> response = callAutomationClient.getCallRecording()
               .resumeWithResponse(response.getValue().getRecordingId(), null);

6. Download recording File using 'downloadToWithResponse' API

Use an Azure Event Grid web hook or other triggered action should be used to notify your services when the recorded media is ready for download.

An Event Grid notification Microsoft.Communication.RecordingFileStatusUpdated is published when a recording is ready for retrieval, typically a few minutes after the recording process has completed (for example, meeting ended, recording stopped). Recording event notifications include contentLocation and metadataLocation, which are used to retrieve both recorded media and a recording metadata file.

Below is an example of the event schema.

{
    "id": string, // Unique guid for event
    "topic": string, // /subscriptions/{subscription-id}/resourceGroups/{group-name}/providers/Microsoft.Communication/communicationServices/{communication-services-resource-name}
    "subject": string, // /recording/call/{call-id}/serverCallId/{serverCallId}
    "data": {
        "recordingStorageInfo": {
            "recordingChunks": [
                {
                    "documentId": string, // Document id for the recording chunk
                    "contentLocation": string, //Azure Communication Services URL where the content is located
                    "metadataLocation": string, // Azure Communication Services URL where the metadata for this chunk is located
                    "deleteLocation": string, // Azure Communication Services URL to use to delete all content, including recording and metadata.
                    "index": int, // Index providing ordering for this chunk in the entire recording
                    "endReason": string, // Reason for chunk ending: "SessionEnded", "ChunkMaximumSizeExceeded”, etc.
                }
            ]
        },
        "recordingStartTime": string, // ISO 8601 date time for the start of the recording
        "recordingDurationMs": int, // Duration of recording in milliseconds
        "sessionEndReason": string // Reason for call ending: "CallEnded", "InitiatorLeft”, etc.
    },
    "eventType": string, // "Microsoft.Communication.RecordingFileStatusUpdated"
    "dataVersion": string, // "1.0"
    "metadataVersion": string, // "1"
    "eventTime": string // ISO 8601 date time for when the event was created
}

Use downloadToWithResponse method of CallRecording class for downloading the recorded media. Following are the supported parameters for downloadToWithResponse method:

  • contentLocation: Azure Communication Services URL where the content is located.
  • destinationPath : File location.
  • parallelDownloadOptions: An optional ParallelDownloadOptions object to modify how the - parallel download will work.
  • overwrite: True to overwrite the file if it exists.
  • context: A Context representing the request context.
Boolean overwrite = true;
ParallelDownloadOptions parallelDownloadOptions = null;
Context context = null;

String filePath = String.format(".\\%s.%s", documentId, fileType);
Path destinationPath = Paths.get(filePath);

Response<Void> downloadResponse = callAutomationClient.getCallRecording().downloadToWithResponse(contentLocation, destinationPath, parallelDownloadOptions, overwrite, context);

The content location and document IDs for the recording files can be fetched from the contentLocation and documentId fields respectively, for each recordingChunk.

7. Delete recording content using ‘deleteWithResponse’ API.

Use deleteWithResponse method of CallRecording class for deleting the recorded media. Following are the supported parameters for deleteWithResponse method:

  • deleteLocation: Azure Communication Services URL where the content to delete is located.
  • context: A Context representing the request context.
Response<Void> deleteResponse = callAutomationClient.getCallRecording().deleteWithResponse(deleteLocation, context);

The delete location for the recording can be fetched from the deleteLocation field of the Event Grid event.

Sample Code

You can download the sample app from GitHub

Prerequisites

  • You need an Azure account with an active subscription.
  • Deploy a Communication Service resource. Record your resource connection string.
  • Subscribe to events via Azure Event Grid.
  • Python 3.7+.

Before you start

Call Recording APIs use exclusively the serverCallIdto initiate recording. There are a couple of methods you can use to fetch the serverCallId depending on your scenario:

Call Automation scenarios

  • When using Call Automation, you have two options to get the serverCallId:
    1. Once a call is created, a serverCallId is returned as a property of the CallConnected event after a call has been established. Learn how to Get CallConnected event from Call Automation SDK.
    2. Once you answer the call or a call is created the serverCallId is returned as a property of the AnswerCallResult or CreateCallResult API responses respectively.

Calling SDK scenarios

  • When using Calling Client SDK, you can retrieve the serverCallId by using the server_call_id variable on the call. Use this example to learn how to Get serverCallId from the Calling Client SDK.

Let's get started with a few simple steps!

1. Create a Call Automation client

Call Recording APIs are part of the Azure Communication Services Call Automation libraries. Thus, it's necessary to create a Call Automation client. To create a call automation client, you'll use your Communication Services connection string and pass it to CallAutomationClient object.

call_automation_client = CallAutomationClient.from_connection_string("<ACSConnectionString>")

2. Start recording session start_recording API

Use the serverCallId received during initiation of the call.

  • RecordingContent is used to pass the recording content type. Use audio
  • RecordingChannel is used to pass the recording channel type. Use mixed or unmixed.
  • RecordingFormat is used to pass the format of the recording. Use wav.
response = call_automation_client.start_recording(call_locator=ServerCallLocator(server_call_id),
            recording_content_type = RecordingContent.Audio,
            recording_channel_type = RecordingChannel.Unmixed,
            recording_format_type = RecordingFormat.Wav,
            recording_state_callback_url = "<CallbackUri>")

2.1. Start Recording - Bring Your Own Azure Blob Store

Start Recording with your own Azure Blob Storage defined to store the recording file once recording is complete.

response = call_automation_client.start_recording(call_locator=ServerCallLocator(server_call_id),
                   recording_content_type = RecordingContent.Audio,
                   recording_channel_type = RecordingChannel.Unmixed,
                   recording_format_type = RecordingFormat.Wav,
                   recording_state_callback_url = "<CallbackUri>",
                   recording_storage = AzureBlobContainerRecordingStorage(container_url="<YOUR_STORAGE_CONTAINER_URL>"))

2.2. Start recording session with Pause mode enabled using 'StartAsync' API

Note

Recordings will need to be resumed for recording file to be generated.

response = call_automation_client.start_recording(call_locator=ServerCallLocator(server_call_id),
            recording_content_type = RecordingContent.Audio,
            recording_channel_type = RecordingChannel.Unmixed,
            recording_format_type = RecordingFormat.Wav,
            pause_on_start = true,
            recording_state_callback_url = "<CallbackUri>")

2.3. Only for Unmixed - Specify a user on channel 0

To produce unmixed audio recording files, you can use the AudioChannelParticipantOrdering functionality to specify which user you want to record on channel 0. The rest of the participants will be assigned to a channel as they speak. If you use RecordingChannel.Unmixed but don't use AudioChannelParticipantOrdering, Call Recording will assign channel 0 to the first participant speaking.

response =  call_automation_client.start_recording(call_locator=ServerCallLocator(server_call_id),
            recording_content_type = RecordingContent.Audio,
            recording_channel_type = RecordingChannel.Unmixed,
            recording_format_type = RecordingFormat.Wav,
            recording_state_callback_url = "<CallbackUri>",
            audio_channel_participant_ordering=[CommunicationUserIdentifier(id="<ACS_USER_MRI>")])

2.4. Only for Unmixed - Specify channel affinity

_channel_affinity = ChannelAffinity(target_participant=CommunicationUserIdentifier("<ACS_USER_MRI>"), channel=0)

response =  call_automation_client.start_recording(call_locator=ServerCallLocator(server_call_id),
            recording_content_type = RecordingContent.Audio,
            recording_channel_type = RecordingChannel.Unmixed,
            recording_format_type = RecordingFormat.Wav,
            recording_state_callback_url = "<CallbackUri>",
            channel_affinity=[_channel_affinity])

The StartAsync API response contains the recordingId of the recording session.

3. Stop recording session using 'stop_recording' API

Use the recording_id received in response of start_recording.

stop_recording = call_automation_client.stop_recording(recording_id = recording_id)

4. Pause recording session using 'pause_recording' API

Use the recording_id received in response of start_recording.

pause_recording = call_automation_client.pause_recording(recording_id = recording_id)

5. Resume recording session using 'resume_recording' API

Use the recording_id received in response of start_recording.

resume_recording = call_automation_client.resume_recording(recording_id = recording_id)

6. Download recording File using 'download_recording' API

Use an Azure Event Grid web hook or other triggered action should be used to notify your services when the recorded media is ready for download.

An Event Grid notification Microsoft.Communication.RecordingFileStatusUpdated is published when a recording is ready for retrieval, typically a few minutes after the recording process has completed (for example, meeting ended, recording stopped). Recording event notifications include contentLocation and metadataLocation, which are used to retrieve both recorded media and a recording metadata file.

Below is an example of the event schema.

{
    "id": string, // Unique guid for event
    "topic": string, // /subscriptions/{subscription-id}/resourceGroups/{group-name}/providers/Microsoft.Communication/communicationServices/{communication-services-resource-name}
    "subject": string, // /recording/call/{call-id}/serverCallId/{serverCallId}
    "data": {
        "recordingStorageInfo": {
            "recordingChunks": [
                {
                    "documentId": string, // Document id for the recording chunk
                    "contentLocation": string, //Azure Communication Services URL where the content is located
                    "metadataLocation": string, // Azure Communication Services URL where the metadata for this chunk is located
                    "deleteLocation": string, // Azure Communication Services URL to use to delete all content, including recording and metadata.
                    "index": int, // Index providing ordering for this chunk in the entire recording
                    "endReason": string, // Reason for chunk ending: "SessionEnded", "ChunkMaximumSizeExceeded”, etc.
                }
            ]
        },
        "recordingStartTime": string, // ISO 8601 date time for the start of the recording
        "recordingDurationMs": int, // Duration of recording in milliseconds
        "sessionEndReason": string // Reason for call ending: "CallEnded", "InitiatorLeft”, etc.
    },
    "eventType": string, // "Microsoft.Communication.RecordingFileStatusUpdated"
    "dataVersion": string, // "1.0"
    "metadataVersion": string, // "1"
    "eventTime": string // ISO 8601 date time for when the event was created
}

Use download_recording API for downloading the recorded media.

response = recording_data = call_automation_client.download_recording(content_location)

with open("<file_name>", "wb") as binary_file:
    binary_file.write(recording_data.read())

The downloadLocation for the recording can be fetched from the contentLocation attribute of the recordingChunk. download_recording method download the content into bytes.

7. Delete recording content using 'delete_recording' API

Use delete_recording API for deleting the recording content (for example, recorded media, metadata)

response = call_automation_client.delete_recording(delete_location);

Sample Code

You can download the sample app from GitHub

Prerequisites

  • You need an Azure account with an active subscription.
  • Deploy a Communication Service resource. Record your resource connection string.
  • Subscribe to events via Azure Event Grid.
  • Node.js Active LTS and Maintenance LTS versions (8.11.1 and 10.14.1 recommended)

Before you start

Call Recording APIs use exclusively the serverCallIdto initiate recording. There are a couple of methods you can use to fetch the serverCallId depending on your scenario:

Call Automation scenarios

  • When using Call Automation, you have two options to get the serverCallId:
    1. Once a call is created, a serverCallId is returned as a property of the CallConnected event after a call has been established. Learn how to Get CallConnected event from Call Automation SDK.
    2. Once you answer the call or a call is created the serverCallId is returned as a property of the AnswerCallResult or CreateCallResult API responses respectively.

Calling SDK scenarios

  • When using Calling Client SDK, you can retrieve the serverCallId by using the getServerCallId method on the call. Use this example to learn how to Get serverCallId from the Calling Client SDK.

Let's get started with a few simple steps!

1. Create a Call Automation client

Call Recording APIs are part of the Azure Communication Services Call Automation libraries. Thus, it's necessary to create a Call Automation client. To create a call automation client, you'll use your Communication Services connection string and pass it to CallAutomationClient object.

const callAutomationClient = new CallAutomationClient.CallAutomationClient("<ACSConnectionString>");

2. Start recording session with StartRecordingOptions using 'StartAsync' API

Use the serverCallId received during initiation of the call.

  • RecordingContent is used to pass the recording content type. Use audio
  • RecordingChannel is used to pass the recording channel type. Use mixed or unmixed.
  • RecordingFormat is used to pass the format of the recording. Use wav.
var locator: CallLocator = { id: "<ServerCallId>", kind: "serverCallLocator" };

var options: StartRecordingOptions =
{
  callLocator: locator,
  recordingContent: "audio",
  recordingChannel:"unmixed",
  recordingFormat: "wav",
  recordingStateCallbackEndpointUrl: "<CallbackUri>"
};
var response = await callAutomationClient.getCallRecording().start(options);

2.1. Start Recording - Bring Your Own Azure Blob Store

Start Recording with your own Azure Blob Storage defined to store the recording file once recording is complete.

const recordingStorageKind: RecordingStorageKind = "azureBlobStorage"
const recordingStorage: RecordingStorage = { 
       recordingStorageKind: recordingStorageKind, 
       recordingDestinationContainerUrl: "<YOUR_STORAGE_CONTAINER_URL>"
   }
var options: StartRecordingOptions = {
       callLocator: callLocator,
       recordingContent: "audio",
       recordingChannel:"unmixed",
       recordingFormat: "wav",
       recordingStateCallbackEndpointUrl: "<CallbackUri>",
       recordingStorage: recordingStorage
   };
var response = await callAutomationClient.getCallRecording().start(options);

2.2. Start recording session with Pause mode enabled using 'StartAsync' API

Note

Recordings will need to be resumed for recording file to be generated.

var locator: CallLocator = { id: "<ServerCallId>", kind: "serverCallLocator" };

var options: StartRecordingOptions =
{
  callLocator: locator,
  recordingContent: "audio",
  recordingChannel:"unmixed",
  recordingFormat: "wav",
  pauseOnStart: true
  recordingStateCallbackEndpointUrl: "<CallbackUri>",
  audioChannelParticipantOrdering:[{communicationUserId: "<ACS_USER_MRI>"}]
};
var response = await callAutomationClient.getCallRecording().start(options);

2.3. Only for Unmixed - Specify a user on channel 0

To produce unmixed audio recording files, you can use the AudioChannelParticipantOrdering functionality to specify which user you want to record on channel 0. The rest of the participants will be assigned to a channel as they speak. If you use RecordingChannel.Unmixed but don't use AudioChannelParticipantOrdering, Call Recording will assign channel 0 to the first participant speaking.

var locator: CallLocator = { id: "<ServerCallId>", kind: "serverCallLocator" };

var options: StartRecordingOptions =
{
  callLocator: locator,
  recordingContent: "audio",
  recordingChannel:"unmixed",
  recordingFormat: "wav",
  recordingStateCallbackEndpointUrl: "<CallbackUri>",
  audioChannelParticipantOrdering:[{communicationUserId: "<ACS_USER_MRI>"}]
};
var response = await callAutomationClient.getCallRecording().start(options);

2.4. Only for Unmixed - Specify channel affinity

var options: StartRecordingOptions =
{
  callLocator: locator,
  recordingContent: "audio",
  recordingChannel:"unmixed",
  recordingFormat: "wav",
  recordingStateCallbackEndpointUrl: "<CallbackUri>",
  ChannelAffinity:
  [
    {
      channel:0,
      targetParticipant:{communicationUserId: "<ACS_USER_MRI>"}
    }
  ]
};
var response = await callAutomationClient.getCallRecording().start(options);

The StartAsync API response contains the recordingId of the recording session.

3. Stop recording session using 'stop' API

Use the recordingId received in response of start.

var stopRecording = await callAutomationClient.getCallRecording().stop(recordingId);

4. Pause recording session using 'pause' API

Use the recordingId received in response of start.

var pauseRecording = await callAutomationClient.getCallRecording().pause(recordingId);

5. Resume recording session using 'ResumeAsync' API

Use the recordingId received in response of start.

var resumeRecording = await callAutomationClient.getCallRecording().resume(recordingId);

6. Download recording File using 'DownloadToAsync' API

Use an Azure Event Grid web hook or other triggered action should be used to notify your services when the recorded media is ready for download.

An Event Grid notification Microsoft.Communication.RecordingFileStatusUpdated is published when a recording is ready for retrieval, typically a few minutes after the recording process has completed (for example, meeting ended, recording stopped). Recording event notifications include contentLocation and metadataLocation, which are used to retrieve both recorded media and a recording metadata file.

Below is an example of the event schema.

{
    "id": string, // Unique guid for event
    "topic": string, // /subscriptions/{subscription-id}/resourceGroups/{group-name}/providers/Microsoft.Communication/communicationServices/{communication-services-resource-name}
    "subject": string, // /recording/call/{call-id}/serverCallId/{serverCallId}
    "data": {
        "recordingStorageInfo": {
            "recordingChunks": [
                {
                    "documentId": string, // Document id for the recording chunk
                    "contentLocation": string, //Azure Communication Services URL where the content is located
                    "metadataLocation": string, // Azure Communication Services URL where the metadata for this chunk is located
                    "deleteLocation": string, // Azure Communication Services URL to use to delete all content, including recording and metadata.
                    "index": int, // Index providing ordering for this chunk in the entire recording
                    "endReason": string, // Reason for chunk ending: "SessionEnded", "ChunkMaximumSizeExceeded”, etc.
                }
            ]
        },
        "recordingStartTime": string, // ISO 8601 date time for the start of the recording
        "recordingDurationMs": int, // Duration of recording in milliseconds
        "sessionEndReason": string // Reason for call ending: "CallEnded", "InitiatorLeft”, etc.
    },
    "eventType": string, // "Microsoft.Communication.RecordingFileStatusUpdated"
    "dataVersion": string, // "1.0"
    "metadataVersion": string, // "1"
    "eventTime": string // ISO 8601 date time for when the event was created
}

Use downloadToPath API for downloading the recorded media.

var response = await callAutomationClient.getCallRecording().downloadToPath(contentLocation, fileName);

The downloadLocation for the recording can be fetched from the contentLocation attribute of the recordingChunk. DownloadToAsync method download the content into provided filename.

7. Delete recording content using 'DeleteAsync' API

Use delete API for deleting the recording content (for example, recorded media, metadata)

var response = await callAutomationClient.getCallRecording().delete(deleteLocation);

Clean up resources

If you want to clean up and remove a Communication Services subscription, you can delete the resource or resource group. Deleting the resource group also deletes any other resources associated with it. Learn more about cleaning up resources.

Next steps

For more information, see the following articles: