author | ms.service | ms.date | ms.topic | ms.custom |
---|---|---|---|---|
dbasantes |
azure-communication-services |
06/11/2023 |
include |
public_preview |
You can download the sample app from GitHub
- 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
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:
- 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 has been 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.
- Once a call is created, a
- When using Calling Client SDK, you can retrieve the
serverCallId
by using thegetServerCallId
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!
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();
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);
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);
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);
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);
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.
Use the recordingId
received in response of startWithResponse
.
Response<Void> response = callAutomationClient.getCallRecording()
.stopWithResponse(response.getValue().getRecordingId(), null);
Use the recordingId
received in response of startWithResponse
.
Response<Void> response = callAutomationClient.getCallRecording()
.pauseWithResponse(response.getValue().getRecordingId(), null);
Use the recordingId
received in response of startWithResponse
.
Response<Void> response = callAutomationClient.getCallRecording()
.resumeWithResponse(response.getValue().getRecordingId(), null);
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
.
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.