PJSIP自定义语音

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PJSIP自定义语音相关的知识,希望对你有一定的参考价值。

参考技术A SDP(会话描述协议): 用于两个会话实体之间的媒体协商,并达成一致,属信令语言族,采用文本(字符)描述形式;
RTP (实时传输协议):由RFC3550定义的端到端的传输实时数据协议,它包含:净荷类型识别,序列号编码,时间戳和传输控制;
RTCP(实时传输控制协议):与RTP共同定义在1996年提出的RFC 1889中,是和 RTP一起工作的控制协议。
RSVP(资源预留协议):RSVP是一种位于第三层的信令协定,它独立于各种网路媒介,使得套用能将自己的QoS要求通过信令通知给网路,网路可以对此套用预留相应的资源。
Sigcomp(信令压缩):一种压缩应用层协议(如SIP、RTSP)消息的方案。

核心标准:RFC3261 SIP:Session Initiation Protocol

扩展标准:RFC2976 The SIP INFO Method
RFC3263 Locating SIP Servers
RFC3265 SIP-Specific Event Notification
RFC3311 UPDATE Method
RFC3326 The Reason Header Field
RFC3372 SIP for Telephones (SIP-T): Context and Architectures
RFC3398 ISUP to SIP Mapping
RFC3428 SIP Extension for Instant Messaging

参考链接:

https://www.renrendoc.com/paper/110170462.html

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自定义语音的主要内容,如果未能解决你的问题,请参考以下文章

微软自定义语音识别定价方案

Microsoft 自定义翻译和语音翻译 API

如何将自定义语言数据集上载到Azure自定义语音服务?

认知服务 - 自定义语音 C++

android如何自定义语音识别

如何自定义NeoSpeech语音库的发音