次の方法で共有


通話を管理する

この記事では、Azure Communication Services Calling SDK を使用して呼び出しを管理する方法について説明します。 トピックには、通話の発信方法、参加者の管理方法、プロパティの管理方法が含まれます。

前提条件

サポート

次の表では、Azure Communication Services でのブレークアウト ルームのサポートを定義します。

ID と通話の種類

次の表は、特定の通話の種類と ID について、機能のサポートを示しています。

アイデンティティ Teams 会議 部屋 1 対 1 の通話 グループ通話 1:1 Teams 相互運用機能通話 グループ チームの相互運用機能通話
Communication Services ユーザー ✔️ ✔️ ✔️ ✔️ ✔️ ✔️
Microsoft 365 ユーザー ✔️ ✔️ ✔️

操作

次の表は、個々の ID の種類に関連する Calling SDK の個々の API のサポートを示しています。

操作 Communication Services ユーザー Microsoft 365 ユーザー
Communication Services ユーザーへの通話を開始する ✔️
Microsoft 365 ユーザーへの通話を開始する ✔️ ✔️
電話番号への通話を開始する ✔️ ✔️
ルームに参加する ✔️
Teams 会議への参加 ✔️ ✔️
groupId に基づく通話に参加する ✔️
着信を受け入れまたは拒否する ✔️ ✔️
通話の保留と再開 ✔️ ✔️
参加者の取得 ✔️ ✔️
Communication Services ユーザーを追加する ✔️
Communication Services ユーザーを削除する ✔️ ✔️
Microsoft 365 ユーザーを追加または削除する ✔️ ✔️
電話番号を追加または削除する ✔️ ✔️
リモート参加者をミュートまたはミュート解除する ✔️ [1] ✔️ [1]
電話を切る ✔️ ✔️
全員の通話を終了する ✔️ [2] ✔️

[1] この API は、グループ通話、ルーム、Teams 会議でのみサポートされます。 [2] この API は、ルームではサポートされません。

SDK

次の表は、個々の Azure Communication Services SDK での機能のサポートを示しています。

サポートの状態 ウェブ ウェブユーザーインターフェース iOS iOS ユーザーインターフェース アンドロイド Androidのユーザーインターフェース ウィンドウズ
サポートの有無 ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️

SDK のインストール

npm install コマンドを使用して、JavaScript 用の Azure Communication Services の Common SDK と Calling SDK をインストールします。

npm install @azure/communication-common --save
npm install @azure/communication-calling --save

必要なオブジェクトを初期化する

CallClient インスタンスは、ほとんどの通話操作に必要です。 新しい CallClient インスタンスを作成する際に、Logger インスタンスなどのカスタム オプションを使用してこれを構成できます。

CallClient インスタンスでは、CallAgent を呼び出すことで createCallAgent インスタンスを作成できます。 このメソッドでは、非同期的に CallAgent インスタンス オブジェクトが返されます。

createCallAgent メソッドでは、CommunicationTokenCredential が引数として使用されます。 これは、ユーザー アクセス トークンを受け取ります。

getDeviceManager インスタンスで CallClient メソッドを使用して、deviceManager にアクセスできます。

const { CallClient } = require('@azure/communication-calling');
const { AzureCommunicationTokenCredential} = require('@azure/communication-common');
const { AzureLogger, setLogLevel } = require("@azure/logger");

// Set the logger's log level
setLogLevel('verbose');

// Redirect log output to console, file, buffer, REST API, or whatever ___location you want
AzureLogger.log = (...args) => {
    console.log(...args); // Redirect log output to console
};

const userToken = '<USER_TOKEN>';
callClient = new CallClient(options);
const tokenCredential = new AzureCommunicationTokenCredential(userToken);
const callAgent = await callClient.createCallAgent(tokenCredential, {displayName: 'optional Azure Communication Services user name'});
const deviceManager = await callClient.getDeviceManager()

Microsoft インフラストラクチャへの SDK 接続を管理する

Call Agent インスタンスは、(呼び出しを結合または開始するために) 呼び出しを管理するのに役立ちます。 呼び出しの SDK を機能させるには、Microsoft インフラストラクチャに接続して着信呼び出しの通知を取得し、他の呼び出しの詳細を調整する必要があります。 Call Agent には、次の 2 つの状態があります。

接続済み - Call AgentConnected connectionStatue 値は、クライアント SDK が接続されており、Microsoft インフラストラクチャから通知を受信できることを意味します。

切断済み - Call AgentDisconnected connectionStatue 値は、SDK の正常な接続を妨げる問題があることを示します。 Call Agent を再作成する必要があります。

  • invalidToken: トークンが有効期限切れであるか、無効な場合、Call Agent インスタンスがこのエラーで切断されます。
  • connectionIssue: クライアントが Microsoft インフラストラクチャに接続する際に問題が発生した場合、多数の再試行ののちに Call AgentconnectionIssue エラーが表示されます。

Call Agent プロパティの現在の値を調べて、ローカル connectionState が Microsoft インフラストラクチャに接続されているかどうかを確認できます。 アクティブな呼び出し中に、connectionStateChanged イベントをリッスンして、Call Agent の状態が接続済みから切断済みに変化したかどうかを判断できます。

const connectionState = callAgentInstance.connectionState;
console.log(connectionState); // it may return either of 'Connected' | 'Disconnected'

const connectionStateCallback = (args) => {
    console.log(args); // it will return an object with oldState and newState, each of having a value of either of 'Connected' | 'Disconnected'
    // it will also return reason, either of 'invalidToken' | 'connectionIssue'
}
callAgentInstance.on('connectionStateChanged', connectionStateCallback);

通話を行う

通話を作成して開始するには、callAgent で API のいずれかを使用し、Communication Services ID SDK を使用して作成したユーザーを指定する必要があります。

通話の作成と開始は同期的に行われます。 call インスタンスを使用すると、通話イベントをサブスクライブできます。

ユーザーまたは PSTN と 1:n の通話を行う

別の Communication Services ユーザーと通話を行うには、startCallcallAgent メソッドを呼び出し、CommunicationUserIdentifier、受信者の を渡します。

ユーザーへの 1 対 1 の呼び出しには、次のコードを使用します。

const userCallee = { communicationUserId: '<ACS_USER_ID>' }
const oneToOneCall = callAgent.startCall([userCallee]);

公衆交換電話網 (PSTN) の通話を行うには、startCallcallAgent メソッドを使用し、受信者の PhoneNumberIdentifier を渡します。 PSTN 通話を許可するように Communication Services リソースを構成する必要があります。

PSTN 番号に電話をかけるときは、代替の発信者 ID を指定します。 代替の発信者 ID は、PSTN 通話の呼び出し元を識別する (E.164 標準に基づく) 電話番号です。 これは、着信通話の場合に通話受信者に表示される電話番号です。

PSTN 通話プランの詳細を参照してください。 プレビュー プログラムにアクセスするには、早期導入者プログラムに申し込みます

相手が PSTN 番号の場合の 1 対 1 の通話には、次のコードを使用します。

const pstnCallee = { phoneNumber: '<ACS_USER_ID>' }
const alternateCallerId = {phoneNumber: '<ALTERNATE_CALLER_ID>'};
const oneToOneCall = callAgent.startCall([pstnCallee], { alternateCallerId });

相手がユーザー 1 名と PSTN 番号の場合の 1 対 n 名の通話には、次のコードを使用します。

const userCallee = { communicationUserId: '<ACS_USER_ID>' }
const pstnCallee = { phoneNumber: '<PHONE_NUMBER>'};
const alternateCallerId = {phoneNumber: '<ALTERNATE_CALLER_ID>'};
const groupCall = callAgent.startCall([userCallee, pstnCallee], { alternateCallerId });

ルーム通話に参加する

room 呼び出しに参加するには、roomId プロパティを room 識別子として使用してコンテキスト オブジェクトをインスタンス化できます。 通話に参加するには、join メソッドを使用し、コンテキスト インスタンスを渡します。

const context = { roomId: '<RoomId>' }
const call = callAgent.join(context);

room を使用すると、アプリケーション開発者は、誰が通話に参加できるか、いつ会うか、そしてどのように共同作業を行うかをより制御しやすくなります。 会議室の詳細については、「 構造化された会議の Rooms API 」および 「会議室呼び出しに参加する」を参照してください。

グループ通話に参加する

groupId パラメーターはシステム メタデータであり、システムの実行に必要な操作に Microsoft によって使用されます。 groupId 値には個人データを含めないでください。 Microsoft ではこのパラメーターを個人データとして扱わず、そのコンテンツが Microsoft の従業員に表示されたり、長期間保管されたりすることがあります。

groupId パラメーターのデータは GUID 形式でなければなりません。 ご利用のシステム内で個人データと見なされない、ランダムに生成された GUID を使用することをお勧めします。

新しいグループ通話を始めるか、進行中のグループ通話に参加するには、join メソッドを使用して、groupId プロパティを含むオブジェクトを渡します。 groupId 値は GUID である必要があります。

const context = { groupId: '<GUID>'};
const call = callAgent.join(context);

着信通話を受信する

ログインしている ID が着信通話を受信すると、callAgent インスタンスで incomingCall イベントが生成されます。 このイベントをリッスンするには、次のいずれかのオプションを使用してサブスクライブします。

const incomingCallHandler = async (args: { incomingCall: IncomingCall }) => {
    const incomingCall = args.incomingCall;

    // Get incoming call ID
    var incomingCallId = incomingCall.id

    // Get information about this Call. This API is provided as a preview for developers
    // and may change based on feedback that we receive. Do not use this API in a production environment.
    // To use this api please use 'beta' release of Azure Communication Services Calling Web SDK
    var callInfo = incomingCall.info;

    // Get information about caller
    var callerInfo = incomingCall.callerInfo

    // Accept the call
    var call = await incomingCall.accept();

    // Reject the call
    incomingCall.reject();

    // Subscribe to callEnded event and get the call end reason
     incomingCall.on('callEnded', args => {
        console.log(args.callEndReason);
    });

    // callEndReason is also a property of IncomingCall
    var callEndReason = incomingCall.callEndReason;
};
callAgentInstance.on('incomingCall', incomingCallHandler);

incomingCall イベントには、受け入れまたは拒否できる incomingCall インスタンスが含まれています。

Azure Communication Calling SDK は、ビデオを有効にして通話を開始、受け入れる、または参加するときにカメラを使用できない場合に、 cameraStartFailed: true 呼び出し診断を発生させます。 この場合、通話はビデオがオフの状態で開始されます。 別のプロセスで使用されているか、オペレーティング システムで無効になっているため、カメラを使用できない可能性があります。

通話の保留と再開

任意の時点で、アクティブなメディアを使用して、 Connected 状態のアクティブな呼び出しが 1 つだけ必要です。 他のすべての呼び出しは、ユーザーが保留にするか、アプリケーションによってプログラムで保留にする必要があります。 このシナリオは、ユーザーが複数の発信通話と着信通話を処理する必要がある場合があるコンタクト センターなどのシナリオで一般的です。 この場合、すべての非アクティブな呼び出しを保留にし、ユーザーはアクティブな呼び出しでのみ他のユーザーと対話する必要があります

呼び出しを保留または再開するには、 holdresume 非同期 API を使用します。

通話を保留にするには:

await call.hold();

hold操作が解決されると、呼び出し状態は LocalHold に設定されます。 1 対 1 の通話では、他の参加者も保留になり、その参加者の観点からの通話の状態が RemoteHoldに設定されます。 その後、相手側の参加者が通話を保留にすると、状態は LocalHold に変わります。

グループ通話または会議では、hold はローカル操作であり、他の通話参加者の通話は保留になりません。

通話を再開するには、保留を開始したすべてのユーザーが通話を再開する必要があります。

保留から通話を再開するには、次の手順を行います。

await call.resume();

resume操作が解決されると、呼び出し状態が再びConnectedに設定されます。

通話をミュートまたはミュート解除する

ローカル エンドポイントをミュートまたはミュート解除するには、 muteunmute 非同期 API を使用します。

//mute local device (microphone / sent audio)
await call.mute();

//unmute local device (microphone / sent audio)
await call.unmute();

着信オーディオのミュートとミュート解除

着信オーディオをミュートすると、通話ボリュームが 0 に設定されます。 着信オーディオをミュートまたはミュート解除するには、 muteIncomingAudiounmuteIncomingAudio 非同期操作を使用します。

//mute local device (speaker)
await call.muteIncomingAudio();

//unmute local device (speaker)
await call.unmuteIncomingAudio();

着信オーディオがミュートされている場合でも、参加者クライアント SDK は通話オーディオ (リモート参加者のオーディオ) を受け取ります。 通話音声は話者に聞こえません。参加者は、 call.unmuteIncomingAudio() が呼び出されるまで聞くことができません。 ただし、通話オーディオにフィルターを適用し、フィルター処理されたオーディオを再生できます。

リモート参加者を管理する

すべてのリモート参加者は、 RemoteParticipant オブジェクトに含まれており、呼び出しインスタンスの remoteParticipants コレクションを介して使用できます。 remoteParticipants オブジェクトには、Call インスタンスからアクセスできます。

通話の参加者を一覧表示する

remoteParticipants コレクションで、通話におけるリモート参加者の一覧が返されます。

call.remoteParticipants; // [remoteParticipant, remoteParticipant....]

通話に参加者を追加する

通話に参加者 (ユーザーまたは電話番号) を追加するには、 addParticipant 操作を使用します。 Identifier の種類のいずれかを指定します。 remoteParticipant インスタンスを同期的に返します。 参加者が正常に呼び出しに追加されると、Call から remoteParticipantsUpdated イベントが発生します。

const userIdentifier = { communicationUserId: '<ACS_USER_ID>' };
const pstnIdentifier = { phoneNumber: '<PHONE_NUMBER>' }
const remoteParticipant = call.addParticipant(userIdentifier);
const alternateCallerId = {  phoneNumber: '<ALTERNATE_CALLER_ID>' };
const remoteParticipant = call.addParticipant(pstnIdentifier, { alternateCallerId });

通話から参加者を削除する

通話から参加者 (ユーザーまたは電話番号) を削除するには、 removeParticipantを呼び出すことができます。 Identifier の種類のいずれかを渡す必要があります。 このメソッドは、呼び出しから参加者を削除した後に非同期的に解決されます。 参加者は、remoteParticipants コレクションからも削除されます。

const userIdentifier = { communicationUserId: '<ACS_USER_ID>' };
const pstnIdentifier = { phoneNumber: '<PHONE_NUMBER>' }
await call.removeParticipant(userIdentifier);
await call.removeParticipant(pstnIdentifier);

リモート参加者のプロパティにアクセスする

リモート参加者には、一連のプロパティとコレクションが関連付けられています。

  • CommunicationIdentifier: リモート参加者の識別子を取得します。 ID は CommunicationIdentifier の種類の 1 つです。

    const identifier = remoteParticipant.identifier;
    
  • これは、次の CommunicationIdentifier の種類のいずれかになります。

    • { communicationUserId: '<ACS_USER_ID'> }: Azure Communication Services ユーザーを表すオブジェクト。
    • { phoneNumber: '<E.164>' }: E.164 形式で電話番号を表すオブジェクト。
    • { microsoftTeamsUserId: '<TEAMS_USER_ID>', isAnonymous?: boolean; cloud?: "public" | "dod" | "gcch" }: Tems ユーザーを表すオブジェクト。
    • { id: string }: 他の識別子の種類に適合しない識別子を表すオブジェクト
  • state: リモート参加者の状態を取得します。

    const state = remoteParticipant.state;
    
  • 次の状態があります。

    • Idle: 初期状態。
    • Connecting: 参加者が通話に接続している間の遷移状態。
    • Ringing: 参加者が発信しています。
    • Connected: 参加者は通話に接続されています。
    • Hold: 参加者は保留中です。
    • EarlyMedia: 参加者が通話に接続する前に再生されるアナウンス。
    • InLobby: リモート参加者がロビーにいることを示します。
    • Disconnected: 最終状態。 参加者は通話から切断されました。 リモート参加者がネットワーク接続を失うと、2 分後に状態は Disconnected に変わります。
  • callEndReason: 参加者が通話を終了した理由を知るには、callEndReason プロパティを調べます。

    const callEndReason = remoteParticipant.callEndReason;
    const callEndReasonCode = callEndReason.code // (number) code associated with the reason
    const callEndReasonSubCode = callEndReason.subCode // (number) subCode associated with the reason
    

    このプロパティは、たとえば、Call.addParticipant() API を使用してリモートの参加者を追加し、リモートの参加者が拒否した場合にのみ設定されます。

    UserB が UserC をキックするシナリオでは、UserA の視点からは、このフラグが UserC に対して設定されていることを認識できません。 言い換えると、UserA は UserC の callEndReason プロパティが設定されることをまったく認識できません。

  • isMuted 状態: リモート参加者がミュートされているかどうかを確認するには、isMuted プロパティを調べます。 Boolean を返します。

    const isMuted = remoteParticipant.isMuted;
    
  • isSpeaking 状態: リモート参加者が話しているかどうかを確認するには、isSpeaking プロパティを調べます。 Boolean を返します。

    const isSpeaking = remoteParticipant.isSpeaking;
    
  • videoStreams: 特定の参加者がこの通話で送信しているすべての動画ストリームを調べるには、videoStreams コレクションを確認します。 これには、RemoteVideoStream オブジェクトが含まれています。

    const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
    
  • displayName: このリモート参加者の表示名を取得するには、文字列を返す displayName プロパティを調べます。

    const displayName = remoteParticipant.displayName;
    
  • endpointDetails: このリモート参加者に関するすべてのエンドポイントの詳細を取得します

    const endpointDetails: EndpointDetails[] = remoteParticipant.endpointDetails;
    

    リモート参加者は、多くの可能なエンドポイントからの呼び出しに含まれる可能性があり、各エンドポイントには独自の一意の participantIdがあります。 participantId は、 RemoteParticipant 識別子の生 ID とは異なります。

他の参加者をミュートする

Azure Communication Services Calling Web SDK バージョン 1.26.1 以降を使用します。

他のすべての参加者をミュートするか、通話に接続されている特定の参加者をミュートするには、その通話に対して非同期 API muteAllRemoteParticipants、またリモート参加者に対して mute を使用することができます。 Call からの mutedByOthers イベントは、ローカル参加者が他のユーザーによってミュートされたときに発生します。

重要

Azure Communication Services のこの機能は、現在プレビュー段階にあります。 プレビュー段階の機能は一般公開されており、新規および既存の Microsoft のすべてのお客様が使用できます。

プレビューの API と SDK は、サービス レベル アグリーメントなしに提供されます。 運用環境のワークロードには使用しないことをお勧めします。 特定の機能がサポートされていないか、機能が制約されている可能性があります。

詳細については、「 Microsoft Azure プレビューの追加使用条件」を参照してください。

呼び出し元の WebJS SDK を使用して PSTN エンドポイントをミュートすることは現在パブリック プレビュー段階であり、ビルド 1.34.1 1.34.1 以降のバージョンで使用できます。

1 対 1 の通話で他のユーザーをミュートすることはサポートされていません。

//mute all participants except yourself
await call.muteAllRemoteParticipants();

//mute a specific participant
await call.remoteParticipants[0].mute();

通話のプロパティを確認する

通話の一意の ID (文字列) を取得します。

const callId: string = call.id;

ローカル参加者 ID を取得します。

const participantId: string = call.info.participantId;

Azure Communication Services ID は、多くのエンドポイントで Web 呼び出し元 SDK を使用でき、各エンドポイントには独自の一意の participantIdがあります。 participantId は、Azure Communication Services のアイデンティティ・ロウIDとは異なります。

Teams 会議に参加する場合は、スレッド ID を取得します。

const threadId: string | undefined = call.info.threadId;

通話に関する情報を取得する:

const callInfo = call.info;

remoteParticipants インスタンスのcall コレクションを調べることで、呼び出しの他の参加者について説明します。

const remoteParticipants = call.remoteParticipants;

着信通話の発信者を特定します。

const callerIdentity = call.callerInfo.identifier;

identifierCommunicationIdentifier の種類の 1 つです。

通話の状態を取得します。

const callState = call.state;

これにより、通話の現在の状態を表す文字列が返されます。

  • None: 通話の初期状態。
  • Connecting: 通話が発信または受信されたときの初期遷移状態。
  • Ringing: 発信通話の場合、リモート参加者に対して通話が発信されていることを示します。 そちら側では、これは Incoming です。
  • EarlyMedia: 通話が接続される前に、アナウンスが再生されている状態を示します。
  • Connected: 通話が接続されていることを示します。
  • LocalHold: 通話がローカル参加者によって保留にされていることを示します。 ローカル エンドポイントとリモート参加者の間でメディアは送信されていません。
  • RemoteHold: 通話がリモート参加者によって保留にされていることを示します。 ローカル エンドポイントとリモート参加者の間でメディアは送信されていません。
  • InLobby: ユーザーがロビーにいることを示します。
  • Disconnecting: 通話が Disconnected 状態になる前の遷移状態。
  • Disconnected: 通話の最終状態。 ネットワーク接続が失われると、2 分後に状態は Disconnected になります。

通話が終了した理由を確認するには、callEndReason プロパティを調べます。

const callEndReason = call.callEndReason;
const callEndReasonMessage = callEndReason.message // (string) user friendly message
const callEndReasonCode = callEndReason.code // (number) code associated with the reason
const callEndReasonSubCode = callEndReason.subCode // (number) subCode associated with the reason

現在の通話が着信か、発信かを知るには、direction プロパティを調べます。 CallDirection を返します。

const isIncoming = call.direction == 'Incoming';
const isOutgoing = call.direction == 'Outgoing';

アクティブな動画ストリームとアクティブな画面共有ストリームを調べるには、localVideoStreams コレクションを確認します。 localVideoStreams操作は、LocalVideoStreamVideo、またはScreenSharing型のRawMediaオブジェクトを返します。

const localVideoStreams = call.localVideoStreams;

現在マイクがミュートされているかどうかを調べます。 Boolean を返します。

const muted = call.isMuted;

現在の着信オーディオ (スピーカー) がミュートされているかどうかを確認します。 Boolean を返します。

const incomingAudioMuted = call.isIncomingAudioMuted;

動画がオンになっているかどうかを確認します。 Boolean を返します。

const isLocalVideoStarted = call.isLocalVideoStarted;

画面共有がオンになっているかどうかを確認します。 Boolean を返します。

const isScreenSharingOn = call.isScreenSharingOn;

電話を切る

通話を切断するには、2 つの方法があります。

  • 最初の呼び出し元は通話を終了でき、他の参加者は通話に残ります。
  • 最初の呼び出し元が離れると、呼び出しはすべての参加者に対して終了します。

通話を終了するには、次の方法を使ってください。

call.hangUp();

HangUpOptionsを指定して、すべての参加者の通話を終了します。

この操作は room では使用できません。

call.hangUp( forEveryone: true);

SDK のインストール

プロジェクト レベルの build.gradle ファイルを見つけて、mavenCentral()buildscript の下のリポジトリの一覧に allprojects を追加します。

buildscript {
    repositories {
    ...
        mavenCentral()
    ...
    }
}
allprojects {
    repositories {
    ...
        mavenCentral()
    ...
    }
}

次に、モジュール レベルの build.gradle ファイルで、次の行を dependencies セクションに追加します。

dependencies {
    ...
    implementation 'com.azure.android:azure-communication-calling:1.0.0'
    ...
}

必要なオブジェクトを初期化する

CallAgent インスタンスを作成するには、createCallAgent インスタンス上で CallClient メソッドを呼び出す必要があります。 この呼び出しは、CallAgent インスタンス オブジェクトを非同期に返します。

createCallAgent メソッドは、CommunicationUserCredentialをカプセル化する を引数として受け取ります。

DeviceManager にアクセスするには、まず callAgent インスタンスを作成する必要があります。 それから、CallClient.getDeviceManager メソッドを使用して DeviceManager を取得することができます。

String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an activity, for instance
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential).get();
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();

呼び出し元の表示名を設定するには、この代替メソッドを使用します。

String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an activity, for instance
CallAgentOptions callAgentOptions = new CallAgentOptions();
callAgentOptions.setDisplayName("Alice Bob");
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential, callAgentOptions).get();

通話を行う

呼び出しを作成して開始するには、 CallAgent.startCall() メソッドを呼び出し、受信者または受信者の Identifier を指定する必要があります。

グループ呼び出しに参加するには、 CallAgent.join() メソッドを呼び出し、 groupIdを指定する必要があります。 グループ ID は GUID または UUID 形式である必要があります。

通話の作成と開始は同期的に行われます。 呼び出しインスタンスを使用すると、呼び出しのすべてのイベントをサブスクライブできます。

ユーザーと 1:1 の通話を行う

別の Communication Services ユーザーと通話するには、callcallAgent メソッドを呼び出し、communicationUserId キーを使用してオブジェクトを渡します。

StartCallOptions startCallOptions = new StartCallOptions();
Context appContext = this.getApplicationContext();
CommunicationUserIdentifier acsUserId = new CommunicationUserIdentifier(<USER_ID>);
CommunicationUserIdentifier participants[] = new CommunicationUserIdentifier[]{ acsUserId };
call oneToOneCall = callAgent.startCall(appContext, participants, startCallOptions);

ユーザーおよび PSTN と 1:n の通話を行う

PSTN 通話プランの詳細を参照してください。 プレビュー プログラムにアクセスするには、早期導入者プログラムに申し込みます

ユーザーと公衆交換電話網 (PSTN) 番号に 1:n 通話を発信するには、受信者または受信者の電話番号を指定する必要があります。

PSTN 通話を有効にするには、Communication Services リソースを構成する必要があります。

CommunicationUserIdentifier acsUser1 = new CommunicationUserIdentifier(<USER_ID>);
PhoneNumberIdentifier acsUser2 = new PhoneNumberIdentifier("<PHONE_NUMBER>");
CommunicationIdentifier participants[] = new CommunicationIdentifier[]{ acsUser1, acsUser2 };
StartCallOptions startCallOptions = new StartCallOptions();
Context appContext = this.getApplicationContext();
Call groupCall = callAgent.startCall(participants, startCallOptions);

通話を受信する

呼び出しを受け入れるには、呼び出しオブジェクトで accept メソッドを呼び出します。

Context appContext = this.getApplicationContext();
IncomingCall incomingCall = retrieveIncomingCall();
Call call = incomingCall.accept(context).get();

ビデオ カメラを使用して着信を受け入れるには:

Context appContext = this.getApplicationContext();
IncomingCall incomingCall = retrieveIncomingCall();
AcceptCallOptions acceptCallOptions = new AcceptCallOptions();
VideoDeviceInfo desiredCamera = callClient.getDeviceManager().get().getCameraList().get(0);
acceptCallOptions.setVideoOptions(new VideoOptions(new LocalVideoStream(desiredCamera, appContext)));
Call call = incomingCall.accept(context, acceptCallOptions).get();

onIncomingCall オブジェクトのcallAgent イベントをサブスクライブして、着信呼び出しを取得します。

// Assuming "callAgent" is an instance property obtained by calling the 'createCallAgent' method on CallClient instance 
public Call retrieveIncomingCall() {
    IncomingCall incomingCall;
    callAgent.addOnIncomingCallListener(new IncomingCallListener() {
        void onIncomingCall(IncomingCall inboundCall) {
            // Look for incoming call
            incomingCall = inboundCall;
        }
    });
    return incomingCall;
}

ルーム通話に参加する

CallAgentRoomCallLocator を使用し、roomId を指定してルーム呼び出しに参加します。 CallAgent.join メソッドは、Call オブジェクトを返します。

val roomCallLocator = RoomCallLocator(roomId)
call = callAgent.join(applicationContext, roomCallLocator, joinCallOptions)

room を使用すると、アプリケーション開発者は、誰が通話に参加できるか、いつ会うか、そしてどのように共同作業を行うかをより制御しやすくなります。 会議室の詳細については、「 構造化された会議の Rooms API 」および 「会議室呼び出しに参加する」を参照してください。

グループ通話に参加する

新しいグループ呼び出しを開始するか、進行中のグループ呼び出しに参加するには、 join メソッドを呼び出し、 groupId プロパティを持つオブジェクトを渡す必要があります。 値には GUID を指定する必要があります。

Context appContext = this.getApplicationContext();
GroupCallLocator groupCallLocator = new GroupCallLocator("<GUID>");
JoinCallOptions joinCallOptions = new JoinCallOptions();

call = callAgent.join(context, groupCallLocator, joinCallOptions);

通話のプロパティ

この通話の一意の ID を取得します。

String callId = call.getId();

通話の他の参加者について知るには、remoteParticipant インスタンスの call コレクションを調べます。

List<RemoteParticipant> remoteParticipants = call.getRemoteParticipants();

通話が着信の場合の呼び出し元の ID です。

CommunicationIdentifier callerId = call.getCallerInfo().getIdentifier();

通話の状態を取得します。

CallState callState = call.getState();

これにより、通話の現在の状態を表す文字列が返されます。

  • NONE - 初期呼び出し状態
  • EARLY_MEDIA - 通話が接続される前にアナウンスが再生される状態を示します
  • CONNECTING - 呼び出しが行われたか受け入れられた後の初期遷移状態
  • RINGING - 発信通話の場合 - リモート参加者の通話が呼び出し中であることを示します
  • CONNECTED - 通話接続
  • LOCAL_HOLD - ローカル エンドポイントとリモート参加者の間を流れるメディアがないローカル参加者によって保留にされた通話
  • REMOTE_HOLD - ローカル エンドポイントとリモート参加者の間を流れるメディアがないリモート参加者によって保留にされた通話
  • DISCONNECTING - 呼び出しが Disconnected 状態になる前の遷移状態
  • DISCONNECTED - 最終的な呼び出し状態
  • IN_LOBBY - Teams の会議の相互運用性のためにロビーにいます

通話が終了した理由を確認するには、callEndReason プロパティを調べます。 これには、コードとサブコードが含まれます。

CallEndReason callEndReason = call.getCallEndReason();
int code = callEndReason.getCode();
int subCode = callEndReason.getSubCode();

現在の通話が着信通話と発信通話のどちらであるかを確認するには、callDirection プロパティを調べます。

CallDirection callDirection = call.getCallDirection(); 
// callDirection == CallDirection.INCOMING for incoming call
// callDirection == CallDirection.OUTGOING for outgoing call

現在マイクがミュートされているかどうかを確認するには、muted プロパティを調べます。

boolean muted = call.isMuted();

アクティブな動画ストリームを調べるには、localVideoStreams コレクションを確認します。

List<LocalVideoStream> localVideoStreams = call.getLocalVideoStreams();

ミュートとミュート解除

ローカル エンドポイントをミュートまたはミュート解除するには、非同期 API の muteunmute を使用します。

Context appContext = this.getApplicationContext();
call.mute(appContext).get();
call.unmute(appContext).get();

通話の音量を変更する

参加者が通話中は、電話のハードウェア ボリューム キーを使用して、ユーザーが通話ボリュームを変更できるようにする必要があります。

アクティビティで呼び出しが行われるストリームタイプsetVolumeControlStreamに対してAudioManager.STREAM_VOICE_CALLメソッドを使用します。

このメソッドを使用すると、ハードウェア ボリューム キーで通話の音量を変更できます。これは、電話アイコンまたはボリューム スライダーに類似したもので示されます。 また、アラーム、メディア、システム全体の音量など、他のサウンドプロファイルによる音量の変更を防止します。 詳細については、 オーディオ出力の変更の処理を参照してください。 |Android 開発者

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
}

リモート参加者の管理

すべてのリモート参加者は RemoteParticipant の種類を持ち、呼び出しインスタンスの remoteParticipants コレクションを通じて使用できます。

通話の参加者の一覧を取得する

remoteParticipants コレクションで、特定の通話におけるリモート参加者の一覧が返されます。

List<RemoteParticipant> remoteParticipants = call.getRemoteParticipants(); // [remoteParticipant, remoteParticipant....]

通話に参加者を追加する

通話に参加者 (ユーザーまたは電話番号) を追加するには、 addParticipant 操作を呼び出すことができます。

この操作により、リモート参加者インスタンスが同期的に返されます。

const acsUser = new CommunicationUserIdentifier("<acs user id>");
const acsPhone = new PhoneNumberIdentifier("<phone number>");
RemoteParticipant remoteParticipant1 = call.addParticipant(acsUser);
AddPhoneNumberOptions addPhoneNumberOptions = new AddPhoneNumberOptions(new PhoneNumberIdentifier("<alternate phone number>"));
RemoteParticipant remoteParticipant2 = call.addParticipant(acsPhone, addPhoneNumberOptions);

通話から参加者を削除する

通話から参加者 (ユーザーまたは電話番号) を削除するには、 removeParticipant 操作を呼び出します。

この操作は、参加者が呼び出しから削除されると非同期的に解決されます。

参加者は、remoteParticipants コレクションからも削除されます。

RemoteParticipant acsUserRemoteParticipant = call.getParticipants().get(0);
RemoteParticipant acsPhoneRemoteParticipant = call.getParticipants().get(1);
call.removeParticipant(acsUserRemoteParticipant).get();
call.removeParticipant(acsPhoneRemoteParticipant).get();

リモート参加者のプロパティ

特定のリモート参加要素には、一連のプロパティとコレクションが関連付けられています。

  • このリモート参加者の識別子を取得します。

ID は Identifier の種類の 1 つです。

CommunicationIdentifier participantIdentifier = remoteParticipant.getIdentifier();
  • このリモート参加者の状態を取得します。

    ParticipantState state = remoteParticipant.getState();
    

状態は次のいずれかになり得ます。

  • IDLE - 初期状態

  • EARLY_MEDIA - 参加者が通話に接続される前にアナウンスが再生される

  • RINGING - 参加者の通話が発信されています

  • CONNECTING - 参加者が通話に接続している間の遷移状態

  • CONNECTED - 参加者が通話に接続されている

  • HOLD: 参加者は保留中です

  • IN_LOBBY - 参加者はロビーで許可されるのを待ちます。 現在、Teams の相互運用シナリオでのみ使用されています

  • DISCONNECTED - 最終的な状態 - 参加者が通話から切断される

  • 参加者が通話を終了した理由を確認するには、callEndReason プロパティを調べます。

    CallEndReason callEndReason = remoteParticipant.getCallEndReason();
    
  • このリモート参加者がミュートされているかどうかを確認するには、isMuted プロパティを調べます。

    boolean isParticipantMuted = remoteParticipant.isMuted();
    
  • このリモート参加者が話しているかどうかを確認するには、isSpeaking プロパティを調べます。

    boolean isParticipantSpeaking = remoteParticipant.isSpeaking();
    
  • 特定の参加者がこの通話で送信しているすべての動画ストリームを調べるには、videoStreams コレクションを確認します。

    List<RemoteVideoStream> videoStreams = remoteParticipant.getVideoStreams(); // [RemoteVideoStream, RemoteVideoStream, ...]
    

他の参加者をミュートする

Android SDK バージョン 2.11.0 以降を呼び出す Azure Communication Services を使用します。

PSTN 参加者がミュートされると、ミュートされ、キーの組み合わせ ( *6 など) を押してミュートを解除できることを示すアナウンスが表示されます。 *6 キーを押すと、ミュートは解除されます。

呼び出しの他のすべての参加者をミュートするには、 muteAllRemoteParticipants API 操作を使用します。

call.muteAllRemoteParticipants();

特定のリモート参加者をミュートするには、特定のリモート参加者に対して mute API 操作を使用します。

remoteParticipant.mute();

他のユーザーによってミュートされていることをローカル参加者に通知するには、 onMutedByOthers イベントをサブスクライブします。

フォアグラウンド サービスの使用

アプリケーションがバックグラウンドであってもユーザーに表示されるタスクを実行する場合は、 Foreground Services を使用できます。

たとえば、フォアグラウンド サービスを使用して、アプリケーションがアクティブな呼び出しを行ったときに、ユーザーに表示される通知を提供します。 これにより、ユーザーがホーム画面にアクセスしたり、最近使った 画面からアプリケーションを削除したりした場合でも、通話は引き続きアクティブになります。

通話中にフォアグラウンド サービスを使用しない場合、ホーム画面に移動しても通話は継続されますが、アプリケーションを最近の画面から削除すると、Android OS によってアプリケーションのプロセスを強制終了された場合に通話が停止する可能性があります。

ユーザーが呼び出しを開始または参加するときに、フォアグラウンド サービスを開始する必要があります。次に例を示します。

call = callAgent.startCall(context, participants, options);
startService(yourForegroundServiceIntent);

また、呼び出しを切断したとき、または通話の状態が [切断] の場合も、フォアグラウンド サービスを停止する必要があります。次に例を示します。

call.hangUp(new HangUpOptions()).get();
stopService(yourForegroundServiceIntent);

フォアグラウンド サービスの詳細

アプリが最近の一覧から削除されたときに、既に実行されているフォアグラウンド サービスを停止するようなシナリオでは、ユーザーに表示される通知が削除されます。 この場合、Android OS はアプリケーション プロセスをしばらくの間存続させることができます。つまり、呼び出しはこの期間中もアクティブなままになる可能性があります。

たとえば、アプリケーションがサービス onTaskRemoved メソッドで Foreground Service を停止している場合、アプリケーションは アクティビティ ライフサイクルに従ってオーディオとビデオを開始または停止できます。 onDestroy メソッドのオーバーライドを使用してアクティビティが破棄されたときのオーディオとビデオの停止など。

システムを設定する

次の手順のようにして、システムを設定します。

Xcode プロジェクトを作成する

Xcode で、新しい iOS プロジェクトを作成し、[単一ビュー アプリ] テンプレートを選択します。 この記事では SwiftUI フレームワークを使うので、[言語][Swift] に、[インターフェイス][SwiftUI] に設定する必要があります。

この記事では、テストは作成しません。 [Include Tests] チェック ボックスはオフにしてもかまいません。

Xcode 内にプロジェクトを作成するためのウィンドウを示すスクリーンショット。

CocoaPods を使用してパッケージと依存関係をインストールする

  1. この例のように、アプリケーション用の Podfile を作成します。

    platform :ios, '13.0'
    use_frameworks!
    target 'AzureCommunicationCallingSample' do
        pod 'AzureCommunicationCalling', '~> 1.0.0'
    end
    
  2. pod install を実行します。

  3. Xcode を使用して .xcworkspace を開きます。

マイクへのアクセスを要求する

デバイスのマイクにアクセスするには、NSMicrophoneUsageDescription を使用してアプリの情報プロパティ一覧を更新する必要があります。 関連付けられる値には、システムがユーザーにアクセスを要求するために使うダイアログに含まれる文字列を設定します。

プロジェクト ツリーの [Info.plist] エントリを右クリックし、[Open As]> を選択します。 最上位の <dict> セクションに以下の行を追加してから、ファイルを保存します。

<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>

アプリのフレームワークを設定する

プロジェクトの ContentView.swift ファイルを開きます。 ファイルの先頭に import 宣言を追加して、AzureCommunicationCalling ライブラリをインポートします。 さらに、AVFoundation をインポートします。 これは、コードでのオーディオ アクセス許可の要求に必要です。

import AzureCommunicationCalling
import AVFoundation

CallAgent を初期化する

CallAgent から CallClient インスタンスを作成するには、初期化された後に callClient.createCallAgent オブジェクトを非同期に返す CallAgent メソッドを使用する必要があります。

通話クライアントを作成するには、CommunicationTokenCredential オブジェクトを渡します。

import AzureCommunication

let tokenString = "token_string"
var userCredential: CommunicationTokenCredential?
do {
    let options = CommunicationTokenRefreshOptions(initialToken: token, refreshProactively: true, tokenRefresher: self.fetchTokenSync)
    userCredential = try CommunicationTokenCredential(withOptions: options)
} catch {
    updates("Couldn't created Credential object", false)
    initializationDispatchGroup!.leave()
    return
}

// tokenProvider needs to be implemented by Contoso, which fetches a new token
public func fetchTokenSync(then onCompletion: TokenRefreshOnCompletion) {
    let newToken = self.tokenProvider!.fetchNewToken()
    onCompletion(newToken, nil)
}

作成した CommunicationTokenCredential オブジェクトを CallClient に渡し、表示名を設定します。

self.callClient = CallClient()
let callAgentOptions = CallAgentOptions()
options.displayName = " iOS Azure Communication Services User"

self.callClient!.createCallAgent(userCredential: userCredential!,
    options: callAgentOptions) { (callAgent, error) in
        if error == nil {
            print("Create agent succeeded")
            self.callAgent = callAgent
        } else {
            print("Create agent failed")
        }
})

アプリケーションがイベント デリゲートを実装する場合は、イベント サブスクリプションを必要とするオブジェクトへの厳密な参照を保持する必要があります。 たとえば、 call.addParticipant メソッドを呼び出すと、 RemoteParticipant オブジェクトが返されます。 その後、アプリケーションは RemoteParticipantDelegate をリッスンするようにデリゲートを設定し、アプリケーションは RemoteParticipant オブジェクトへの厳密な参照を保持する必要があります。 それ以外の場合、このオブジェクトが収集されると、呼び出し元 SDK がオブジェクトを呼び出そうとしたときに、デリゲートは致命的な例外をスローします。

発信通話を行う

通話を作成して開始するには、CallAgent でいずれかの API を呼び出し、Communication Services 管理クライアント SDK を使用してプロビジョニングしたユーザーの Communication Services ID を指定する必要があります。

通話の作成と開始は同期的に行われます。 呼び出しのすべてのイベントをサブスクライブできる呼び出しインスタンスを受け取ります。

ユーザーに対する 1:1 の通話、またはユーザーおよび PSTN と 1:n の通話を行う

let callees = [CommunicationUser(identifier: 'UserId')]
self.callAgent?.startCall(participants: callees, options: StartCallOptions()) { (call, error) in
     if error == nil {
         print("Successfully started outgoing call")
         self.call = call
     } else {
         print("Failed to start outgoing call")
     }
}

ユーザーおよび PSTN と 1:n の通話を行う

PSTN 通話プランの詳細を参照してください。 プレビュー プログラムにアクセスするには、早期導入者プログラムに申し込みます

ユーザーと公衆交換電話網 (PSTN) に 1:n 通話を発信するには、Communication Services で取得した電話番号を指定する必要があります。

let pstnCallee = PhoneNumberIdentifier(phoneNumber: '+1999999999')
let callee = CommunicationUserIdentifier('UserId')
self.callAgent?.startCall(participants: [pstnCallee, callee], options: StartCallOptions()) { (groupCall, error) in
     if error == nil {
         print("Successfully started outgoing call to multiple participants")
         self.call = groupCall
     } else {
         print("Failed to start outgoing call to multiple participants")
     }
}

ルーム通話に参加する

room 呼び出しに参加するには、roomId プロパティを room 識別子として指定します。 通話に参加するには、join メソッドを使用し、roomCallLocator を渡します。

func joinRoomCall() {
    if self.callAgent == nil {
        print("CallAgent not initialized")
        return
    }
    
    if (self.roomId.isEmpty) {
        print("Room ID not set")
        return
    }
    
    // Join a call with a Room ID
    let options = JoinCallOptions()
    let audioOptions = AudioOptions()
    audioOptions.muted = self.muted
    
    options.audioOptions = audioOptions
    
    let roomCallLocator = RoomCallLocator(roomId: roomId)
    self.callAgent!.join(with: roomCallLocator, joinCallOptions: options) { (call, error) in
        self.setCallAndObserver(call: call, error: error)
    }
}

room を使用すると、アプリケーション開発者は、誰が通話に参加できるか、いつ会うか、そしてどのように共同作業を行うかをより制御しやすくなります。 会議室の詳細については、「 構造化された会議の Rooms API 」および 「会議室呼び出しに参加する」を参照してください。

グループ通話に参加する

通話に参加するには、CallAgent でいずれかの API を呼び出す必要があります。

let groupCallLocator = GroupCallLocator(groupId: UUID(uuidString: "uuid_string")!)
self.callAgent?.join(with: groupCallLocator, joinCallOptions: JoinCallOptions()) { (call, error) in
    if error == nil {
        print("Successfully joined group call")
        self.call = call
    } else {
        print("Failed to join group call")
    }
}

着信通話をサブスクライブする

着信通話イベントに登録します。

final class IncomingCallHandler: NSObject, CallAgentDelegate, IncomingCallDelegate
{
    // Event raised when there is an incoming call
    public func callAgent(_ callAgent: CallAgent, didReceiveIncomingCall incomingcall: IncomingCall) {
        self.incomingCall = incomingcall
        // Subscribe to get OnCallEnded event
        self.incomingCall?.delegate = self
    }

    // Event raised when incoming call was not answered
    public func incomingCall(_ incomingCall: IncomingCall, didEnd args: PropertyChangedEventArgs) {
        print("Incoming call was not answered")
        self.incomingCall = nil
    }
}

電話の着信を受け入れる

通話を受け入れるには、accept オブジェクトに対して IncomingCall メソッドを呼び出します。

self.incomingCall!.accept(options: AcceptCallOptions()) { (call, error) in
   if (error == nil) {
       print("Successfully accepted incoming call")
       self.call = call
   } else {
       print("Failed to accept incoming call")
   }
}

let firstCamera: VideoDeviceInfo? = self.deviceManager!.cameras.first
localVideoStreams = [LocalVideoStream]()
localVideoStreams!.append(LocalVideoStream(camera: firstCamera!))
let acceptCallOptions = AcceptCallOptions()
acceptCallOptions.videoOptions = VideoOptions(localVideoStreams: localVideoStreams!)
if let incomingCall = self.incomingCall {
    incomingCall.accept(options: acceptCallOptions) { (call, error) in
        if error == nil {
            print("Incoming call accepted")
        } else {
            print("Failed to accept incoming call")
        }
    }
} else {
  print("No incoming call found to accept")
}

通話中の操作を実行する

通話中に操作を実行して、ビデオとオーディオに関連する設定を管理できます。

ミュートとミュート解除

ローカル エンドポイントのミュートまたはその解除を行う場合は、非同期 API の muteunmute を使用できます。

call!.mute { (error) in
    if error == nil {
        print("Successfully muted")
    } else {
        print("Failed to mute")
    }
}

ローカル エンドポイントのミュートを非同期に解除するには、次のコードを使用します。

call!.unmute { (error) in
    if error == nil {
        print("Successfully un-muted")
    } else {
        print("Failed to unmute")
    }
}

リモート参加者を管理する

RemoteParticipantの種類は、すべてのリモート参加者を表します。 これらは、呼び出しインスタンスの remoteParticipants コレクションを通じて使用できます。

通話の参加者の一覧を取得する

call.remoteParticipants

通話に参加者を追加する

通話に参加者をユーザーまたは電話番号として追加するには、 addParticipant 操作を呼び出します。 この操作は、リモート参加者インスタンスを同期的に返します。

let remoteParticipantAdded: RemoteParticipant = call.add(participant: CommunicationUserIdentifier(identifier: "userId"))

通話から参加者を削除する

ユーザーまたは電話番号として通話から参加者を削除するには、 removeParticipant 操作を呼び出します。 この操作は非同期的に解決されます。

call!.remove(participant: remoteParticipantAdded) { (error) in
    if (error == nil) {
        print("Successfully removed participant")
    } else {
        print("Failed to remove participant")
    }
}

リモート参加者のプロパティを取得する

// [RemoteParticipantDelegate] delegate - an object you provide to receive events from this RemoteParticipant instance
var remoteParticipantDelegate = remoteParticipant.delegate

// [CommunicationIdentifier] identity - same as the one used to provision a token for another user
var identity = remoteParticipant.identifier

// ParticipantStateIdle = 0, ParticipantStateEarlyMedia = 1, ParticipantStateConnecting = 2, ParticipantStateConnected = 3, ParticipantStateOnHold = 4, ParticipantStateInLobby = 5, ParticipantStateDisconnected = 6
var state = remoteParticipant.state

// [Error] callEndReason - reason why participant left the call, contains code/subcode/message
var callEndReason = remoteParticipant.callEndReason

// [Bool] isMuted - indicating if participant is muted
var isMuted = remoteParticipant.isMuted

// [Bool] isSpeaking - indicating if participant is currently speaking
var isSpeaking = remoteParticipant.isSpeaking

// RemoteVideoStream[] - collection of video streams this participants has
var videoStreams = remoteParticipant.videoStreams // [RemoteVideoStream, RemoteVideoStream, ...]

他の参加者をミュートする

Azure Communication Services Calling iOS SDK バージョン 2.13.0 以降を使用します。

PSTN 参加者がミュートされると、ミュートされ、キーの組み合わせ ( *6 など) を押してミュートを解除できることを示すアナウンスが表示されます。 *6 キーを押すと、ミュートは解除されます。

通話の他のすべての参加者をミュートするには、通話で muteAllRemoteParticipants 操作を使用します。

call!.muteAllRemoteParticipants { (error) in
    if error == nil {
        print("Successfully muted all remote participants.")
    } else {
        print("Failed to mute remote participants.")
    }
}

特定のリモート参加者をミュートするには、特定のリモート参加者に対して mute 操作を使用します。

remoteParticipant.mute { (error) in
    if error == nil {
        print("Successfully muted participant.")
    } else {
        print("Failed to mute participant.")
    }
}

他のユーザーによってミュートされていることをローカル参加者に通知するには、 onMutedByOthers イベントをサブスクライブします。

システムを設定する

次の手順のようにして、システムを設定します。

Visual Studio プロジェクトの作成

ユニバーサル Windows プラットフォーム アプリを作成するには、Visual Studio 2022 で、新しいブランク アプリ(ユニバーサル Windows) プロジェクトを作成します。 プロジェクト名を入力した後、10.0.17763.0 より後の Windows SDK を自由に選択できます。

WinUI 3 アプリの場合、Blank App, Packaged (WinUI 3 in Desktop) テンプレートで新しいプロジェクトを作成し、シングルページの WinUI 3 アプリを設定します。 Windows App SDK バージョン 1.3 以降が必要です。

NuGet パッケージ マネージャーを使用してパッケージと依存関係をインストールする

Calling SDK の API とライブラリは、NuGet パッケージにより一般公開されています。

Calling SDK NuGet パッケージを検索、ダウンロード、インストールするには:

  1. [ツール]>[NuGet パッケージ マネージャー]>[ソリューションの NuGet パッケージの管理] を選んで、NuGet パッケージ マネージャーを開きます。
  2. [参照] を選んでから、検索ボックスに「Azure.Communication.Calling.WindowsClient」と入力します。
  3. [プレリリースを含める] チェックボックスがオンになっていることを確認します。
  4. Azure.Communication.Calling.WindowsClient パッケージを選び、Azure.Communication.Calling.WindowsClient1.4.0-beta.1 以降のバージョンを選びます。
  5. 右側のペインで、Azure Communication Services プロジェクトに対応するチェックボックスをオンにします。
  6. [インストール] を選択します。

Visual Studio でサンプル アプリを実装する

このセクションでは、Visual Studio で動作する呼び出しを管理するアプリを開発する方法について説明します。

マイクへのアクセスを要求する

アプリはマイクにアクセスする必要があります。 ユニバーサル Windows プラットフォーム (UWP) アプリでは、マイク機能をアプリ マニフェスト ファイルで宣言する必要があります。

マイクにアクセスするには:

  1. Solution Explorer パネルで、.appxmanifest 拡張子が付いたファイルをダブルクリックします。
  2. [Capabilities] タブをクリックします。
  3. 機能の一覧から [Microphone] チェック ボックスをオンにします。

通話の発信と終了を行うための UI ボタンを作成する

このサンプル アプリには、2 つのボタンが含まれています。 1 つは通話を行い、もう 1 つは通話を終了します。

アプリに 2 つのボタンを追加します。

  1. Solution Explorer パネルで、UWP の場合は MainPage.xaml、WinUI 3 の場合は MainWindows.xaml という名前のファイルをダブルクリックします。
  2. 中央のパネルで、UI プレビューの下にある XAML コードを探します。
  3. XAML コードを次の抜粋で変更します。
<TextBox x:Name="CalleeTextBox" PlaceholderText="Who would you like to call?" />
<StackPanel>
    <Button x:Name="CallButton" Content="Start/Join call" Click="CallButton_Click" />
    <Button x:Name="HangupButton" Content="Hang up" Click="HangupButton_Click" />
</StackPanel>

Calling SDK API を使用してアプリを設定する

Calling SDK API は、2 つの異なる名前空間に含まれています。

次の手順では、これらの名前空間について C# コンパイラに通知します。これにより、Visual Studio の Intellisense がコード開発に役立ちます。

  1. Solution Explorer パネルで、UWP の場合は MainPage.xaml、WinUI 3 の場合は MainWindows.xaml という名前のファイルの左側にある矢印をクリックします。
  2. MainPage.xaml.cs または MainWindows.xaml.cs という名前のファイルをダブルクリックします。
  3. 現在の using ステートメントの下部に次のコマンドを追加します。
using Azure.Communication.Calling.WindowsClient;

MainPage.xaml.cs または MainWindows.xaml.cs は開いたままにします。 次の手順では、さらにコードを追加します。

アプリの操作を有効にする

以前に追加した UI ボタンは、置かれたCommunicationCallの上で動作する必要があります。 つまり、CommunicationCall データ メンバーを MainPage または MainWindow クラスに追加する必要があります。 さらに、非同期操作の CallAgent 作成を成功させるには、CallAgent データ メンバーも同じクラスに追加する必要があります。

MainPage または MainWindow クラスに次のデータ メンバーを追加します。

CallAgent callAgent;
CommunicationCall call;

ボタン ハンドラーを作成する

前に、2 つの UI ボタンが XAML コードに追加されました。 次のコードでは、ユーザーがボタンを選択すると実行されるハンドラーを追加します。 次のコードは、前のセクションのデータ メンバーの後に追加する必要があります。

private async void CallButton_Click(object sender, RoutedEventArgs e)
{
    // Start call
}

private async void HangupButton_Click(object sender, RoutedEventArgs e)
{
    // End the current call
}

オブジェクト モデル

UWP 用の Azure Communication Services Calling クライアント ライブラリが備える主な機能のいくつかは、以下のクラスとインターフェイスにより処理されます。

名前 説明
CallClient CallClient は、通話クライアント ライブラリへのメイン エントリ ポイントです。
CallAgent CallAgent は、通話を開始して参加するために使用します。
CommunicationCall CommunicationCall は、発信したり参加したりした通話の管理に使用されます。
CommunicationTokenCredential CommunicationTokenCredential は、CallAgent をインスタンス化するためのトークン資格情報として使用されます。
CallAgentOptions CallAgentOptions には、呼び出し元を識別するための情報が含まれています。
HangupOptions HangupOptions は、呼び出しを終了する必要があるかどうかをすべての参加者に対して通知します。

CallAgent を初期化する

CallAgent から CallClient インスタンスを作成するには、初期化されると CallClient.CreateCallAgentAsync オブジェクトを非同期に返す CallAgent メソッドを使用する必要があります。

CallAgent を作成するには、CallTokenCredential オブジェクトと CallAgentOptions オブジェクトを渡す必要があります。 形式に誤りがあるトークンが渡されると、CallTokenCredential がスローされることに注意してください。

アプリの初期化中に呼び出すには、次のコードを内部に追加し、ヘルパー関数を追加します。

var callClient = new CallClient();
this.deviceManager = await callClient.GetDeviceManagerAsync();

var tokenCredential = new CallTokenCredential("<AUTHENTICATION_TOKEN>");
var callAgentOptions = new CallAgentOptions()
{
    DisplayName = "<DISPLAY_NAME>"
};

this.callAgent = await callClient.CreateCallAgentAsync(tokenCredential, callAgentOptions);

リソース用の有効な資格情報トークンで <AUTHENTICATION_TOKEN> を変更します。 資格情報トークンをソースにする必要がある場合は、 ユーザー アクセス トークンを参照してください。

CallAgent を作成して通話を行う

CallAgentを作成するために必要なオブジェクトの準備ができました。 次に、CallAgent を非同期的に作成して通話を行います。

前の手順の例外を処理した後、次のコードを追加します。

var startCallOptions = new StartCallOptions();
var callees = new [] { new UserCallIdentifier(CalleeTextBox.Text.Trim()) };

this.call = await this.callAgent.StartCallAsync(callees, startCallOptions);
this.call.OnStateChanged += Call_OnStateChangedAsync;

8:echo123を使用して、Azure Communication Services エコー ボットと通信します。

ミュートとミュート解除

発信音声をミュートまたはミュート解除するには、 MuteOutgoingAudioAsyncUnmuteOutgoingAudioAsync 非同期操作を使用します。

// mute outgoing audio
await this.call.MuteOutgoingAudioAsync();

// unmute outgoing audio
await this.call.UnmuteOutgoingAudioAsync();

他の参加者をミュートする

Windows SDK バージョン 1.9.0 以降を呼び出す Azure Communication Services を使用します。

PSTN 参加者がミュートされると、ミュートされたこと、およびキーの組み合わせ ( *6 など) を押してミュートを解除できることを示すアナウンスを受け取る必要があります。 *6 キーを押す場合は、ミュートを解除する必要があります。

他のすべての参加者をミュートしたり、特定の参加者をミュートしたりするには、呼び出しで MuteAllRemoteParticipantsAsync 非同期操作を使用し、リモート参加者に MuteAsync します。

// mute all participants except yourself
await this.call.MuteAllRemoteParticipantsAsync();

// mute specific participant in the call
await this.call.RemoteParticipants.FirstOrDefault().MuteAsync();

他のユーザーによってミュートされていることをローカル参加者に通知するには、 MutedByOthers イベントをサブスクライブします。

通話を終了する

呼び出しが行われたら、HangupAsync オブジェクトの CommunicationCall メソッドを使用して呼び出しを切断します。

呼び出しを終了する必要があるかどうかをすべての参加者に通知するには、 HangupOptions のインスタンスを使用します。

HangupButton_Click内に次のコードを追加します。

this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions() { ForEveryone = false });

コードの実行

  1. Visual Studio で、 x64x86 、または ARM64用のアプリがビルドされていることを確認します。
  2. F5 キーを押してアプリの実行を開始します。
  3. アプリが実行されたら、[ 呼び出し ] ボタンをクリックして、定義された受信者に通話を発信します。

アプリを初めて実行すると、マイクへのアクセスを許可するようにユーザーに求められます。

次のステップ