Re: How to get the audio stream from PJSIP when there is no audio device hardware.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



pjsua sample app already has this feature. take a look pjsua manule http://www.pjsip.org/pjsua.htm and have a try

--null-audio        Use NULL audio device
  --rec-file=file     Open file recorder (extension can be .wav or .mp3
  --auto-rec          Automatically record conversation

On Sat, Sep 16, 2017 at 2:13 AM, James Doherty <james@xxxxxxxxxxxxxx> wrote:

Hello,

 

Thanks for a great product.

 

I want to use PJSIP's C API to record the incoming audio to a file on a machine with _no_ hardware sound device. I’ve read the FAQ and the PJMEDIA documentation but am still unclear about the architecture of bridges, media ports and sound devices.

 

My target machines, both Windows 10 and Linux, have no hardware audio devices installed, so I call pjsua_set_null_snd_dev() after initializing and starting the libraries. Example code below.

 

Later after I make a SIP call and it is answered I attempt to attach a WAV file writer to the DEFAULT_CAPTURE_DEV, but the pjmedia_aud_dev_default_param(…) call returns PJMEDIA_AUD_INVALID_DEV. 
 
Runing the code on a machine (either Win or Linux) _with_ a hardware sound device succeeds and things progress as I expect. Even though pjsua_set_null_snd_dev() is invoked. Absolutely no changes to the code.
 
Is there a resource I can consult so to understand this better?

 

James

 

/** Code **/

 

#include <pjlib.h>
#include <pjlib-util.h>
#include <pjnath.h>
#include <pjsip.h>
#include <pjsip_ua.h>
#include <pjsip_simple.h>
#include <pjsua-lib/pjsua.h>
#include <pjmedia.h>
#include <pjmedia-codec.h>
#include <pj/log.h>
#include <pj/os.h>
 
    int main(int, char **)
    {
    // Create pjsua first! 
            pj_status_t status = pjsua_create();
            if (status != PJ_SUCCESS)
            {
                fprintf(stderr,"pjsua_create error\n");
                return -1;
            }
 
    // Init pjsua 
            pjsua_config cfg;
            pjsua_logging_config log_cfg;
 
            pjsua_config_default(&cfg);
 
            pjsua_logging_config_default(&log_cfg);
            log_cfg.console_level = 4;
 
            status = pjsua_init(&cfg, &log_cfg, NULL);
            if (status != PJ_SUCCESS)
            {
                fprintf(stderr,"pjsua_init error\n");
                return -1;
            }
 
 
    // Proactively list known audio devices so we are sure there are NONE
            pjmedia_aud_dev_info info[64];
            unsigned info_count = 64;
            pjsua_enum_aud_devs(info, &info_count);
 
            fprintf(stderr,"Listing known sound devices, total of [%u]\n", info_count);
            for (unsigned i = 0; i<info_count; ++i)
            {
                fprintf(stderr,"Name [%s]", info[i].name);
            }
 
    // Add transport
            pjsua_transport_config tcfg;
            pjsua_transport_id trans_id;
            pjsua_transport_config_default(&tcfg);
            tcfg.port = 5060;
            status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &tcfg, &trans_id);
            if (status != PJ_SUCCESS)
            {
                fprintf(stderr, "pjsua_transport_create error\n");
                return -1;
            }
 
    // Initialization is done, now start pjsua 
            status = pjsua_start();
            if (status != PJ_SUCCESS)
            {
                fprintf(stderr, "pjsua_start error\n");
                return -1;
            }
 
    // Set NULL sound
            status = pjsua_set_null_snd_dev();
            if (status != PJ_SUCCESS)
            {
                fprintf(stderr, "pjsua_set_null_snd_dev error");
                return -1;
            }
 
    // Register to a SIP server by creating SIP account, I happen to  use Asterisk 
            pjsua_acc_id acc_id;
            fprintf(stderr, "Setting up SIP server registration\n");
            {
                pjsua_acc_config cfg;
                pjsua_acc_config_default(&cfg);
                cfg.id = pj_str("sip:6001@10.0.0.21");
                cfg.reg_uri = cfg.id; // same as ID
                cfg.cred_count = 1;
 
                cfg.cred_info[0].realm = pj_str("*");
                cfg.cred_info[0].scheme = pj_str("digest"); 
                cfg.cred_info[0].username = pj_str("6001");
                cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
                cfg.cred_info[0].data = "">
 
                status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
                if (status != PJ_SUCCESS)
                {
                    fprintf(stderr, "pjsua_acc_add error\n");
                    return -1;
                }
            }
 
            fprintf(stderr, "Waiting for SIP server registration to complete....\n");
 
            Sleep(2000); // sleep 2 seconds
 
    // Call extension 9 on my Asterisk server at 10.0.0.21:5060
            pj_str_t sip_target(pj_str("sip:9@10.0.0.21"));
            fprintf(stderr, "Making call to [%s]\n", sip_target.ptr);
 
            pjsua_call_id call_id;
            status = pjsua_call_make_call(acc_id, &sip_target, 0, NULL, NULL, &call_id);
            if (status != PJ_SUCCESS)
            {
                fprintf(stderr, "pjsua_call_make_call error\n");
                return -1;
            }
 
            pj_pool_t * pool = nullptr;
            pjmedia_port * wav = nullptr;
            pjmedia_aud_stream *strm = nullptr;
            pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(), "wav-audio", 1000, 1000, NULL);
 
            if (nullptr == pool)
            {
                fprintf(stderr,"Pool creation failed\n");
                return -1;
            }
 
    // 8kHz, single channel 16bit MS WAV format file
            status = pjmedia_wav_writer_port_create(pool, "test.wav", 8000, 1, 320, 16, PJMEDIA_FILE_WRITE_PCM, 0, &wav);
            if (status != PJ_SUCCESS)
            {
                fprintf(stderr, "Error creating WAV file\n");
                return -1;
            }
 
            pjmedia_aud_param param; 
    //////////////////////////////////////////////////////
    // FAILURE HERE : This is the function call which returns PJMEDIA_AUD_INVALID_DEV
    //////////////////////////////////////////////////////
            status = pjmedia_aud_dev_default_param(PJMEDIA_AUD_DEFAULT_CAPTURE_DEV, &param); 
            if (status != PJ_SUCCESS) 
            {
                fprintf(stderr, "pjmedia_aud_dev_default_param()");
                return -1;
            }
 
            param.dir = PJMEDIA_DIR_CAPTURE;
            param.clock_rate = PJMEDIA_PIA_SRATE(&wav->info);
            param.samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
            param.channel_count = PJMEDIA_PIA_CCNT(&wav->info);
            param.bits_per_sample = PJMEDIA_PIA_BITS(&wav->info);
 
            status = pjmedia_aud_stream_create(&param, &test_rec_cb, &test_play_cb, wav, &strm);
            if (status != PJ_SUCCESS)
            {
                fprintf(stderr, "Error opening the sound stream");
                return -1;
            }
 
            status = pjmedia_aud_stream_start(strm);
            if (status != PJ_SUCCESS)
            {
                fprintf(stderr, "Error starting the sound device");
                return -1;
            }
 
    // Spend some time allowing the called party to pick up and recording to proceed
            Sleep(10000); // sleep 10 seconds
 
    // Clean up code omitted
    return 0;
    }

 

 


_______________________________________________
Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@xxxxxxxxxxxxxxx
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org


_______________________________________________
Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@xxxxxxxxxxxxxxx
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux