记一次pjsip通话没声音的调试过程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次pjsip通话没声音的调试过程相关的知识,希望对你有一定的参考价值。

参考技术A 1、定位:首先就是定位是否有流,将dev port的frame写文件,conference port的frame写文件,stream port的frame写文件。发现从stream port开始,frame就是空的了。(写文件的位置一般都在相应port的put_frame实现中,因为是编码方向的流)
2、调试:检查port连接是否异常,发现port一开始连接正常,但是中途发生了media channel update,stream被destroy然后重新create,start,这个时候stream port本应和conference port重新连接起来的但是发现并没有,这一步产生两个疑点:首先为什么会发生media channel update且codec param协商失败?这是因为stream create会置 code param的vad参数为0,stream port的put_frame中才会真正使能这个参数(但是需要过一段时间,这个时间由PJMEDIA_STREAM_VAD_SUSPEND_MSEC来控制,具体可参考pjsip中的注释),由于update到来的时,这个参数还没有使能,因此media update channel时codec param参数协商失败。其次为什么stream destroy然后再creat,start,stream port就没有和conference port连接了?这是因为前面的人修改了on_call_audio_state的实现,在连接conference port和stream port前加了判断,call state是confirm状态就不连接,所以才会出现通话中channel update时重启stream会导致stream中没有流。
3、解决:三个方案选其一
channel update时不比较codec的vad参数
将PJMEDIA_STREAM_VAD_SUSPEND_MSEC改小,保证update前codec的vad参数已经修改过来
将on_call_audio_state中连接port前的判断去掉

ios pjsip - 在 sip 通话期间播放声音

【中文标题】ios pjsip - 在 sip 通话期间播放声音【英文标题】:ios pjsip - play a sound during sip call 【发布时间】:2013-09-27 09:50:45 【问题描述】:

当我在 sip 通话时,有时我想发送 dtmf 数字。 为此,我创建了一个自定义拨号盘,当按下某个键时,它会播放该键的声音,但在 sip 通话期间它不会播放该声音(当没有通话时,会播放声音)。 这些声音使用AudioToolbox.h 库 (AudioServicesPlaySystemSound(soundID)) 中的函数播放。

是否需要在 pjsip (pjsua) 或 AudioToolbox 库中设置一些属性才能在 sip 呼叫期间播放声音? 我知道这是可能的(Bria 有这个,Groundwire 也有,不确定他们是否使用 pjsip 来实现 sip)。

【问题讨论】:

【参考方案1】:

这个答案是来自这两个链接的代码 sn-ps 的组合:PJSUA-API Media Manipulation 和 pjsipDll_PlayWav.cpp。

当 pjsua 拨打电话时,它使用端口(会议端口)将媒体从/到呼叫目的地传输到您的设备扬声器。 您可以同时打开多个端口

所以我们要播放我们的键盘按钮点击声音是打开一个端口并播放声音(在这种情况下它是一个 wav 文件,你可以注意到还有一个 pjsua 用于流式传输的函数avi 文件)。 为此,我们将使用这个函数:

 pj_status_t    pjsua_conf_connect (pjsua_conf_port_id source, pjsua_conf_port_id sink)

我们的接收器端口是我们的设备扬声器端口,在这种情况下(并且大多数情况下)它是 0。

以下所有函数都添加到 pjsua_app.c 文件中。 在 Objective-C 类中使用它们的位置之前,您必须添加如下一行:

pj_status_t play_sound_during_call(pj_str_t sound_file);

这里是播放声音的函数:

pj_status_t play_sound_during_call(pj_str_t sound_file)

    pjsua_player_id player_id;
    pj_status_t status;
    status = pjsua_player_create(&sound_file, 0, &player_id);
    if (status != PJ_SUCCESS)
        return status;

    pjmedia_port *player_media_port;

    status = pjsua_player_get_port(player_id, &player_media_port);
    if (status != PJ_SUCCESS)
    
        return status;
    

    pj_pool_t *pool = pjsua_pool_create("my_eof_data", 512, 512);
    struct pjsua_player_eof_data *eof_data = PJ_POOL_ZALLOC_T(pool, struct pjsua_player_eof_data);
    eof_data->pool = pool;
    eof_data->player_id = player_id;

    pjmedia_wav_player_set_eof_cb(player_media_port, eof_data, &on_pjsua_wav_file_end_callback);

    status = pjsua_conf_connect(pjsua_player_get_conf_port(player_id), 0);

    if (status != PJ_SUCCESS)
    
        return status;
            

    return status;

这是当你的wav文件读取(播放)结束时监听的回调函数:

struct pjsua_player_eof_data

    pj_pool_t          *pool;
    pjsua_player_id player_id;
;

static PJ_DEF(pj_status_t) on_pjsua_wav_file_end_callback(pjmedia_port* media_port, void* args)

    pj_status_t status;

    struct pjsua_player_eof_data *eof_data = (struct pjsua_player_eof_data *)args;

    status = pjsua_player_destroy(eof_data->player_id);

    PJ_LOG(3,(THIS_FILE, "End of Wav File, media_port: %d", media_port));

    if (status == PJ_SUCCESS)
    
        return -1;// Here it is important to return a value other than PJ_SUCCESS
                  //Check link below
    

    return PJ_SUCCESS;

pjmedia_wav_player_set_eof_cb 回调函数应该返回 PJ_SUCCESS 以外的值的原因是这里的文档 pjmedia_wav_player_set_eof_cb 说:

注意,如果应用在回调中销毁文件端口,这里必须返回non-PJ_SUCCESS。

【讨论】:

嗨@SihadBegovic,我正在尝试在iOS 中实现电话会议的代码。但是,面对一些问题,您能否发布您如何添加 sip 电话会议的代码。谢谢。 我也面临文件无法打开的错误。请帮忙 @Sihad Begovic 你能告诉我如何使用这个功能吗? 这只是猜测应该如何。文件应位于您的应用程序包或应用程序文档文件夹中。无论哪种方式,您都应该在字符串中使用该路径,使用 [[NSBundle mainBundle] pathForResource:resource ofType:type];或从文档 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);然后将 NSString 路径转换为 ​​char 并在末尾转换为 pj_str_t 并在 pj_status_t play_sound_during_call(pj_str_t sound_file); 中使用它;

以上是关于记一次pjsip通话没声音的调试过程的主要内容,如果未能解决你的问题,请参考以下文章

Manjaro设置声音

笔记本电脑没声音该怎么办

为啥录制出来的视频没有声音?

打开打开录制声音后,为啥录屏还是没声音?

GB28181PJSIP库回声消除热拔插声音去抖

解决电脑没有声音的方法?