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

Posted

技术标签:

【中文标题】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); 中使用它;

以上是关于ios pjsip - 在 sip 通话期间播放声音的主要内容,如果未能解决你的问题,请参考以下文章

SIP开源项目opensip,Freeswitch

iPhone:在通话期间在应用程序中调整播放音量

介绍一个开源的SIP(VOIP)协议库PJSIP

电话通信功能知识总结

java sip打电话实现,如何判断用户不说话

iOS 应用中支持 IPV6 的 pjsip 2.5.5