簡介
在 Azure 通訊服務 (ACS) 會議室通話期間,您可以使用通話 SDK 或通話自動化 SDK 或兩者來管理通話。 在會議室通話中,您可以使用指派給會議室中參與者和屬性的角色來控制通話內動作。 參與者角色會控制每位參與者允許的功能,而會議室屬性則適用於整個會議室通話。
通話 SDK
通話 SDK 是用戶端通話程式庫,可讓會議室通話中的參與者執行數個通話內作業,例如螢幕共用、開啟/關閉視訊、靜音/取消靜音等等。 如需功能的完整清單,請參閱 通話 SDK 概觀。
您可以根據指派給通話參與者的角色來控制功能。 例如,只有簡報者可以共享螢幕。 如需參與者角色和權限,請參閱 會議室概念。
通話自動化 SDK
通話自動化 SDK 是一個伺服器端程式庫,可讓系統管理員在中央和控制的環境中管理進行中的會議室通話。 不同於通話 SDK,通話自動化 SDK 作業與角色無關。 因此,通話系統管理員可以代表會議室通話參與者執行數個通話內作業。
下列清單描述會議室通話中可用的常見通話內動作。
連線至會議室通話
通話自動化必須先連線到現有的會議室通話,才能執行任何通話內作業。 使用回撥機制引發 CallConnected 或 ConnectFailed 事件,以指出連線作業是否分別成功或失敗。
Uri callbackUri = new Uri("https://<myendpoint>/Events"); //the callback endpoint where you want to receive subsequent events
CallLocator roomCallLocator = new RoomCallLocator("<RoomId>");
ConnectCallResult response = await client.ConnectAsync(roomCallLocator, callbackUri);
String callbackUri = "https://<myendpoint>/Events"; //the callback endpoint where you want to receive subsequent events
CallLocator roomCallLocator = new RoomCallLocator("<RoomId>");
ConnectCallResult response = client.connectCall(roomCallLocator, callbackUri).block();
const roomCallLocator = { kind: "roomCallLocator", id: "<RoomId>" };
const callbackUri = "https://<myendpoint>/Events"; // the callback endpoint where you want to receive subsequent events
const response = await client.connectCall(roomCallLocator, callbackUri);
callback_uri = "https://<myendpoint>/Events" # the callback endpoint where you want to receive subsequent events
room_call_locator = RoomCallLocator("<room_id>")
call_connection_properties = client.connect_call(call_locator=room_call_locator, callback_url=callback_uri)
成功連線到會議室通話後,會透過回撥 URI 通知 CallConnect 事件。 您可以使用 callConnectionId 視需要擷取會議室通話上的通話連線。 下列範例程式碼片段會使用 callConnectionId 來示範此函式。
新增 PSTN 參與者
您可以使用通話自動化撥出 PSTN 號碼,以將參與者新增至會議室通話。 不過,您必須設定會議室以啟用 PSTN 撥出選項(EnabledPSTNDialout 設定為 true),且 Azure 通訊服務資源必須佈建有效的電話號碼。
如需詳細資訊,請參閱會議室快速入門。
var callerIdNumber = new PhoneNumberIdentifier("+16044561234"); // This is the ACS-provisioned phone number for the caller
var callThisPerson = new CallInvite(new PhoneNumberIdentifier("+16041234567"), callerIdNumber); // The target phone number to dial out to
CreateCallResult response = await client.GetCallConnection(callConnectionId).AddParticipantAsync(callThisPerson);
PhoneNumberIdentifier callerIdNumber = new PhoneNumberIdentifier("+16044561234"); // This is the ACS-provisioned phone number for the caller
CallInvite callInvite = new CallInvite(new PhoneNumberIdentifier("+16041234567"), callerIdNumber); // The phone number participant to dial out to
AddParticipantOptions addParticipantOptions = new AddParticipantOptions(callInvite);
Response<AddParticipantResult> addParticipantResultResponse = client.getCallConnectionAsync(callConnectionId)
.addParticipantWithResponse(addParticipantOptions).block();
const callInvite = {
targetParticipant: { phoneNumber: "+18008008800" }, // The phone number participant to dial out to
sourceCallIdNumber: { phoneNumber: "+18888888888" } // This is the ACS-provisioned phone number for the caller
};
const response = await client.getCallConnection(callConnectionId).addParticipant(callInvite);
caller_id_number = PhoneNumberIdentifier(
"+18888888888"
) # TThis is the ACS-provisioned phone number for the caller
target = PhoneNumberIdentifier("+18008008800"), # The phone number participant to dial out to
call_connection_client = call_automation_client.get_call_connection(
"call_connection_id"
)
result = call_connection_client.add_participant(
target,
operation_context="Your context",
operationCallbackUrl="<url_endpoint>"
)
移除 PSTN 參與者
var removeThisUser = new PhoneNumberIdentifier("+16044561234");
// Remove a participant from the call with optional parameters
var removeParticipantOptions = new RemoveParticipantOptions(removeThisUser)
{
OperationContext = "operationContext",
OperationCallbackUri = new Uri("uri_endpoint"); // Sending event to a non-default endpoint
}
RemoveParticipantsResult result = await client.GetCallConnection(callConnectionId).RemoveParticipantAsync(removeParticipantOptions);
CommunicationIdentifier removeThisUser = new PhoneNumberIdentifier("+16044561234");
RemoveParticipantOptions removeParticipantOptions = new RemoveParticipantOptions(removeThisUser)
.setOperationContext("<operation_context>")
.setOperationCallbackUrl("<url_endpoint>");
Response<RemoveParticipantResult> removeParticipantResultResponse = client.getCallConnectionAsync(callConnectionId)
.removeParticipantWithResponse(removeParticipantOptions);
const removeThisUser = { phoneNumber: "+16044561234" };
const removeParticipantResult = await client.getCallConnection(callConnectionId).removeParticipant(removeThisUser);
remove_this_user = PhoneNumberIdentifier("+16044561234")
call_connection_client = call_automation_client.get_call_connection(
"call_connection_id"
)
result = call_connection_client.remove_participant(remove_this_user, operation_context="Your context", operationCallbackUrl="<url_endpoint>")
傳送 DTMF
將 DTMF 音調清單傳送給外部參與者。
var tones = new DtmfTone[] { DtmfTone.One, DtmfTone.Two, DtmfTone.Three, DtmfTone.Pound };
var sendDtmfTonesOptions = new SendDtmfTonesOptions(tones, new PhoneNumberIdentifier(calleePhonenumber))
{
OperationContext = "dtmfs-to-ivr"
};
var sendDtmfAsyncResult = await callAutomationClient.GetCallConnection(callConnectionId).GetCallMedia().SendDtmfTonesAsync(sendDtmfTonesOptions);
List<DtmfTone> tones = Arrays.asList(DtmfTone.ONE, DtmfTone.TWO, DtmfTone.THREE, DtmfTone.POUND);
SendDtmfTonesOptions options = new SendDtmfTonesOptions(tones, new PhoneNumberIdentifier(c2Target));
options.setOperationContext("dtmfs-to-ivr");
client.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.sendDtmfTonesWithResponse(options)
.block();
const tones = [DtmfTone.One, DtmfTone.Two, DtmfTone.Three];
const sendDtmfTonesOptions: SendDtmfTonesOptions = {
operationContext: "dtmfs-to-ivr"
};
const result: SendDtmfTonesResult = await client.getCallConnection(callConnectionId)
.getCallMedia()
.sendDtmfTones(tones, {
phoneNumber: c2Target
}, sendDtmfTonesOptions);
console.log("sendDtmfTones, result=%s", result);
tones = [DtmfTone.ONE, DtmfTone.TWO, DtmfTone.THREE]
call_connection_client = call_automation_client.get_call_connection(
"call_connection_id"
)
result = call_connection_client.send_dtmf_tones(
tones = tones,
target_participant = PhoneNumberIdentifier(c2_target),
operation_context = "dtmfs-to-ivr")
通話錄音
Azure 通訊服務會議室支援錄製功能,包括通話自動化所提供的 start、stop、pause、resume等等。 請參閱下列程式碼片段,以在會議室通話中啟動/停止/暫停/繼續錄製。 如需動作的完整清單,請參閱 通話自動化錄製。
// Start recording
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);
// Pause recording using recordingId received in response of start recording.
var pauseRecording = await callAutomationClient.GetCallRecording ().PauseAsync(recordingId);
// Resume recording using recordingId received in response of start recording.
var resumeRecording = await callAutomationClient.GetCallRecording().ResumeAsync(recordingId);
// Stop recording using recordingId received in response of start recording.
var stopRecording = await callAutomationClient.GetCallRecording().StopAsync(recordingId);
// Start recording
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);
// Pause recording using recordingId received in response of start recording
Response<Void> response = callAutomationClient.getCallRecording()
.pauseWithResponse(recordingId, null);
// Resume recording using recordingId received in response of start recording
Response<Void> response = callAutomationClient.getCallRecording()
.resumeWithResponse(recordingId, null);
// Stop recording using recordingId received in response of start recording
Response<Void> response = callAutomationClient.getCallRecording()
.stopWithResponse(recordingId, null);
// Start recording
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);
// Pause recording using recordingId received in response of start recording
var pauseRecording = await callAutomationClient.getCallRecording().pause(recordingId);
// Resume recording using recordingId received in response of start recording.
var resumeRecording = await callAutomationClient.getCallRecording().resume(recordingId);
// Stop recording using recordingId received in response of start recording
var stopRecording = await callAutomationClient.getCallRecording().stop(recordingId);
# Start recording
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>")
# Pause recording using recording_id received in response of start recording
pause_recording = call_automation_client.pause_recording(recording_id = recording_id)
# Resume recording using recording_id received in response of start recording
resume_recording = call_automation_client.resume_recording(recording_id = recording_id)
# Stop recording using recording_id received in response of start recording
stop_recording = call_automation_client.stop_recording(recording_id = recording_id)
終止通話
您可以使用通話自動化 SDK 掛斷動作來終止通話。 當掛斷動作完成時,SDK 會發佈 CallDisconnected 事件。
_ = await client.GetCallConnection(callConnectionId).HangUpAsync(forEveryone: true);
Response<Void> response = client.getCallConnectionAsync(callConnectionId).hangUpWithResponse(true).block();
await callConnection.hangUp(true);
call_connection_client = call_automation_client.get_call_connection(
"call_connection_id"
)
call_connection_client.hang_up(is_for_everyone=True)
其他動作
會議室通話中也支援下列通話內動作。
- 新增參與者 (ACS 識別碼)
- 移除參與者 (ACS 識別碼)
- 取消新增參與者 (ACS 識別碼和 PSTN 號碼)
- 掛斷通話
- 取得參與者 (ACS 識別碼和 PSTN 號碼)
- 取得多位參與者 (ACS 識別碼和 PSTN 號碼)
- 取得通話的最新資訊
- 播放音訊檔案和文字
- 播放所有音訊檔案和文字
- 同時辨識 DTMF 和語音
- 辨識連續 DTMF
如需詳細資訊,請參閱通話動作和媒體動作。
後續步驟
在本章節中,您已了解如何:
- 從應用程式加入會議室通話
- 使用通話 SDK 將通話內動作新增至會議室通話
- 使用通話自動化 SDK 將通話內動作新增至會議室通話
您可能也會想要: