Mengelola panggilan

Pelajari cara mengelola panggilan dengan Azure Communication Services SDKS. Kami akan belajar cara melakukan panggilan, mengelola peserta dan properti mereka.

Prasyarat

Memasang SDK

Menggunakan perintah npm install untuk memasang panggilan Azure Communication Services dan SDK umum untuk JavaScript.

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

Menginisialisasi objek yang diperlukan

CallClient, instans diperlukan untuk sebagian besar operasi panggilan. Mari buat CallClient instans baru. Anda dapat mengonfigurasinya dengan opsi khusus seperti Pencatat instans.

Bila Anda memiliki instans CallClient, Anda dapat membuat instans CallAgent dengan memanggil metode createCallAgent pada instans CallClient. Metode ini secara asinkron mengembalikan objek instans CallAgent.

Metode createCallAgent menggunakan CommunicationTokenCredential sebagai argumen. Hal ini menerima token akses pengguna.

Anda dapat menggunakan metode getDeviceManager pada instans CallClient untuk mengakses 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 wherever desired. To console, file, buffer, REST API, etc...
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()

Melakukan Telepon

Untuk membuat dan memulai panggilan, gunakan salah satu API di callAgent dan berikan pengguna yang Anda buat melalui SDK identitas Communication Services.

Pembuatan dan permulaan panggilan bersifat sinkron. Instans call memungkinkan Anda untuk berlangganan acara panggilan.

Melakukan panggilan 1:n ke pengguna atau PSTN

Untuk memanggil pengguna Communication Services lain, menggunakan metode startCall di callAgent dan meneruskan CommunicationUserIdentifier penerima yang Anda buat dengan perpustakaan administrasi Communication Services.

Untuk panggilan 1:1 ke pengguna, gunakan kode berikut:

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

Untuk melakukan panggilan ke jaringan telepon umum (PSTN), gunakan metode startCall di callAgent dan meneruskan PhoneNumberIdentifier penerima. Sumber daya Communication Services Anda harus dikonfigurasi untuk mengizinkan panggilan PSTN.

Saat Anda memanggil nomor PSTN, tentukan ID penelepon alternatif Anda. ID penelepon alternatif adalah nomor telepon (berdasarkan standar E.164) yang mengidentifikasi penelepon dalam panggilan PSTN. Hal ini adalah nomor telepon yang dilihat oleh penerima panggilan untuk panggilan masuk.

Catatan

Panggilan PSTN saat ini dalam pratinjau pribadi. Untuk akses, daftar ke program pengguna awal.

Untuk panggilan 1:1 ke nomor PSTN, gunakan kode berikut:

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

Untuk panggilan 1:n ke nomor PSTN dan pengguna, gunakan kode berikut:

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

Bergabung ke panggilan grup

Catatan

Parameter groupId dianggap sebagai metadata sistem dan dapat digunakan oleh Microsoft untuk operasi yang diperlukan untuk menjalankan sistem. Jangan sertakan data pribadi dalam nilai groupId. Microsoft tidak memperlakukan parameter ini sebagai data pribadi dan kontennya dapat dilihat oleh karyawan Microsoft atau disimpan dalam jangka panjang.

Parameter groupId memerlukan data dalam format GUID. Sebaiknya gunakan GUID yang dibuat secara acak yang tidak dianggap sebagai data pribadi di sistem Anda.

Untuk memulai panggilan grup baru atau bergabung dengan panggilan grup yang sedang berlangsung, gunakan metode join dan berikan objek dengan properti groupId. Nilai groupId harus berupa GUID.

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

Menerima panggilan masuk

Instans callAgent mengeluarkan peristiwa incomingCall saat identitas masuk menerima panggilan masuk. Untuk mendengarkan acara ini, berlangganan dengan menggunakan salah satu opsi berikut:

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

Peristiwa incomingCall mencakup kejadian incomingCall yang dapat Anda terima atau tolak.

Saat memulai/bergabung/menerima panggilan dengan video aktif, jika perangkat kamera video yang ditentukan sedang digunakan oleh proses lain atau semisalnya dinonaktifkan dalam sistem, panggilan akan dimulai dengan video non aktif, dan kameraStartFailed: true call diagnostic akan dieksekusi.

Mematikan suara dan menyalakan suara

Untuk menonaktifkan atau mengaktifkan titik akhir lokal, Anda dapat menggunakan mute dan unmute API asinkron:

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

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

Mematikan suara dan menyalakan suara audio masuk

Mematikan suara audio masuk mengatur volume panggilan ke 0. Untuk mematikan suara atau menyalakan suara audio masuk, Anda dapat menggunakan muteIncomingAudio API asinkron dan unmuteIncomingAudio :

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

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

Saat audio masuk dimatikan suaranya, peserta akan tetap menerima audio panggilan (audio peserta jarak jauh). Audio panggilan tidak akan berhenti di pembicara dan peserta tidak akan dapat mendengarkan sampai 'call.unmuteIncomingAudio()' dipanggil. Namun, kita dapat menerapkan filter pada audio panggilan dan memutar audio yang difilter.

Kelola peserta jarak jauh

Semua peserta jarak jauh diwakili jenis RemoteParticipant dan tersedia melalui koleksi remoteParticipants pada instans panggilan.

Daftar peserta dalam panggilan

Koleksi remoteParticipants mengembalikan daftar peserta jarak jauh dalam panggilan:

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

Menambahkan peserta ke panggilan

Untuk menambahkan peserta (baik pengguna atau nomor telepon) ke panggilan, Anda dapat menggunakan addParticipant. Memberikan salah satu dari Identifier jenis. Hal ini secara sinkron mengembalikan instans remoteParticipant. Acara remoteParticipantsUpdated dari Panggilan dimunculkan saat peserta berhasil ditambahkan ke panggilan.

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

Hapus peserta dari panggilan

Untuk menghapus peserta (baik pengguna atau nomor telepon) dari panggilan, Anda dapat memanggil removeParticipant. Anda harus melewati salah satu dari Identifier jenis. Metode ini diselesaikan secara asinkron setelah peserta dihapus dari panggilan. Peserta juga dihapus dari koleksi remoteParticipants.

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

Mengakses properti peserta jarak jauh

Peserta jarak jauh memiliki seperangkat properti dan koleksi terkait:

  • CommunicationIdentifier: Mendapatkan pengidentifikasi untuk peserta jarak jauh. Identitas adalah salah satu dari CommunicationIdentifier jenis:

    const identifier = remoteParticipant.identifier;
    

Hal ini dapat berupa salah satu dari CommunicationIdentifier jenis berikut:

  • { communicationUserId: '<ACS_USER_ID'> }: Objek yang mewakili pengguna Azure Communication Services.

  • { phoneNumber: '<E.164>' }: Objek yang mewakili nomor telepon dalam format E.164.

  • { microsoftTeamsUserId: '<TEAMS_USER_ID>', isAnonymous?: boolean; cloud?: "public" | "dod" | "gcch" }: Objek yang mewakili pengguna Teams.

  • { id: string }: pengidentifikasi representasi objek yang tidak cocok dengan jenis pengidentifikasi lainnya

  • state: Mendapatkan status peserta jarak jauh.

    const state = remoteParticipant.state;
    

Status dapat berupa:

  • Idle: Status awal.

  • Connecting: Status transisi saat peserta tersambung ke panggilan.

  • Ringing: Peserta menelepon.

  • Connected: Peserta tersambung ke panggilan.

  • Hold: Peserta ditangguhkan.

  • EarlyMedia: Pengumuman yang diputar sebelum peserta tersambung ke panggilan.

  • InLobby: Menunjukkan bahwa peserta jarak jauh berada di lobi.

  • Disconnected: Status akhir. Peserta terputus dari panggilan. Jika peserta jarak jauh kehilangan konektivitas jaringan, statusnya berubah menjadi Disconnected setelah dua menit.

  • callEndReason: Untuk mempelajari alasan peserta meninggalkan panggilan, periksa properti 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
    

    Catatan:

    • Properti ini hanya diatur saat menambahkan peserta jarak jauh melalui API Call.addParticipant(), dan peserta jarak jauh menolak misalnya.
    • Dalam skenario di mana misalnya, UserB menendang UserC, dari perspektif UserA, UserA tidak akan melihat bendera ini diatur untuk UserC. Dengan kata lain UserA tidak akan melihat properti callEndReason PenggunaC diatur sama sekali.
  • isMuted status: Untuk mengetahui apakah peserta jarak jauh dibisukan, periksa properti isMuted. Hal ini mengembalikan Boolean.

    const isMuted = remoteParticipant.isMuted;
    
  • isSpeaking status: Untuk mengetahui apakah peserta jarak jauh berbicara, periksa properti isSpeaking. Hal ini mengembalikan Boolean.

    const isSpeaking = remoteParticipant.isSpeaking;
    
  • videoStreams: Untuk memeriksa semua aliran video yang dikirim oleh peserta tertentu dalam panggilan ini, periksa koleksi videoStreams. Hal ini berisi RemoteVideoStream objek.

    const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
    
  • displayName: Untuk mendapatkan nama tampilan untuk peserta jarak jauh ini, periksa properti displayName yang dikembalikan string.

    const displayName = remoteParticipant.displayName;
    

Periksa properti panggilan

Mendapatkan ID unik (string) untuk panggilan:

const callId: string = call.id;

Mendapatkan informasi tentang panggilan:

Catatan

API ini disediakan sebagai pratinjau untuk pengembang dan dapat berubah menurut umpan balik yang kami terima. Jangan gunakan API ini dalam lingkungan produksi. Untuk menggunakan api ini, gunakan rilis 'beta' dari Azure Communication Services Calling Web SDK

const callInfo = call.info;

Pelajari tentang peserta lain dalam panggilan dengan memeriksa koleksi remoteParticipants pada instans 'panggilan':

const remoteParticipants = call.remoteParticipants;

Mengidentifikasi penelepon dari panggilan masuk:

const callerIdentity = call.callerInfo.identifier;

identifier adalah salah satu dari CommunicationIdentifier jenis.

Mendapatkan status panggilan:

const callState = call.state;

Hal ini mengembalikan string yang mewakili status panggilan saat ini:

  • None: Status panggilan awal.
  • Connecting: Status transisi awal saat panggilan dilakukan atau diterima.
  • Ringing: Untuk panggilan keluar, menunjukkan bahwa ada panggilan berdering untuk peserta jarak jauh. Ini artinya Incoming di pihak mereka.
  • EarlyMedia: Menunjukkan keadaan di mana pengumuman dimainkan sebelum panggilan tersambung.
  • Connected: Menunjukkan bahwa panggilan tersambung.
  • LocalHold: Menunjukkan bahwa panggilan ditunda oleh peserta lokal. Tidak ada media yang mengalir antara titik akhir lokal dan peserta jarak jauh.
  • RemoteHold: Menunjukkan bahwa panggilan ditunda oleh peserta jarak jauh. Tidak ada media yang mengalir antara titik akhir lokal dan peserta jarak jauh.
  • InLobby: Menunjukkan bahwa pengguna berada di lobi.
  • Disconnecting: Status transisi sebelum panggilan beralih ke status Disconnected.
  • Disconnected: Status panggilan terakhir. Jika koneksi jaringan terputus, statusnya berubah menjadi Disconnected setelah dua menit.

Cari tahu mengapa panggilan berakhir dengan memeriksa properti callEndReason:

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

Mempelajari apakah panggilan saat ini masuk atau keluar dengan memeriksa properti direction. Hal ini mengembalikan CallDirection.

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

Periksa apakah mikrofon saat ini dimatikan. Hal ini mengembalikan Boolean.

const muted = call.isMuted;

Periksa apakah audio masuk (speaker) saat ini dimatikan suaranya. Hal ini mengembalikan Boolean.

const incomingAudioMuted = call._isIncomingAudioMuted;

Cari tahu apakah aliran berbagi layar dikirim dari titik akhir tertentu dengan memeriksa properti isScreenSharingOn. Hal ini mengembalikan Boolean.

const isScreenSharingOn = call.isScreenSharingOn;

Periksa aliran video aktif dengan memeriksa koleksi localVideoStreams. Hal ini mengembalikan LocalVideoStream objek.

const localVideoStreams = call.localVideoStreams;

Memasang SDK

Temukan build.gradle tingkat proyek Anda dan pastikan untuk menambahkan mavenCentral() ke daftar repositori di bawah buildscript dan allprojects

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

Kemudian, di level modul build.gradle tambahkan baris berikut ke bagian dependensi

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

Menginisialisasi objek yang diperlukan

Untuk membuat instans CallAgent, Anda harus memanggil metode createCallAgent pada instans CallClient. Ini secara asinkron mengembalikan objek instans CallAgent. Metode createCallAgent mengambil CommunicationUserCredential sebagai argumen, yang merangkum token akses. Untuk mengakses DeviceManager, instans callAgent harus dibuat terlebih dahulu, kemudian Anda dapat menggunakan metode CallClient.getDeviceManager untuk mendapatkan 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();

Untuk mengatur nama tampilan penelepon, gunakan metode alternatif ini:

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

Melakukan Telepon

Untuk membuat dan memulai panggilan, Anda perlu memanggil metode CallAgent.startCall()dan menyediakan penerima panggilan Identifier. Untuk bergabung dalam panggilan grup, Anda perlu memanggil metode CallAgent.join() dan menyediakan groupId. ID Grup harus dalam format GUID atau UUID.

Pembuatan dan permulaan panggilan bersifat sinkron. Instans panggilan memungkinkan Anda berlangganan semua peristiwa pada panggilan.

Melakukan panggilan 1:1 ke pengguna

Untuk melakukan panggilan ke pengguna Communication Services lain, panggil metode call pada callAgent dan teruskan objek dengan kunci 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);

Melakukan panggilan 1:n dengan pengguna dan PSTN

Peringatan

Saat ini panggilan PSTN tidak tersedia

Untuk melakukan panggilan 1:n ke pengguna dan nomor PSTN, Anda harus menentukan nomor telepon penerima panggilan. Sumber daya Communication Services Anda harus dikonfigurasi untuk mengizinkan panggilan PSTN:

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

Menerima panggilan

Untuk menerima panggilan, hubungi metode 'terima' pada objek panggilan.

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

Untuk menerima panggilan dengan kamera video aktif:

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

Panggilan masuk dapat diperoleh dengan berlangganan peristiwa onIncomingCall pada objek 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;
}

Bergabung ke panggilan grup

Untuk memulai panggilan grup baru atau bergabung dalam panggilan grup yang sedang berlangsung, Anda harus memanggil metode 'gabung' dan meneruskan objek dengan properti groupId. Nilainya harus GUID.

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

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

Properti panggilan

Dapatkan ID unik untuk Panggilan ini:

String callId = call.getId();

Untuk mempelajari tentang peserta lain dalam koleksi panggilan, periksa koleksi remoteParticipant pada instans call:

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

Identitas penelepon jika panggilan masuk:

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

Dapatkan status Panggilan:

CallState callState = call.getState();

Hal ini mengembalikan string yang mewakili status panggilan saat ini:

  • 'NONE' - status panggilan awal
  • 'EARLY_MEDIA' - menunjukkan status di mana pengumuman diputar sebelum panggilan tersambung
  • 'CONNECTING' - status transisi awal setelah panggilan dilakukan atau diterima
  • 'RINGING' - untuk panggilan keluar - menunjukkan panggilan berdering untuk peserta jarak jauh
  • 'CONNECTED' - panggilan tersambung
  • 'LOCAL_HOLD' - panggilan ditunda oleh peserta lokal, tidak ada media yang mengalir antara titik akhir lokal dan peserta jarak jauh
  • 'REMOTE_HOLD' - panggilan ditunda oleh peserta jarak jauh, tidak ada media yang mengalir antara titik akhir lokal dan peserta jarak jauh
  • 'DISCONNECTING' - status transisi sebelum panggilan masuk ke status 'Disconnected'
  • 'DISCONNECTED' - status panggilan akhir
  • 'IN_LOBBY' - di lobi untuk interoperabilitas rapat Teams

Untuk mengetahui alasan panggilan diakhiri, periksa properti callEndReason. Properti tersebut berisi kode/subkode:

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

Untuk melihat apakah panggilan saat ini adalah panggilan masuk atau keluar, periksa properti callDirection:

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

Untuk melihat apakah mikrofon saat ini dibisukan, periksa properti muted:

boolean muted = call.isMuted();

Untuk memeriksa aliran video aktif, periksa koleksi localVideoStreams:

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

Mematikan suara dan menyalakan suara

Untuk mematikan atau menyalakan suara titik akhir lokal, Anda dapat menggunakan API asinkron mute dan unmute:

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

Mengubah volume panggilan

Saat Anda sedang menelepon, tombol volume perangkat keras di telepon akan memungkinkan pengguna untuk mengubah volume panggilan. Ini dilakukan dengan menggunakan metode setVolumeControlStream dengan jenis aliran AudioManager.STREAM_VOICE_CALL pada Aktivitas tempat panggilan dilakukan. Hal ini memungkinkan tombol volume perangkat keras untuk mengubah volume panggilan (dilambangkan dengan ikon telepon atau sesuatu yang serupa pada slider volume), mencegah untuk mengubah volume untuk profil suara lainnya, seperti alarm, media atau volume lebar sistem. Untuk informasi selengkapnya, Anda dapat memeriksa Menangani perubahan pada keluaran audio | Pengembang Android.

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

Manajemen peserta jarak jauh

Semua peserta jarak jauh diwakili jenis RemoteParticipant dan tersedia melalui koleksi remoteParticipants pada instans panggilan.

Mencantumkan peserta dalam panggilan

Koleksi remoteParticipants mengembalikan daftar peserta jarak jauh dalam panggilan tertentu:

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

Menambahkan peserta ke panggilan

Untuk menambahkan peserta ke panggilan (baik pengguna atau nomor telepon) Anda dapat memanggil addParticipant. Tindakan ini akan secara sinkron mengembalikan instans peserta jarak jauh.

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

Menghapus peserta dari panggilan

Untuk menghapus peserta dari panggilan (pengguna atau nomor telepon), Anda bisa memanggil removeParticipant. Tindakan ini akan diselesaikan secara asinkron setelah peserta dihapus dari panggilan. Peserta juga akan dihapus dari koleksi remoteParticipants.

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

Properti peserta jarak jauh

Setiap peserta jarak jauh yang diberikan memiliki sekumpulan properti dan koleksi yang terkait dengannya:

  • Dapatkan pengidentifikasi untuk peserta jarak jauh ini. Identitas adalah salah satu jenis 'Pengidentifikasi'

    CommunicationIdentifier participantIdentifier = remoteParticipant.getIdentifier();
    
  • Dapatkan status peserta jarak jauh ini.

    ParticipantState state = remoteParticipant.getState();
    

Status bisa menjadi salah satu dari

  • 'IDLE' - status awal

  • 'EARLY_MEDIA' - pengumuman diputar sebelum peserta tersambung ke panggilan

  • 'RINGING' - panggilan peserta berdering

  • 'CONNECTING' - status transisi saat peserta tersambung ke panggilan

  • 'CONNECTED' - peserta tersambung ke panggilan

  • 'HOLD' - peserta ditangguhkan

  • 'IN_LOBBY' - peserta menunggu di lobi untuk diterima. Saat ini hanya digunakan dalam skenario interop Teams

  • 'DISCONNECTED' - status akhir - peserta terputus dari panggilan

  • Untuk mengetahui alasan peserta meninggalkan panggilan, periksa properti callEndReason:

    CallEndReason callEndReason = remoteParticipant.getCallEndReason();
    
  • Untuk memeriksa apakah peserta jarak jauh ini dibisukan atau tidak, periksa properti isMuted:

    boolean isParticipantMuted = remoteParticipant.isMuted();
    
  • Untuk memeriksa apakah peserta jarak jauh ini berbicara atau tidak, periksa properti isSpeaking:

    boolean isParticipantSpeaking = remoteParticipant.isSpeaking();
    
  • Untuk memeriksa semua aliran video yang dikirim peserta tertentu dalam panggilan ini, periksa koleksi videoStreams:

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

Menggunakan Layanan Latar Depan

Jika Anda ingin menjalankan tugas yang dapat dilihat pengguna meski saat aplikasi Anda berjalan di latar belakang, Anda dapat menggunakan Layanan Latar Depan.

Misalnya, dengan Layanan Latar Depan, Anda dapat mempertahankan pemberitahuan yang dapat dilihat pengguna saat aplikasi memiliki panggilan aktif. Dengan demikian, meski pengguna membuka layar utama atau menghapus aplikasi dari layar baru-baru ini, panggilan akan tetap aktif.

Jika Anda tidak menggunakan Layanan Latar Depan saat dalam panggilan, membuka layar utama dapat menjaga panggilan tetap aktif, tetapi menghapus aplikasi dari layar baru-baru ini dapat menghentikan panggilan jika OS Android menghentikan proses aplikasi Anda.

Anda harus memulai Layanan Latar Depan saat memulai/bergabung ke panggilan, misalnya:

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

Dan menghentikan Layanan Latar Depan saat Anda menutup panggilan atau status panggilan Terputus, misalnya:

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

Catatan tentang penggunaan Layanan Latar Depan

Perhatikan bahwa skenario seperti menghentikan Layanan Latar Depan yang sudah berjalan saat aplikasi dihapus dari daftar baru-baru ini, akan menghapus pemberitahuan yang dapat dilihat pengguna dan OS Android dapat menjaga proses aplikasi tetapi aktif Anda selama periode tambahan, yang berarti bahwa panggilan masih dapat aktif selama periode tersebut.

Jika aplikasi Anda menghentikan Layanan Latar Depan pada metode layanan onTaskRemoved misalnya, aplikasi Anda dapat memulai/menghentikan audio dan video sesuai dengan Siklus Hidup Aktivitas seperti menghentikan audio dan video saat aktivitas Anda dihentikan dengan penggantian metode onDestroy.

Siapkan sistem Anda

Buat proyek Xcode

Di Xcode, buat proyek iOS baru dan pilih templat Single View App. Tutorial ini menggunakan kerangka kerja SwiftUI, jadi Anda harus mengatur Bahasa pemrograman ke Swift dan Antarmuka Pengguna ke SwiftUI.

Anda tidak akan membuat tes unit selama proses mulai cepat ini. Jangan ragu untuk menghapus kotak teks Sertakan Tes Unit dan Sertakan Tes UI.

Cuplikan layar yang memperlihatkan jendela untuk membuat proyek dalam Xcode.

Menginstal paket dan dependensi dengan CocoaPods

  1. Buat Podfile untuk aplikasi Anda, seperti ini:

    platform :ios, '13.0'
    use_frameworks!
    target 'AzureCommunicationCallingSample' do
        pod 'AzureCommunicationCalling', '~> 1.0.0'
    end
    
  2. Jalankan pod install.

  3. Buka .xcworkspace dengan Xcode.

Meminta akses ke mikrofon

Untuk mengakses mikrofon perangkat, Anda perlu memperbarui daftar properti informasi aplikasi Anda dengan NSMicrophoneUsageDescription. Anda mengatur nilai yang terkait ke string yang akan disertakan dalam dialog yang digunakan sistem untuk meminta akses dari pengguna.

Klik kanan Info.plist entri pohon proyek dan pilih Buka Sebagai>Kode Sumber. Tambahkan baris berikut ke bagian <dict> tingkat atas, lalu simpan file.

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

Siapkan kerangka kerja aplikasi

Buka file ContentView.swift proyek Anda dan tambahkan import deklarasi ke bagian atas file untuk diimpor ke AzureCommunicationCalling pustaka. Selain itu, impor AVFoundation. Anda akan memerlukannya untuk permintaan izin audio dalam kode.

import AzureCommunicationCalling
import AVFoundation

Inisialisasi CallAgent

Untuk membuat CallAgent instans dari CallClient, Anda harus menggunakan callClient.createCallAgent metode yang secara asinkron mengembalikan CallAgent objek setelah diinisialisasi.

Untuk membuat klien panggilan, Anda harus meneruskan CommunicationTokenCredential objek.

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

Berikan CommunicationTokenCredential objek yang Anda buat ke CallClient, dan atur nama tampilan.

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

Catatan

Ketika aplikasi menerapkan delegasi peristiwa, aplikasi harus memiliki referensi yang kuat ke objek yang memerlukan langganan peristiwa. Misalnya, ketika RemoteParticipant objek dikembalikan pada pemanggilan call.addParticipant metode dan aplikasi menetapkan delegasi untuk mendengarkan RemoteParticipantDelegate, aplikasi harus memegang referensi yang kuat ke RemoteParticipant objek. Jika tidak, jika objek ini dikumpulkan, delegasi akan melemparkan pengecualian fatal ketika Calling SDK mencoba memanggil objek.

Melakukan panggilan keluar

Untuk membuat dan memulai panggilan, Anda perlu memanggil salah satu API CallAgent dan memberikan identitas Azure Communication Services pengguna yang telah Anda sediakan dengan menggunakan Communication Services Management SDK.

Pembuatan dan permulaan panggilan bersifat sinkron. Anda akan menerima instans panggilan yang memungkinkan Anda berlangganan semua peristiwa di panggilan.

Lakukan panggilan 1:1 ke pengguna atau panggilan 1:n dengan pengguna dan PSTN

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

Melakukan panggilan 1:n dengan pengguna dan PSTN

Untuk melakukan panggilan ke PSTN, Anda harus menentukan nomor telepon yang diperoleh dengan Azure 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")
     }
}

Bergabung ke panggilan grup

Untuk bergabung dalam panggilan, Anda perlu menghubungi salah satu API diCallAgent.

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

Berlangganan panggilan masuk

Berlangganan peristiwa panggilan masuk.

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

Menerima panggilan masuk

Untuk menerima panggilan, hubungi accept metode pada IncomingCall objek.

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

Melakukan operasi selama panggilan

Anda dapat melakukan berbagai operasi selama panggilan untuk mengelola pengaturan yang terkait dengan video dan audio.

Mematikan suara dan menyalakan suara

Untuk mematikan atau menyalakan suara titik akhir lokal, Anda dapat menggunakan mute dan unmute API asinkron.

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

Gunakan kode berikut untuk menyalakan suara titik akhir lokal secara asinkron.

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

Kelola peserta jarak jauh

Semua peserta jarak jauh diwakili oleh RemoteParticipant jenis dan tersedia melalui remoteParticipants koleksi pada instans panggilan.

Mencantumkan peserta dalam panggilan

call.remoteParticipants

Menambahkan peserta ke panggilan

Untuk menambahkan peserta ke panggilan (baik pengguna atau nomor telepon) Anda dapat memanggil addParticipant. Tindakan ini akan secara sinkron mengembalikan instans peserta jarak jauh.

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

Hapus peserta dari panggilan

Untuk menghapus peserta dari panggilan (pengguna atau nomor telepon), Anda bisa memanggil removeParticipant API. Ini akan menyelesaikan secara asinkron.

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

Dapatkan properti peserta jarak jauh

// [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, ...]

Persiapan

Membuat proyek Visual Studio

Untuk aplikasi UWP, di Visual Studio 2019, buat proyek baru Blank App (Universal Windows) . Setelah memasukkan nama proyek, jangan ragu untuk memilih Windows SDK apa pun yang lebih besar dari 10.0.17134.

Untuk aplikasi WinUI 3, buat proyek baru dengan Blank App, Packaged (WinUI 3 in Desktop) templat untuk menyiapkan aplikasi WinUI 3 satu halaman. SDK Aplikasi Windows versi 1.2 pratinjau 2 ke atas diperlukan.

Pasang paket dan dependensi dengan NuGet Package Manager

API dan pustaka SDK Panggilan tersedia untuk umum melalui paket NuGet. Langkah-langkah berikut mencontohkan cara menemukan, mengunduh, dan memasang paket NuGet SDK Panggilan.

  1. Buka Manajer Paket NuGet (Tools ->NuGet Package Manager ->Manage NuGet Packages for Solution)
  2. Klik Browse lalu ketik Azure.Communication.Calling di kotak pencarian.
  3. Pastikan kotak centang Include prerelease dipilih.
  4. Klik pada Azure.Communication.Calling paket, pilih Azure.Communication.Calling1.0.0-beta.33 atau versi yang lebih baru.
  5. Pilih kotak centang yang terkait dengan proyek CS pada tab sisi kanan.
  6. Klik tombol Install.

Meminta akses ke mikrofon

Aplikasi ini akan memerlukan akses ke mikrofon untuk berjalan dengan benar. Di aplikasi UWP, kemampuan mikrofon harus dideklarasikan dalam file manifes aplikasi. Langkah-langkah berikut mencontohkan cara mencapai hal tersebut.

  1. Di panel Solution Explorer, klik dua kali pada file bernama .appxmanifest.
  2. Klik tab Capabilities.
  3. Pilih kotak centang Microphone dari daftar kapabilitas.

Membuat tombol UI untuk membuat dan menutup panggilan

Aplikasi sampel sederhana ini akan berisi dua tombol. Satu untuk membuat panggilan dan yang lain untuk menutup panggilan. Langkah-langkah berikut mencontohkan cara menambahkan tombol ini ke aplikasi.

  1. Di panel Solution Explorer , klik dua kali pada file bernama MainPage.xaml untuk UWP, atau MainWindows.xaml untuk WinUI 3.
  2. Di panel tengah, cari kode XMAL di bawah pratinjau UI.
  3. Ubah kode XAML dengan kutipan berikut:
<TextBox x:Name="CalleeTextBox" Text="Who would you like to call?" TextWrapping="Wrap" VerticalAlignment="Center" Grid.Row="0" Height="40" Margin="10,10,10,10" />
<StackPanel Orientation="Horizontal">
    <Button x:Name="CallButton" Content="Start Call" Click="CallButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="200"/>
    <Button x:Name="HangupButton" Content="Hang Up" Click="HangupButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="200"/>
</StackPanel>

Menyiapkan aplikasi dengan API SDK Panggilan

API SDK Panggilan berada di dua namespace layanan yang berbeda. Langkah-langkah berikut menginformasikan pengompilasi C# tentang namespace layanan ini yang memungkinkan Intellisense Visual Studio membantu pengembangan kode.

  1. Di panel Solution Explorer , klik panah di sisi kiri file bernama MainPage.xaml untuk UWP, atau MainWindows.xaml untuk WinUI 3.
  2. Klik dua kali pada file bernama MainPage.xaml.cs atau MainWindows.xaml.cs.
  3. Tambahkan perintah berikut di bagian bawah pernyataan using saat ini.
using Azure.Communication;
using Azure.Communication.Calling;

Silakan simpan MainPage.xaml.cs atau MainWindows.xaml.cs buka. Langkah-langkah berikutnya akan menambahkan lebih banyak kode ke dalamnya.

Mengizinkan interaksi aplikasi

Tombol UI yang sebelumnya ditambahkan perlu dioperasikan di atas Call. Ini berarti bahwa Call anggota data harus ditambahkan ke MainPage kelas atau MainWindow . Selain itu, untuk memungkinkan operasi asinkron yang membuat CallAgent berhasil, data anggota CallAgent juga harus ditambahkan ke kelas yang sama.

Tambahkan anggota data berikut ke MainPage kelas pr MainWindow :

CallAgent callAgent;
Call call;

Membuat pengatur tombol

Sebelumnya, dua tombol UI ditambahkan ke kode XAML. Kode berikut menambahkan pengatur untuk dieksekusi saat pengguna memilih tombol. Kode berikut harus ditambahkan setelah anggota data dari bagian sebelumnya.

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

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

Model objek

Kelas dan antarmuka berikut menangani beberapa fitur utama dari pustaka klien Panggilan Azure Communication Services untuk UWP.

Nama Deskripsi
CallClient CallClient adalah titik masuk utama ke pustaka klien Panggilan.
CallAgent CallAgent digunakan untuk memulai dan bergabung dalam panggilan.
Call Call digunakan untuk mengelola atau bergabung dalam panggilan.
CommunicationTokenCredential CommunicationTokenCredential digunakan sebagai info masuk token untuk membuat instans CallAgent.
CallAgentOptions CallAgentOptions berisi informasi untuk mengidentifikasi penelepon.
HangupOptions HangupOptions menginformasikan kepada semua pesertanya apakah panggilan harus diakhiri.

Menginisialisasi CallAgent

Untuk membuat instans CallAgent dari CallClient Anda harus menggunakan metode CallClient.CreateCallAgent yang secara asinkron mengembalikan objek CallAgent setelah diinisialisasi.

Untuk membuat CallAgent, Anda harus melewati objek CommunicationTokenCredential dan objek CallAgentOptions. Perlu diingat bahwa CommunicationTokenCredential melempar jika token cacat dilewati.

Kode berikut harus ditambahkan di dalam dan fungsi pembantu untuk dipanggil dalam inisialisasi aplikasi.

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

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

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

<AUTHENTICATION_TOKEN> harus diganti dengan token info masuk yang valid untuk sumber daya Anda. Lihat dokumentasi token akses pengguna jika token info masuk harus bersumber.

Membuat CallAgent dan melakukan panggilan

Objek yang diperlukan untuk membuat CallAgent sekarang siap. Sudah waktunya untuk secara asinkron membuat CallAgent dan melakukan panggilan.

Kode berikut harus ditambahkan setelah menangani pengecualian dari langkah sebelumnya.

var startCallOptions = new StartCallOptions();

var callees = new ICommunicationIdentifier[1] { new CommunicationUserIdentifier(CalleeTextBox.Text.Trim()) };

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

Jangan ragu untuk menggunakan 8:echo123 untuk berbicara dengan bot gema Azure Communication Services.

Mengakhiri panggilan

Setelah panggilan dilakukan, metode HangupAsync objek Call harus digunakan untuk menutup panggilan.

Instans HangupOptions juga harus digunakan untuk menginformasikan apakah panggilan harus diakhiri kepada semua pesertanya.

Kode berikut harus ditambahkan di dalam HangupButton_Click.

this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions());

Jalankan kode

Pastikan Visual Studio akan membuat aplikasi untuk x64, x86, atau ARM64, lalu tekan F5 untuk mulai menjalankan aplikasi. Setelah itu, klik tombol Call untuk melakukan panggilan ke penerima panggilan yang ditentukan.

Perlu diingat bahwa pertama kali aplikasi berjalan, sistem akan meminta pengguna untuk memberikan akses ke mikrofon.

Langkah berikutnya