PJSUA2 — запись звонка в WAV в Windows с помощью Null-Audio

Я сейчас начинаю работать с PJSUA2. Я хочу разработать SIP-клиент, который принимает звонки. Когда он принимает вызов, я играю WAV-файл и также записываю ввод в WAV-файл. PJSIP не определяет мои аудиоустройства по умолчанию, но это нормально, так как я все равно не хочу их использовать, поэтому я выбираю NullAudio через audDevManager (). SetNullDev ().

Вот код моего звонка:

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 — запись аудио звонка в файл wav. Теперь я могу правильно воспроизвести файл WAV для вызывающего абонента, а также записать свой собственный файл WAV через устройство записи Verify. Но звук от звонящего не записывается, а сгенерированный WAV-файл — это тишина.

Нужно ли что-то инициализировать или что я пропустил? Большое спасибо за вашу помощь!

2

Решение

Это просто дикая догадка.

Когда PJSUA отправляет второй запрос INVITE сразу после получения первого OK, что он делает в диалоговом режиме (это можно проверить с помощью 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 содержит долю секунды длинной записи разговора, прежде чем сеанс был повторно инициализирован.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]