CXPlayDTMFCallAction 不播放本地 dtmf 声音

CXPlayDTMFCallAction doesn't play local dtmf sound

我正在将 CallKit 与 VOIP 应用集成。我能够拨入和拨出电话。我按照以下步骤操作:

  1. 配置音频会话
  2. 在 (didActivate) 中启动音频
  3. 在 (didDeActivate) 中停止音频

我已经实现了 DTMF 提供商委托的回调,如下所示:

func provider(_ provider: CXProvider, perform action: CXPlayDTMFCallAction) {
    print("Provider - CXPlayDTMFCallAction")

    let dtmfDigts:String = action.digits

    for (index, _) in dtmfDigts.characters.enumerated() {
        let dtmfDigit = dtmfDigts.utf8CString[index]
        print("Processing dtmfDigit:\(dtmfDigit)" )
        self.softphone.dtmf(on:dtmfDigit)
    }

    self.softphone.dtmfOff()

    // Signal to the system that the action has been successfully performed.
    action.fulfill()
}

在通话过程中,当我在本机通话 UI 上按数字时,我听不到按键音,即本地 dtmf 声音。

来自https://developer.apple.com/reference/callkit/cxplaydtmfcallaction

"CallKit automatically plays the corresponding DTMF frequencies for any digits transmitted over a call. The app is responsible for managing the timing and handling of digits as part of fulfilling the action."

这是已知问题还是 callkit 不播放本地 dtmf 按键音?

CallKit 应该在本地通话 UI 的 'keypad' 按钮中按下按键时在本地播放 DTMF 音调。但是 CallKit 应用程序负责通过其自己的网络接口将 DTMF 音调发送到远程端。

如果您在本机通话中听不到本地播放的音调 UI 那么请 report a bug 到 Apple。

我是通过以下方式让它工作的:

func provider(_ provider: CXProvider, perform action: CXPlayDTMFCallAction) {
    print("Provider - CXPlayDTMFCallAction")

    self.softphone.audioController.configureAudioSession()

    let dtmfDigts:String = action.digits

    for (index, _) in dtmfDigts.characters.enumerated() {
        let dtmfDigit = dtmfDigts.utf8CString[index]
        print("Processing dtmfDigit:\(dtmfDigit)" )
        self.softphone.dtmf(on:dtmfDigit)
    }

    self.softphone.dtmfOff()

    // Signal to the system that the action has been successfully performed.
    action.fulfill()
}

注意:我添加了self.softphone.audioController.configureAudioSession()。

-(void) configureAudioSession
{
    // Configure the audio session
    AVAudioSession *sessionInstance = [AVAudioSession sharedInstance];

    // we are going to play and record so we pick that category
    NSError *error = nil;
    [sessionInstance setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
    if (error) {
        NSLog(@"error setting audio category %@",error);
    }

    // set the mode to voice chat
    [sessionInstance setMode:AVAudioSessionModeVoiceChat error:&error];
    if (error) {
        NSLog(@"error setting audio mode %@",error);
    }

    NSLog(@"setupAudioSession");

    return;
}