ios pjsip - 在sip通话期间播放声音 [英] ios pjsip - play a sound during sip call
问题描述
当我正在啜饮时,有时我想发送dtmf数字。
为此,我创建了一个自定义拨号盘,当按下某个键时,应该播放该键的声音,但是在啜饮呼叫期间没有播放该声音(当没有呼叫时,播放声音)。
这些声音是用 AudioToolbox.h
库中的函数播放的( AudioServicesPlaySystemSound(soundID)
)。
When I am on sip call, sometimes I want to send dtmf digits.
To do this I created a custom dial pad which when a key is pressed should play a sound of that key, but it is not playing that sound during a sip call (when there is no call, sound is played).
These sounds are played with functions from AudioToolbox.h
library (AudioServicesPlaySystemSound(soundID)
).
我是否需要在pjsip(pjsua)或AudioToolbox库中设置一些属性才能在sip调用期间播放声音?
我知道这是可能的( Bria 有这个, Groundwire ,也不确定他们是否正在使用pjsip来实现sip)。
Is there some property that I need to set up in pjsip (pjsua) or in AudioToolbox library to enable a sound be played during a sip call?
I know this is possible (Bria has this, Groundwire also, not sure if they are using pjsip to implement sip).
推荐答案
这个答案是来自这两个链接的代码片段的组合: PJSUA-API Media Manipulation 和 pjsipDll_PlayWav.cpp 。
This answer is combination of code snippets from these two links: PJSUA-API Media Manipulation and pjsipDll_PlayWav.cpp.
当pjsua拨打电话时t正在使用端口(会议端口)将媒体从/向呼叫目的地传输到设备扬声器。 您可以同时打开多个端口。
When pjsua makes a call it is using ports (conference ports) for transferring media from/to the call destination to your device speaker. You can have multiple ports opened at the same moment.
那么我们打算播放键盘按键点击声音的方法是打开再多一个端口并播放声音(在这种情况下它是一个wav文件,你可以注意到还有一个用于流式传输avi文件的pjsua函数)。
要做到这一点,我们将使用这个函数:
So what we are going to do to play our keypad button click sound is to open one more port and play a sound (in this case it is a wav file, and as you can notice there are also a pjsua function for streaming avi files).
To do this we are going to use this function:
pj_status_t pjsua_conf_connect (pjsua_conf_port_id source, pjsua_conf_port_id sink)
其中我们的接收端口是我们的设备扬声器端口,在这种情况下(大多数情况下)它是0。
where our sink port is our device speaker port, in this case (and mostly) it is 0.
以下所有功能都添加到pjsua_app.c文件中。
在Objective-C类中使用它们之前,你必须添加如下一行:
All functions below are added to pjsua_app.c file. Before the place where they are used in the Objective-C class you have to add a line like this:
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文件读取(播放)时监听已结束:
And here is the callback function that listens when your wav file reading (playing) has ended:
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 说:
The reason why the pjmedia_wav_player_set_eof_cb callback function should return a value other then PJ_SUCCESS is because the documentation here pjmedia_wav_player_set_eof_cb says:
请注意,如果应用程序销毁回调中的文件端口,则必须在此处返回非PJ_SUCCESS。
这篇关于ios pjsip - 在sip通话期间播放声音的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!