PJSUA2 - 使用Null-Audio在Windows中录制对WAV的呼叫

时间:2017-02-20 15:07:42

标签: c++ wav pjsip pjsua2

我目前正在开始使用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制作了播放器和录音机成员变量。现在我可以正确地向调用者播放WAV文件,我也可以通过recorderVerify录制我自己的WAV文件。但是没有记录来自呼叫者的音频,但生成的WAV文件却是静音。

我是否需要初始化某些内容或我错过了哪些内容?非常感谢你的帮助!

1 个答案:

答案 0 :(得分:1)

这只是一个疯狂的猜测。

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

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

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

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

aud_med->startTransmit(recorder);

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