通話の保留処理

Vonage Client SDK には、専用の「保留」API は用意されていません。その代わりに、 「ホールド」は、「ミュート」と「イヤーマフ」を組み合わせた形で実装されています:

  • mute(callId) — 相手側への音声送信を停止します
  • enableEarmuff(callId) — 相手側からの音声の受信が停止する

へ ホールド解除, 両方を反転:call unmute(callId) そして disableEarmuff(callId).

iOS および Android では、システムコール UI(CallKit / Telecom フレームワーク)がネイティブの保留ボタンを提供しています。以下のプラットフォームガイドでは、そのボタンを SDK の「ミュート」および「イヤーマフ」機能に紐付ける方法について説明しています。

このガイドでは、当社のVoIP SDKを使用して、iOSおよびAndroid Applicationsに通話保留機能を実装する手順について解説します。

現在、Web SDKでは通話保留機能はサポートされていません。

通信システムの統合

このチュートリアルを始める前に、アプリケーションにAndroid Telecomフレームワークが組み込まれていることを確認してください。

公式ガイドに従ってください これ または、当社のAndroid用音声サンプルアプリをお試しください これ.

接続の実装によるサポートの維持

のインプリメンテーションを構築したら、 接続 class, 次のコードを追加する必要があります。 CAPABILITY_SUPPORT_HOLD 接続機能に対して および onHold() そして onUnhold() のメソッドがある。

以下はKotlinでの例です:

class CallConnection(val callId: CallId) : Connection() {
    private lateinit var clientManager: VoiceClientManager
    var isOnHold = false
        private set

    init {
        connectionProperties = connectionProperties or PROPERTY_SELF_MANAGED
        connectionCapabilities = connectionCapabilities or CAPABILITY_SUPPORT_HOLD /** add other capabilities */
        audioModeIsVoip = true
    }

    // ... Other methods ...

    override fun onHold() {
        if (!isOnHold) {
            clientManager.holdCall(this)
        }
    }

    override fun onUnhold() {
        if (isOnHold) {
            clientManager.unholdCall(this)
        }
    }

    fun toggleHoldState() {
        isOnHold = !isOnHold
        if (isOnHold) setOnHold() else setActive()
    }
}

Voice SDK との連携

通話の保留状態を実装するには、以下を有効にしてください。 ミュート そして 耳当て 同時に。

以下のコードは、 VoiceClientManager このクラスはそれを示しています:

class VoiceClientManager(private val context: Context) {
    private lateinit var client : VoiceClient

    fun holdCall(call: CallConnection){
        call.apply{
            client.mute(callId){ error ->
                error?.let {
                    println("Error muting when holding call with id: $callId")
                } ?: run {
                    client.enableEarmuff(callId){ error ->
                        error?.let {
                            println("Error enabling earmuff when holding with id: $callId")
                        } ?: run {
                            println("Call $callId successfully put on hold")
                            toggleHoldState()
                        }
                    }
                }
            }
        }
    }

    fun unholdCall(call: CallConnection){
        call.apply{
            client.unmute(callId){ error ->
                error?.let {
                    println("Error unmuting when unholding call with id: $callId")
                } ?: run {
                    client.disableEarmuff(callId){ error ->
                        error?.let {
                            println("Error disabling earmuff unholding call with id: $callId")
                        } ?: run {
                            println("Call $callId successfully removed from hold")
                            toggleHoldState()
                        }
                    }
                }
            }
        }
    }
}

具体的な実装や要件に合わせて、コードスニペットを自由に調整してください。

Callkitとの連携

このチュートリアルを始める前に、アプリケーションにCallkitフレームワークが組み込まれていることを確認してください。

以下の手順に従うことができます。 公式ガイド、または、当社のiOS用音声サンプルアプリをお試しください。 これ.

CXUpdate によるサポートの維持

一度構築したら、 CallController クラスで、aへの参照を保持している CXProvider そして CXCallController 以下の設定を有効にする必要があります。 supportsHolding のフラグ CXCallUpdate 発信および着信の両方について。

以下はSwiftでの例です:

import CallKit

class CallController {
    let callProvider: CXProvider
    let cxController = CXCallController()

    // ... Other methods ...

    func reportOutgoingCall(callId: String){
        self.callProvider.reportOutgoingCall(with: callId, connectedAt: Date.now)
        let update = CXCallUpdate()
        /** add other capabilities */
        update.supportsHolding = true
        self.callProvider.reportCall(with: callId, updated: update)
    }

    func reportIncomingCall(callId: String){
        let update = CXCallUpdate()
        /** add other capabilities */
        update.supportsHolding = true
        self.callProvider.reportNewIncomingCall(with: callId, update: update)
    }
}

Voice SDK との連携

一度構築したら、 CXProviderDelegate 実装、 次の内容に耳を傾けてください。 CXSetHeldCallAction Voice SDK を使用して通話を保留にする。

通話の保留状態を実装するには、以下を有効にしてください。 ミュート そして 耳当て 同時に。

以下のコードは、 CallController このクラスはそれを示しています:

import VonageClientSDKVoice

class CallController: NSObject {
    let callProvider: CXProvider
    let cxController = CXCallController()
    let client: VGVoiceClient
    var activeCalls: [UUID: String] = [:] // Maps CallKit UUID to Vonage callId

    // ... initialization and other methods ...
}

extension CallController: CXProviderDelegate {

    func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction) {
        guard let callId = self.activeCalls[action.callUUID] else {
            action.fail()
            return
        }
        if action.isOnHold {
            self.client.mute(callId) { error in
                if let error = error {
                    print("Error muting when holding call: \(error)")
                    return
                }
                self.client.enableEarmuff(callId) { error in
                    if let error = error {
                        print("Error enabling earmuff when holding call: \(error)")
                        return
                    }
                    print("Call \(callId) successfully put on hold")
                }
            }
        } else {
            self.client.unmute(callId) { error in
                if let error = error {
                    print("Error unmuting when unholding call: \(error)")
                    return
                }
                self.client.disableEarmuff(callId) { error in
                    if let error = error {
                        print("Error disabling earmuff when unholding call: \(error)")
                        return
                    }
                    print("Call \(callId) successfully removed from hold")
                }
            }
        }
        // CallKit requires fulfilling the action synchronously
        action.fulfill()
    }
}

具体的な実装や要件に合わせて、コードスニペットを自由に調整してください。