LINUX.ORG.RU

pjsua2 нету звука! первые шаги

 , ,


0

3

Добрый день нужно написать консольную программу(Qt,c++) чтобы делала звонки по sip. Установил pjsua2(pjsip). Далее использую демо программу пытаюсь позвонить. Аккаунт регистрирует и звонок идет , но нету звука. Пробовал и записывать в файл и проигрывать фал - тишина. Опыта ноль. Поэтому прошу помощи.

        // Init library
        EpConfig ep_cfg;
        ep_cfg.logConfig.level = 4;
        ep.libInit( ep_cfg );

        // Transport
        TransportConfig tcfg;
        tcfg.port = 5080;      
        ep.transportCreate(PJSIP_TRANSPORT_UDP, tcfg);

        // Start library
        ep.libStart();
        std::cout << "*** PJSUA2 STARTED ***" << std::endl;

        // Add account
        AccountConfig acc_cfg;
        acc_cfg.idUri = "sip:user7@mangosip.ru";
        acc_cfg.regConfig.registrarUri = "sip:mangosip.ru";
        acc_cfg.sipConfig.authCreds.push_back( AuthCredInfo("digest", "*","login", 0, "password") );
        std::auto_ptr<MyAccount> acc(new MyAccount);
        acc->create(acc_cfg);

        pj_thread_sleep(2000);

        // Make outgoing call
        Call *call = new MyCall(*acc);
        acc->calls.push_back(call);
        CallOpParam prm(true);
        prm.opt.audioCount = 1;
        prm.opt.videoCount = 0;
        call->makeCall("sip:user8@mangosip.ru", prm);



        AudioMedia& cap_med = Endpoint::instance().audDevManager().getCaptureDevMedia();
        AudioMedia& play_med = Endpoint::instance().audDevManager().getPlaybackDevMedia();

        CallInfo ci = call->getInfo();
        AudioMedia *aud_med = NULL;

        // Find out which media index is the audio
        for (unsigned i=0; i<ci.media.size(); ++i) {
            if (ci.media[i].type == PJMEDIA_TYPE_AUDIO) {
                aud_med = (AudioMedia *)call->getMedia(i);
                break;
            }
        }

        if (aud_med) {
            // This will connect the sound device/mic to the call audio media
            cap_med.startTransmit(*aud_med);

            // And this will connect the call audio media to the sound device/speaker
            aud_med->startTransmit(play_med);
        }



        AudioMediaRecorder recorder;

        try
        {
            recorder.createRecorder("/home/alexey/file.wav");
            cap_med.startTransmit(recorder);
        }
        catch(Error& err) {}


        pj_thread_sleep(8000);


        // Hangup all calls
        pj_thread_sleep(8000);
        ep.hangupAllCalls();
        pj_thread_sleep(4000);

        // Destroy library
        std::cout << "*** PJSUA2 SHUTTING DOWN ***" << std::endl;


    }

ошибка в консоли: sound_port.c EC suspended because of inactivity



Последнее исправление: cetjs2 (всего исправлений: 2)

Если честно, не вижу тут ни капли Qt. Ты, для начала, локализовал, где собственно проблема? Иначе помочь будет трудно. Кто знает, может твоя «пися2» использует какой-то кодек, который не поддерживается клиентом - вот и тишина. А может попробовать другую программу-клиент?

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от DELIRIUM

цитата с сайта pjsua2 is a new, objected oriented, C++ API created on top of PJSUA-LIB

alexey_s1985
() автор топика
Ответ на: комментарий от DELIRIUM

Ну та, что в sflphone (теперь уже ring) используется. Там, кстати, можно и посмотреть, как и что.

gag ★★★★★
()
Ответ на: комментарий от Usuychik

эксперимент провожу в локальной сети. Но естественно все звонки в дальнейшем будут наружу. Я просто принцип до конца понять не могу. Мне в идеале нужно чтобы я в GUI тыкал на телефонные номера а звонки шли с аппарата (cisco303). И входящие чтобы шли на аппарат но в GUI естественно предупреждение о звонке должно быть. Я вчера нахардкодил там немного и он стал проигрывать файл но не в трубку телефона а в динамик компа.

       
        CallInfo ci = call->getInfo();
        AudioMedia *aud_med = NULL;
        
        AudioMediaRecorder recorder;
        AudioMedia& cap_med = Endpoint::instance().audDevManager().getCaptureDevMedia();
        try
        {
            recorder.createRecorder("/hoem/alexey/file.wav");
            cap_med.startTransmit(recorder);
        }
        catch(Error& err) {}

        AudioMediaPlayer player;
        AudioMedia& play_med = Endpoint::instance().audDevManager().getPlaybackDevMedia();
        try
        {
            player.createPlayer("/home/alexey/file.wav");
            player.startTransmit(play_med);
        }
        catch(Error& err) {}



        // Find out which media index is the audio
        for (unsigned i=0; i<ci.media.size(); ++i)
        {
            if (ci.media[i].type == PJMEDIA_TYPE_AUDIO)
            {
                aud_med = (AudioMedia *)call->getMedia(i);
                break;
            }
        }

        if (aud_med)
        {
            // This will connect the sound device/mic to the call audio media
            cap_med.startTransmit(*aud_med);

            // And this will connect the call audio media to the sound device/speaker
            aud_med->startTransmit(play_med);
        }

alexey_s1985
() автор топика
Ответ на: комментарий от alexey_s1985

А у вас АТС есть? Если есть, то может проще в разы через ее API дергать. PJSIP нужна если ты хочешь в своем приложении обрабатывать звонки, а просто набрать номер и отправить на обычный телефон лучше через API вашей PBX

Usuychik
()

В общем посмотрел я твои темы — ты это для CRM пилишь, тогда подход у тебя в корне не верный. Пили интеграцию твоей CRM c какой-нибуть PBX — Asterisk или FreeSwitch к примеру. А PJSIP нужен, если ты захочешь свой софтофон написать.

Usuychik
()
Ответ на: комментарий от Usuychik

ну у меня сип провайдер все функции атс выполняет. Могу Asterisk поднять если что... мне бы кто помог со звуком )))))))

alexey_s1985
() автор топика
Ответ на: комментарий от alexey_s1985

Просто если в полседствии у тебя будет NAT, то отгребешь проблем немерянно. Мой совет остается прежним - пили интеграцию с АТС.

Usuychik
()
Ответ на: комментарий от alexey_s1985

А ты с SIP-телефонией вообще когда-то работал? Самое первое тебе нужно будет в твоем софте предусмотреть подмену адресов в SIP сообщениях.

Usuychik
()
Ответ на: комментарий от Usuychik

на уровне пользователя если только, иначе зачем я здесь). Кстати подправил прогу теперь звонит и записывает звонки в файл. На прием тоже работает но надо тогда код поменять. Мало ли кому нервы спасет кидаю:

#include <QCoreApplication>

    #include <pjsua2.hpp>
    #include <iostream>
    #include <memory>
    #include <pj/file_access.h>
#define THIS_FILE "main.cpp"

    using namespace pj;

    class MyAccount;

    class MyCall : public Call
    {
    private:
        MyAccount *myAcc;

    public:
        MyCall(Account &acc, int call_id = PJSUA_INVALID_ID)
        : Call(acc, call_id)
        {
            myAcc = (MyAccount *)&acc;
        }

        virtual void onCallState(OnCallStateParam &prm);//когда состояние вызова изменилось
        virtual void onCallMediaState(OnCallMediaStateParam &prm);//когда состояние микр или динамик изменилось
    };

    class MyAccount : public Account
    {
    public:
        std::vector<Call *> calls;

    public:
        MyAccount()
        {}

        ~MyAccount()
        {
            std::cout << "*** Account is being deleted: No of calls="
                      << calls.size() << std::endl;
        }

        void removeCall(Call *call)
        {
            for (std::vector<Call *>::iterator it = calls.begin();
                 it != calls.end(); ++it)
            {
                if (*it == call) {
                    calls.erase(it);
                    break;
                }
            }
        }

        virtual void onRegState(OnRegStateParam &prm)
        {
        AccountInfo ai = getInfo();
        std::cout << (ai.regIsActive? "*** Register: code=" : "*** Unregister: code=")
              << prm.code << std::endl;
        }

        virtual void onIncomingCall(OnIncomingCallParam &iprm)
        {
            Call *call = new MyCall(*this, iprm.callId);
            CallInfo ci = call->getInfo();
            CallOpParam prm;

            std::cout << "*** Incoming Call: " <<  ci.remoteUri << " [" << ci.stateText << "]" << std::endl;

            calls.push_back(call);
            prm.statusCode = (pjsip_status_code)200;
            call->answer(prm);
        }
    };

    void MyCall::onCallState(OnCallStateParam &prm)
    {
        PJ_UNUSED_ARG(prm);

        CallInfo ci = getInfo();
        std::cout << "*** Call: " <<  ci.remoteUri << " [" << ci.stateText
                  << "]" << std::endl;

        if (ci.state == PJSIP_INV_STATE_DISCONNECTED)
        {

            myAcc->removeCall(this);
            /* Delete the call */
            delete this;
        }
    }

    void MyCall::onCallMediaState(OnCallMediaStateParam &prm)
    {
        CallInfo ci = getInfo();

        // Iterate all the call medias
        for (unsigned i = 0; i < ci.media.size(); i++)
        {
            if (ci.media[i].type==PJMEDIA_TYPE_AUDIO && getMedia(i))
            {
                AudioMedia *aud_med = (AudioMedia *)getMedia(i);

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

            }
        }
    }




    static void mainProg1(Endpoint &ep) throw(Error)
    {
        // Init library
        EpConfig ep_cfg;
        ep_cfg.logConfig.level = 6;
        ep.libInit( ep_cfg );

        // Transport
        TransportConfig tcfg;
        tcfg.port = 5060;      //5080 mango
        ep.transportCreate(PJSIP_TRANSPORT_UDP, tcfg);

        // Start library
        ep.libStart();
        std::cout << "*** PJSUA2 STARTED ***" << std::endl;

        // Add account
        AccountConfig acc_cfg;
        acc_cfg.idUri = "sip:логин@сиппровайдер.ru";
        acc_cfg.regConfig.registrarUri = "sip:сиппровайдер.ru";
        acc_cfg.sipConfig.authCreds.push_back( AuthCredInfo("digest", "*","логин", 0, "пароль") );
        std::auto_ptr<MyAccount> acc(new MyAccount);
        acc->create(acc_cfg);

        pj_thread_sleep(2000);


        // Make outgoing call
        Call *call = new MyCall(*acc);
        acc->calls.push_back(call);
        CallOpParam prm(true);
        prm.opt.audioCount = 1;
        prm.opt.videoCount = 0;
        call->makeCall("sip:комузвоним@сиппровайдер.ru", prm);


        // Just wait for ENTER key
        std::cout << "Press ENTER to quit..." << std::endl;
        std::cin.get();



        CallInfo ci = call->getInfo();
        AudioMedia *aud_med = NULL;

        for (unsigned i=0; i<ci.media.size(); ++i)
        {
            if (ci.media[i].type == PJMEDIA_TYPE_AUDIO)
            {
                aud_med = (AudioMedia *)call->getMedia(i);
                break;
            }
        }



        AudioMediaRecorder recorder;
        AudioMedia& cap_med = Endpoint::instance().audDevManager().getCaptureDevMedia();
        try
        {
            recorder.createRecorder("/путь/куда/пишем/файл.wav");
            cap_med.startTransmit(recorder);
        }
        catch(Error& err) {
        }

        AudioMediaPlayer player;
        AudioMedia& play_med = Endpoint::instance().audDevManager().getPlaybackDevMedia();
        try
        {
            player.createPlayer("/путь/куда/пишем/файл.wav");
            player.startTransmit(play_med);
        }
        catch(Error& err) {
        }


        if (aud_med)
        {
            // This will connect the sound device/mic to the call audio media
            cap_med.startTransmit(*aud_med);
            // And this will connect the call audio media to the sound device/speaker
            aud_med->startTransmit(play_med);
        }

        pj_thread_sleep(20000); //пишем  20сек
      // потом вешаем трубку


         ep.hangupAllCalls();


        try
        {
            player.stopTransmit(play_med);
        }
        catch(Error& err) {
        }
        try
        {
           cap_med.stopTransmit(recorder);
        }
        catch(Error& err) {
        }



        pj_thread_sleep(1000);

        // Destroy library
        std::cout << "*** PJSUA2 SHUTTING DOWN ***" << std::endl;


 }



    int main()
    {
        int ret = 0;
        Endpoint ep;

        try
        {
            ep.libCreate();
            mainProg1(ep);
            ret = PJ_SUCCESS;
        }
        catch (Error & err)
        {
            std::cout << "Exception: " << err.info() << std::endl;
            ret = 1;
        }

        try
        {
            ep.libDestroy();
        }
            catch(Error &err)
        {
            std::cout << "Exception: " << err.info() << std::endl;
            ret = 1;
        }

        if (ret == PJ_SUCCESS)
        {
            std::cout << "Success" << std::endl;
        }
        else
        {
            std::cout << "Error Found" << std::endl;
        }

        return ret;
    }
ну вот дальше мне не понятно как звонок на мобильник сделать. Ты наверное про это и имел ввиду )

alexey_s1985
() автор топика
Ответ на: комментарий от Usuychik

все разобрался вот так на мобильные звонит и пишет) call->makeCall(«sip:7921*******@вашсип.ru», prm);

alexey_s1985
() автор топика
12 сентября 2018 г.
Ответ на: комментарий от alexey_s1985

Python 3.5

А нет ли такого готового под питон? что-то никак не могу разобраться с этим пыжом... Заранее спасибо если кто сможет выложить и помочь с проблемой...

anonymous
()
Ответ на: Python 3.5 от anonymous

линфон с пистон биндингом есть, гуглите

anonymous
()
Ответ на: Python 3.5 от anonymous

Я тоже ковыряю pjsua2 python3.6 - хотя 3.5 - 3.6 не суть важно. На С++ все намного проще, но нужно на питоне. Позвонить пока не получилось... есть подозрение что нужно отключить поддержку аудио девайсов через pjsua_set_null_snd_dev() - но никак не могу сделать это через pjsua2 или _pjsua2. Если кто разобрабрался с этим именно для питона черкните сюда плиз.

merlin-shadow
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.