这个答案是这两个链接的代码片段的组合:PJSUA-API 媒体操作 and pjsipDll_PlayWav.cpp.
当 pjsua 拨打电话时,它会使用端口(会议端口)将媒体从呼叫目的地传输到您的设备扬声器。您可以同时打开多个端口.
因此,要播放键盘按钮点击声音,我们要做的就是再打开一个端口并播放声音(在本例中,它是一个 wav 文件,您可以注意到,还有一个用于流式传输 avi 文件的 pjsua 函数) 。
为此,我们将使用这个函数:
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 says:
请注意,如果应用程序在回调中销毁文件端口,则此处必须返回非 PJ_SUCCESS。