C++ PJSUA2-在Windows中使用空音频录制对WAV的调用

C++ PJSUA2-在Windows中使用空音频录制对WAV的调用,c++,wav,pjsip,pjsua2,C++,Wav,Pjsip,Pjsua2,我现在开始使用PJSUA2。我想开发一个接受呼叫的SIP客户端。当它接受呼叫时,我播放一个WAV文件,并将输入记录到一个WAV文件中。PJSIP不会检测我的默认音频设备,但这很好,因为我无论如何都不想使用它们,所以我通过audDevManager().setNullDev()选择NullAudio 这是我的电话号码: class MyCall : public Call { public: AudioMediaPlayer player; AudioMediaRecorder recorder;

我现在开始使用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;
    }
}
类MyCall:公共调用{
公众:
音频媒体播放器;
音频媒体记录器;
音频媒体记录器Recorderify;
MyCall(帐户和帐户,int call\u id=PJSUA\u无效\u id)
:呼叫(acc,呼叫id)
{ }
void MyCall::onCallState(OnCallStateParam&prm)
{

这只是一个猜测

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

当第二次为第二次邀请请求调用
onCallMediaState
时,您正在尝试

player.createPlayer("Ring02.wav", PJMEDIA_FILE_NO_LOOP);
recorder.createRecorder("in.wav");
recorderVerify.createRecorder("test.wav");
这将抛出,因为它们已经被创建。如果我是对的,你的日志必须有错误通知。所以你不能

aud_med->startTransmit(recorder);

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

您是否发现了问题所在?不太可能。我没有让它运行,并继续进行其他不涉及SIP的项目。但如果您有任何想法,我想返回并尝试一下.