2

I'm currently starting to work with PJSUA2. I want to develop an SIP client that accepts calls. When it accepts a call, I play a WAV file and record the input to a WAV file as well. PJSIP does not detect my default audio devices, but that's fine since I don't want to use them anyway, so I go for NullAudio via audDevManager().setNullDev().

Here's the code of my call:

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;
    }
}

};

I already made the player and recorder member variables based upon PJSUA2 - Recording call audio to wav file. Now I can correctly play a WAV file to the caller and I also can record my own WAV file via recorderVerify. But the audio from the caller is not recorded, but the generated WAV file is silence instead.

Do I need to initialize something or what did I miss? Thanks a lot for your help!

Community
  • 1
  • 1
Niels
  • 223
  • 4
  • 14
  • Did you ever find out what was wrong? – Roman Nov 24 '17 at 12:43
  • Unfotunately not. I didn't get it to run and went on with other projects that didn't involve SIP. But if you have any idea, I would like to return to it and give it a try. – Niels Nov 27 '17 at 08:11

1 Answers1

2

That is just a wild guess.

When PJSUA sends second INVITE request right after first OK was received, which it does in in-dialog mode (you can check that with wireshark), onCallMediaState is called second time and, if for some reason parties agreed on some another codec, not that that was the first time, there could be another getMedia(i) object, and the first original one could be destroyed. In that case recorder just stops recording and you get WAV one second long.

When onCallMediaState is called second time for second INVITE request, you are trying to

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

which will throw, because they've been already created. If I am right, your log has to have that error notice. So you don't get to

aud_med->startTransmit(recorder);

to continue recording, therefore your WAV contains fraction of second long record of a conversation, before session was re-initialized.

Roman
  • 1,946
  • 3
  • 20
  • 28