ios pjsip – 在拨打电话时播放声音

当我啜饮电话时,有时候我想发送dtmf数字。
为此,我创build了一个自定义拨号盘,当按下某个按键时,应该播放该按键的声音,但是在SIP呼叫期间(没有呼叫,声音播放时)不会播放该声音。
这些声音与AudioToolbox.h库( AudioServicesPlaySystemSound(soundID) )中的函数一起播放。

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

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

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

所以我们要做的就是打开我们的键盘button点击声音是打开一个端口和播放声音(在这种情况下,它是一个WAV文件,你可以注意到也有一个PJSUAfunctionstreamAVI文件) 。
要做到这一点,我们要使用这个function:

  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); 

在这里播放声音的function是:

 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文件读取(播放)结束时监听的callback函数:

 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_cbcallback函数应该返回PJ_SUCCESS以外的值的原因是因为这里的文档pjmedia_wav_player_set_eof_cb表示:

请注意,如果应用程序销毁callback中的文件端口,则必须在此处返回非PJ_SUCCESS。