2

我目前正在开始使用 PJSUA2。我想开发一个接受呼叫的 SIP 客户端。当它接受呼叫时,我播放 WAV 文件并将输入记录到 WAV 文件中。PJSIP 没有检测到我的默认音频设备,但这很好,因为我不想使用它们,所以我通过 audDevManager().setNullDev() 选择 NullAudio。

这是我的通话代码:

class MyCall : public Call {
public:
AudioMediaPlayer player;
AudioMediaRecorder recorder;
AudioMediaRecorder recorderVerify;

MyCall(Account &acc, int call_id = PJSUA_INVALID_ID)
: Call(acc, call_id)
{ }

void MyCall::onCallState(OnCallStateParam &prm)
{
    cout << "!!!!!   onCallState is called   !!!!!" << endl;
    CallInfo ci = getInfo();
    cout << "ci.state = " << ci.state << endl;
    if (ci.state == PJSIP_INV_STATE_DISCONNECTED) {
        delete this;
    }
}

void MyCall::onCallMediaState(OnCallMediaStateParam &prm){
    cout << "!!!!!      onCallMediaState is called     !!!!!" << endl;

    try{
        player.createPlayer("Ring02.wav", PJMEDIA_FILE_NO_LOOP);
        recorder.createRecorder("in.wav");
        recorderVerify.createRecorder("test.wav");
        CallInfo ci = getInfo();
        AudioMedia* aud_med = 0;
        // Iterate all the call medias
        for (unsigned i = 0; i < ci.media.size(); i++) {
            cout << "Check audio " << i << endl;
            if (ci.media[i].type==PJMEDIA_TYPE_AUDIO && getMedia(i)) {
                aud_med = static_cast<AudioMedia*>( getMedia(i));
                break;
            }
        }
        if (aud_med != 0){
            cout << "Send stuff to media" << endl;

            // Connect the call audio media to sound device
            AudDevManager& mgr = Endpoint::instance().audDevManager();
            player.startTransmit(*aud_med);
            aud_med->startTransmit(recorder);
            player.startTransmit(recorderVerify);
        }

    } catch (Error& err) {
        cout << "Error when playing: " << err.info() << endl;
    }
}

};

我已经根据PJSUA2 - Recording call audio to wav file制作了 player 和 recorder 成员变量。现在我可以正确地向调用者播放 WAV 文件,并且我还可以通过 recorderVerify 录制我自己的 WAV 文件。但是没有记录来电者的音频,而是生成的 WAV 文件是静音的。

我需要初始化一些东西还是我错过了什么?非常感谢你的帮助!

4

1 回答 1

2

这只是一个疯狂的猜测。

当 PJSUA 在收到第一个 OK 后立即发送第二个 INVITE 请求时,它在对话模式下执行(您可以使用 wireshark 检查),onCallMediaState被第二次调用,如果由于某种原因各方同意另一个编解码器,不是那个是第一次,可能会有另一个getMedia(i)对象,而第一个原始对象可能会被破坏。在那种情况下,录音机只是停止录音,而你会得到一秒钟的 WAV。

onCallMediaState第二次 INVITE 请求被第二次调用时,您正在尝试

player.createPlayer("Ring02.wav", PJMEDIA_FILE_NO_LOOP);
recorder.createRecorder("in.wav");
recorderVerify.createRecorder("test.wav");

这会抛出,因为它们已经被创建了。如果我是对的,您的日志必须有该错误通知。所以你无法到达

aud_med->startTransmit(recorder);

继续录制,因此在会话重新初始化之前,您的 WAV 包含会话的第二长记录的一小部分。

于 2017-11-27T13:41:37.277 回答