Call recording quickstart
This article describes call recording for voice and video calls. To start using the Call Recording APIs, you must have a call in place. To build the end-user calling experience, make sure you're familiar with Calling client SDK and Call Automation.
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 serverCallId
to 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
:
When you establish a call, it returns a
serverCallId
as a property of theCallConnected
event after a call is established. Learn how to Get CallConnected event from Call Automation SDK.When you answer the call or a call is created, it returns the
serverCallId
as a property of theAnswerCallResult
orCreateCallResult
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. So you need to create a Call Automation client.
To create a call automation client, 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.
- Use
RecordingContent
to pass the recording content type. UseAUDIO
. - Use
RecordingChannel
to pass the recording channel type. UseMIXED
orUNMIXED
. - Use
RecordingFormat
to pass the format of the recording. UseWAV
.
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 using your designated Azure Blob Storage to store the recorded 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>"))
ExternalStorage = new BlobStorage(new Uri("<Insert Container / Blob Uri>"))
};
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 to StartAsync
.
var stopRecording = await callAutomationClient.GetCallRecording().StopAsync(recordingId);
4. Pause recording session using PauseAsync
API
Use the recordingId
received in response to StartAsync
.
var pauseRecording = await callAutomationClient.GetCallRecording ().PauseAsync(recordingId);
5. Resume recording session using ResumeAsync
API
Use the recordingId
received in response to 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 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 finishes processing (such as when meeting ends or a recording stops). Recording event notifications include contentLocation
and metadataLocation
, which you can use 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 to download the recorded media.
var recordingDownloadUri = new Uri(contentLocation);
var response = await callAutomationClient.GetCallRecording().DownloadToAsync(recordingDownloadUri, fileName);
Fetch the downloadLocation
for the recording from the contentLocation
attribute of the recordingChunk
. Use the DownloadToAsync
method to download the content into a provided filename.
7. Delete recording content using DeleteAsync
API
Use DeleteAsync
API to delete the recording content (such as recorded media and 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 exclusively use the serverCallId
to 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
:
Once a call is created, a
serverCallId
is returned as a property of theCallConnected
event after a call is established. Learn how to Get CallConnected event from Call Automation SDK.Once you answer the call or a call is created the
serverCallId
is returned as a property of theAnswerCallResult
orCreateCallResult
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. So you need to create a Call Automation client.
To create a call automation client, 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.
- Use
RecordingContent
to pass the recording content type. UseAUDIO
. - Use
RecordingChannel
to pass the recording channel type. UseMIXED
orUNMIXED
. - Use
RecordingFormat
to pass the format of the recording. UseWAV
.
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 using your designated Azure Blob Storage to store the recorded 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>"))
.setExternalStorage(new BlobStorage("<Insert Container / Blob Uri>"));
// //start recording
RecordingStateResult result = callRecording.start(recordingOptions);
2.2. Start recording session with Pause mode enabled using StartAsync
API
Note
Recordings must 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 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>"))
.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 to startWithResponse
.
Response<Void> response = callAutomationClient.getCallRecording()
.stopWithResponse(response.getValue().getRecordingId(), null);
4. Pause recording session using pauseWithResponse
API
Use the recordingId
received in response to startWithResponse
.
Response<Void> response = callAutomationClient.getCallRecording()
.pauseWithResponse(response.getValue().getRecordingId(), null);
5. Resume recording session using resumeWithResponse
API
Use the recordingId
received in response to 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 completes (such as meeting ends or recording stops). Recording event notifications include contentLocation
and metadataLocation
, which you can use to retrieve both recorded media and a recording metadata file.
The following code 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 to download 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 optionalParallelDownloadOptions
object to modify how the parallel download works.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 to delete the recorded media. 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 serverCallId
to 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
:- Once a call is created, a
serverCallId
is returned as a property of theCallConnected
event after a call is established. Learn how to Get CallConnected event from Call Automation SDK. - Once you answer the call or a call is created, it returns the
serverCallId
as a property of theAnswerCallResult
orCreateCallResult
API responses respectively.
- Once a call is created, a
Calling SDK scenarios
- When using Calling Client SDK, you can retrieve the
serverCallId
by using theserver_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, 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.
- Use
RecordingContent
to pass the recording content type. UseAUDIO
. - Use
RecordingChannel
to pass the recording channel type. UseMIXED
orUNMIXED
. - Use
RecordingFormat
to pass the format of the recording. UseWAV
.
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 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.
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 to 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 to 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 to 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 completes (such as the meeting ended or the recording stopped). Recording event notifications include contentLocation
and metadataLocation
, which are used to retrieve both recorded media and a recording metadata file.
The following code 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 to download 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
. Use the download_recording
method to download the content into bytes.
7. Delete recording content using 'delete_recording' API
Use delete_recording
API for deleting the recording content such as recorded media and 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 serverCallId
to 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
:- Once a call is created, a
serverCallId
is returned as a property of theCallConnected
event after a call is established. Learn how to Get a CallConnected event from the Call Automation SDK. - Once you answer the call or a call is created, it returns the
serverCallId
as a property of theAnswerCallResult
orCreateCallResult
API responses respectively.
- Once a call is created, a
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 a 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, 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.
- Use
RecordingContent
to pass the recording content type. UseAUDIO
. - Use
RecordingChannel
to pass the recording channel type. UseMIXED
orUNMIXED
. - Use
RecordingFormat
to pass the format of the recording. UseWAV
.
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 using your designated Azure Blob Storage to store the recorded 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 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.
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 to start
.
var stopRecording = await callAutomationClient.getCallRecording().stop(recordingId);
4. Pause recording session using 'pause' API
Use the recordingId
received in response to start
.
var pauseRecording = await callAutomationClient.getCallRecording().pause(recordingId);
5. Resume recording session using 'ResumeAsync' API
Use the recordingId
received in response to 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 completes (such as the meeting ended or the recording stopped). Recording event notifications include contentLocation
and metadataLocation
, which are used to retrieve both recorded media and a recording metadata file.
The following code 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 to download 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
. Use the DownloadToAsync
method to download the content into a 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:
- Download our Java, Python, and JavaScript call recording sample apps.
- Learn more about Call Recording.
- Learn more about Call Automation.