你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

通话记录快速入门

本文介绍语音和视频通话的通话记录。 若要开始使用通话记录 API,必须正在进行通话。 若要构建最终用户通话体验,请务必熟悉通话客户端 SDK通话自动化

代码示例

可以从 GitHub 下载示例应用

先决条件

  • 需要一个具有活动订阅的 Azure 帐户。
  • 部署一个通信服务资源。 记录资源连接字符串。
  • 通过 Azure 事件网格订阅事件。
  • 下载 .NET SDK

开始之前

通话记录 API 专门使用 serverCallId 来启动记录。 根据你的方案,可以使用多种方法提取 serverCallId

通话自动化方案

使用通话自动化时,可以采用两种做法来获取 serverCallId

  1. 建立通话时,会在通话建立后返回 serverCallId 作为 CallConnected 事件的属性。 了解如何从通话自动化 SDK 获取 CallConnected 事件

  2. 在应答通话或创建通话后,会将 serverCallId 分别作为 AnswerCallResultCreateCallResult API 响应的属性返回。

通话 SDK 方案

使用通话客户端 SDK 时,可以通过对通话使用 getServerCallId 方法来检索 serverCallId。 使用此示例了解如何从通话客户端 SDK 获取 serverCallId

让我们从几个简单的步骤开始。

1. 创建通话自动化客户端

通话记录 API 是 Azure 通信服务通话自动化库的一部分。 需要创建通话自动化客户端。

若要创建通话自动化客户端,请使用通信服务连接字符串并将其传递给 CallAutomationClient 对象。

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

2. 使用“StartAsync”API 通过 StartRecordingOptions 启动记录会话

使用在发起通话期间收到的 serverCallId

  • 使用 RecordingContent 传递录制内容类型。 使用 AUDIO
  • 使用 RecordingChannel 传递录制频道类型。 使用 MIXEDUNMIXED
  • 使用 RecordingFormat 传递录制格式。 使用 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. 开始录制 - 自带 Azure Blob 存储

使用指定的 Azure Blob 存储开始录制,以存储录制完成后的录制文件。

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. 使用“StartAsync”API 启用暂停模式开始录制会话

注意

录制需要恢复才能生成录制文件。

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. 仅适用于未混合音频 - 在通道 0 上指定用户

若要生成未混合音频录制文件,可以使用 AudioChannelParticipantOrdering 功能来指定要在通道 0 上录制的用户。 其余参与者会在讲话时被分配到某个通道。 如果使用 RecordingChannel.Unmixed 而不使用 AudioChannelParticipantOrdering,则通话记录会将通道 0 分配给通话中的首个参与者。

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。 仅适用于未混合音频 - 指定通道相关性

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);

StartAsync API 响应包含记录会话的 recordingId

3.使用 StopAsync API 停止录制会话

使用在对 StartAsync 的响应中收到的 recordingId

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

4.使用 PauseAsync API 暂停录制会话

使用在对 StartAsync 的响应中收到的 recordingId

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

5.使用 ResumeAsync API 继续录制会话

使用在对 StartAsync 的响应中收到的 recordingId

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

6.使用 DownloadToAsync API 下载录制文件

当录制的媒体可供下载时,请使用 Azure 事件网格 Webhook 或其他触发的操作来通知服务。

通常在录制内容完成处理(例如在会议结束或录制停止时)后几分钟即可检索录制内容,此时会发布事件网格通知 Microsoft.Communication.RecordingFileStatusUpdated。 录制事件通知包括 contentLocationmetadataLocation,可用于检索录制的媒体和录制元数据文件。

事件架构的一个示例:

{
    "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
}

使用 DownloadToAsync API 下载录制的媒体。

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

recordingChunkcontentLocation 属性提取录制内容的 downloadLocation。 使用 DownloadToAsync 方法将内容下载到提供的文件名中。

7.使用 DeleteAsync API 删除录制内容

使用 DeleteAsync API 删除录制内容(例如录制的媒体和元数据)。

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

代码示例

可以从 GitHub 下载示例应用

先决条件

  • 需要一个具有活动订阅的 Azure 帐户。
  • 部署一个通信服务资源。 记录资源连接字符串。
  • 通过 Azure 事件网格订阅事件。
  • 下载 Java SDK

开始之前

通话记录 API 专门使用 serverCallId 来启动记录。 根据你的方案,可以使用多种方法提取 serverCallId

通话自动化方案

使用通话自动化时,可以采用两种做法来获取 serverCallId

  1. 创建通话后,会在建立通话后将 serverCallId 作为 CallConnected 事件的属性返回。 了解如何从通话自动化 SDK 获取 CallConnected 事件

  2. 在应答通话或创建通话后,serverCallId 将分别作为 AnswerCallResultCreateCallResult API 响应的属性返回。

通话 SDK 方案

使用通话客户端 SDK 时,可以通过对通话使用 getServerCallId 方法来检索 serverCallId

使用此示例了解如何从通话客户端 SDK 获取 serverCallId

让我们从几个简单的步骤开始。

1. 创建通话自动化客户端

通话记录 API 是 Azure 通信服务通话自动化库的一部分。 需要创建通话自动化客户端。

若要创建通话自动化客户端,请使用通信服务连接字符串并将其传递给 CallAutomationClient 对象。

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

2.使用 startWithResponse API 通过 StartRecordingOptions 启动录制会话

使用在发起通话期间收到的 serverCallId

  • 使用 RecordingContent 传递录制内容类型。 使用 AUDIO
  • 使用 RecordingChannel 传递录制频道类型。 使用 MIXEDUNMIXED
  • 使用 RecordingFormat 传递录制格式。 使用 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. 开始录制 - 自带 Azure Blob 存储

使用指定的 Azure Blob 存储开始录制,以存储录制完成后的录制文件。

        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. 使用 StartAsync API 在启用“暂停”模式的情况下启动录制会话

注意

录制必须恢复才能生成录制文件。

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. 仅适用于未混合音频 - 在通道 0 上指定用户

若要生成未混合音频录制文件,可以使用 AudioChannelParticipantOrdering 功能来指定要在通道 0 上录制的用户。 其余参与者会在讲话时被分配到某个通道。 如果使用 RecordingChannel.Unmixed 而不使用 AudioChannelParticipantOrdering,则通话记录会将通道 0 分配给通话中的首个参与者。

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。 仅适用于未混合音频 - 指定通道相关性

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);

startWithResponse API 响应包含记录会话的 recordingId

3.使用 stopWithResponse API 停止录制会话

使用在对 startWithResponse 的响应中收到的 recordingId

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

4.使用 pauseWithResponse API 暂停录制会话

使用在对 startWithResponse 的响应中收到的 recordingId

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

5.使用 resumeWithResponse API 继续录制会话

使用在对 startWithResponse 的响应中收到的 recordingId

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

6.使用 downloadToWithResponse API 下载录制文件

当记录的媒体可供下载时,请使用 Azure 事件网格 Webhook 或其他触发的操作来通知服务。

通常在记录过程完成(例如会议结束或录制停止)后几分钟即可检索记录,此时会发布事件网格通知 Microsoft.Communication.RecordingFileStatusUpdated。 录制事件通知包括 contentLocationmetadataLocation,可用于检索录制的媒体和录制元数据文件。

以下代码是事件架构的示例。

{
    "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
}

使用 CallRecording 类的 downloadToWithResponse 方法下载录制的媒体。 下面是 downloadToWithResponse 方法支持的参数:

  • contentLocation:Azure 通信服务内容的 URL。
  • destinationPath:文件位置。
  • parallelDownloadOptions:可选的 ParallelDownloadOptions 对象,用于修改并行下载的工作方式。
  • overwrite:如果为 True,则会覆盖文件(如果该文件存在)。
  • 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);

对于每个 recordingChunk,可以分别从 contentLocationdocumentId 字段提取记录文件的内容位置和文档 ID。

7.使用 deleteWithResponse API 删除录制内容

使用 CallRecording 类的 deleteWithResponse 方法删除录制的媒体。 deleteWithResponse 方法支持的参数:

  • deleteLocation:要删除的内容所在的 Azure 通信服务 URL。
  • context:表示请求上下文的上下文。
Response<Void> deleteResponse = callAutomationClient.getCallRecording().deleteWithResponse(deleteLocation, context);

可以从事件网格事件的 deleteLocation 字段中提取用于删除录制内容的位置。

代码示例

可以从 GitHub 下载示例应用

先决条件

  • 需要一个具有活动订阅的 Azure 帐户。
  • 部署一个通信服务资源。 记录资源连接字符串。
  • 通过 Azure 事件网格订阅事件。
  • Python 3.7+。

开始之前

通话记录 API 专门使用 serverCallId 来启动记录。 根据你的方案,可以使用多种方法提取 serverCallId

通话自动化方案

  • 使用通话自动化时,可以采用两种做法来获取 serverCallId
    1. 创建通话后,会在建立通话后将 serverCallId 作为 CallConnected 事件的属性返回。 了解如何从通话自动化 SDK 获取 CallConnected 事件
    2. 在应答通话或创建通话后,会将 serverCallId 分别作为 AnswerCallResultCreateCallResult API 响应的属性返回。

通话 SDK 方案

让我们从几个简单的步骤开始!

1. 创建通话自动化客户端

通话记录 API 是 Azure 通信服务通话自动化库的一部分。 因此,需要创建通话自动化客户端。

若要创建通话自动化客户端,请使用通信服务连接字符串并将其传递给 CallAutomationClient 对象。

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

2. 使用“start_recording”API 开始录制会话

使用在发起通话期间收到的 serverCallId

  • 使用 RecordingContent 传递录制内容类型。 使用 AUDIO
  • 使用 RecordingChannel 传递录制频道类型。 使用 MIXEDUNMIXED
  • 使用 RecordingFormat 传递录制格式。 使用 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. 开始录制 - 自带 Azure Blob 存储

使用自己的 Azure Blob 存储开始录制,该存储定义为在录制完成后存储录制文件。

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. 使用“StartAsync”API 启用暂停模式开始录制会话

注意

录制需要恢复才能生成录制文件。

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. 仅适用于未混合音频 - 在通道 0 上指定用户

若要生成未混合音频录制文件,可以使用 AudioChannelParticipantOrdering 功能来指定要在通道 0 上录制的用户。 其余参与者会在讲话时被分配到某个通道。 如果使用 RecordingChannel.Unmixed 而不使用 AudioChannelParticipantOrdering,则通话记录会将通道 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>",
            audio_channel_participant_ordering=[CommunicationUserIdentifier(id="<ACS_USER_MRI>")])

2.4。 仅适用于未混合音频 - 指定通道相关性

_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])

StartAsync API 响应包含记录会话的 recordingId

3. 使用“stop_recording”API 停止录制会话

使用在对 start_recording 的响应中收到的 recording_id

stop_recording = call_automation_client.stop_recording(recording_id = recording_id)

4. 使用“pause_recording”API 暂停录制会话

使用在对 start_recording 的响应中收到的 recording_id

pause_recording = call_automation_client.pause_recording(recording_id = recording_id)

5. 使用“resume_recording”API 恢复录制会话

使用在对 start_recording 的响应中收到的 recording_id

resume_recording = call_automation_client.resume_recording(recording_id = recording_id)

6. 使用“download_recording”API 下载录制文件

当记录的媒体可供下载时,请使用 Azure 事件网格 Webhook 或其他触发的操作来通知服务。

通常在记录过程完成(例如会议结束或录制停止)后几分钟即可检索记录,此时会发布事件网格通知 Microsoft.Communication.RecordingFileStatusUpdated。 录制事件通知包括 contentLocationmetadataLocation,用于检索录制的媒体和录制元数据文件。

以下代码是事件架构的示例。

{
    "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
}

使用 download_recording API 下载录制的媒体。

response = recording_data = call_automation_client.download_recording(content_location)

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

可以从 recordingChunkcontentLocation 属性提取录制内容的 downloadLocation。 使用 download_recording 方法将内容下载为字节。

7. 使用“delete_recording”API 删除录制内容

使用 delete_recording API 删除录制内容,例如录制的媒体和元数据。

response = call_automation_client.delete_recording(delete_location);

代码示例

可以从 GitHub 下载示例应用

先决条件

  • 需要一个具有活动订阅的 Azure 帐户。
  • 部署一个通信服务资源。 记录资源连接字符串。
  • 通过 Azure 事件网格订阅事件。
  • Node.js 活动 LTS 和维护 LTS 版本(建议使用 8.11.1 和 10.14.1)

开始之前

通话记录 API 专门使用 serverCallId 来启动记录。 根据你的方案,可以使用多种方法提取 serverCallId

通话自动化方案

  • 使用通话自动化时,可以采用两种做法来获取 serverCallId
    1. 创建通话后,会在建立通话后将 serverCallId 作为 CallConnected 事件的属性返回。 了解如何从通话自动化 SDK 获取 CallConnected 事件
    2. 在应答通话或创建通话后,会将 serverCallId 分别作为 AnswerCallResultCreateCallResult API 响应的属性返回。

通话 SDK 方案

使用通话客户端 SDK 时,可以通过对通话使用 getServerCallId 方法来检索 serverCallId

使用此示例了解如何从通话客户端 SDK 获取 serverCallId

让我们从几个简单的步骤开始!

1. 创建通话自动化客户端

通话记录 API 是 Azure 通信服务通话自动化库的一部分。 因此,需要创建通话自动化客户端。

若要创建通话自动化客户端,请使用通信服务连接字符串并将其传递给 CallAutomationClient 对象。

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

2. 使用“StartAsync”API 通过 StartRecordingOptions 启动记录会话

使用在发起通话期间收到的 serverCallId

  • 使用 RecordingContent 传递录制内容类型。 使用 AUDIO
  • 使用 RecordingChannel 传递录制频道类型。 使用 MIXEDUNMIXED
  • 使用 RecordingFormat 传递录制格式。 使用 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. 开始录制 - 自带 Azure Blob 存储

使用指定的 Azure Blob 存储开始录制,以存储录制完成后的录制文件。

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. 使用“StartAsync”API 启用暂停模式开始录制会话

注意

录制需要恢复才能生成录制文件。

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. 仅适用于未混合音频 - 在通道 0 上指定用户

若要生成未混合音频录制文件,可以使用 AudioChannelParticipantOrdering 功能来指定要在通道 0 上录制的用户。 其余参与者会在讲话时被分配到某个通道。 如果使用 RecordingChannel.Unmixed 而不使用 AudioChannelParticipantOrdering,则通话记录会将通道 0 分配给通话中的首个参与者。

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。 仅适用于未混合音频 - 指定通道相关性

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);

StartAsync API 响应包含记录会话的 recordingId

3. 使用“stop”API 停止录制会话

使用在对 start 的响应中收到的 recordingId

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

4. 使用“pause”API 暂停录制会话

使用在对 start 的响应中收到的 recordingId

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

5. 使用“ResumeAsync”API 恢复录制会话

使用在对 start 的响应中收到的 recordingId

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

6. 使用“DownloadToAsync”API 下载记录文件

当记录的媒体可供下载时,请使用 Azure 事件网格 Webhook 或其他触发的操作来通知服务。

通常在记录过程完成(例如会议结束或录制停止)后几分钟即可检索记录,此时会发布事件网格通知 Microsoft.Communication.RecordingFileStatusUpdated。 录制事件通知包括 contentLocationmetadataLocation,用于检索录制的媒体和录制元数据文件。

以下代码是事件架构的示例。

{
    "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
}

使用 downloadToPath API 下载录制的媒体。

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

可以从 recordingChunkcontentLocation 属性提取录制内容的 downloadLocation。 使用 DownloadToAsync 方法将内容下载到提供的文件名中。

7. 使用“DeleteAsync”API 删除录制内容

使用 delete API 来删除录制内容(例如录制的媒体、元数据)

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

清理资源

如果想要清理并删除通信服务订阅,可以删除资源或资源组。 删除资源组同时也会删除与之相关联的任何其他资源。 了解有关清理资源的详细信息。

后续步骤

有关详细信息,请参阅以下文章: