🏠 博客主页:小小马车夫的主页
🍅 所属专栏:FreeSwitch开发实践
🥝 专栏介绍:主要介绍博主在实际项目中使用FreeSwitch开发外呼类项目的一些经验心得,主要涉及FreeSwitch的基本安装编译、基本配置、ESL、WSS、录音、自定义模块、media bug、语音播放、MRCP及对接AI机器人等内容。内容在持续更新中,如果感兴趣可以对专栏进行订阅~🎈🎈想对未来的自己说的话🎈🎈🥑 🥑 间歇性的努力和蒙混过日子,都是对之前努力的清零🥑 🥑
前言
上一篇介绍创建和使用自定义模块,创建一个自己的app嵌入到FreeSwitch;这一篇介绍运用“media bug”,获取通话语音流。首先,看到这儿,应该会有两个问题:
- 什么是media bug
- media bug有什么用,能干什么
第一个问题我们放到后面详细介绍,第二个问题media bug能干什么,media bug主要用来监听通话语音数据,而拿到通话语音流了可以做很多事情,可以加不少业务: - 通话监听
- 分析语音,即通常说的ASR(语音识别)
一、什么是media bug
media bug中的bug并不是软件缺陷的意思,它的作用是在FreeSwitch媒体通话数据流(语音或视频)中截取这部分数据流,达到监听的作用,类似从一个管道安插一个管道,这个管道就是“media bug”, 相当于打一个“洞”,所以media bug的bug应该称为“盗取”、“截取”的意思。
二、如何使用media bug获取通话语音流
首先,看一段media bug创建和获取通话语音流的例子:
2.1 media bug创建
switch_status_t status;
switch_media_bug_t *bug;
//添加media bug
status = switch_core_media_bug_add(session, "mymedia", 0, mymediabug_callback, (void*)robot_id, 0, SMBF_READ_STREAM | SMBF_NO_PAUSE, &bug);
我们看一下switch_core_media_bug_add
的声明:
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(_In_ switch_core_session_t *session,
_In_ const char *function,
_In_ const char *target,
_In_ switch_media_bug_callback_t callback,
_In_opt_ void *user_data,
_In_ time_t stop_time,
_In_ switch_media_bug_flag_t flags, _Out_ switch_media_bug_t **new_bug);
函数说明:
参数 | 解释 |
---|---|
session | 会话session |
function | media bug函数名称,可以作为唯一key,一个key对应一个media bug, 对应Media-Bug-Function |
target | 目标,对应Media-Bug-Taget |
callback | media bug回调函数 |
user_data | 回调函数的传入数据 |
stop_time | 停止时间 |
flags | 标志,不标志,回调函数中监听不通的功能 |
new_bug | 传出参数, 新创建media bug |
2.2 media bug回调函数
static switch_bool_t mymediabug_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
switch_core_session_t* session = switch_core_media_bug_get_session(bug);
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
switch_frame_t frame = { 0 };
frame.data = data;
frame.buflen = sizeof(data);
const char*robot_id = (const char *) user_data;
if (robot_id == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "mymedia user data is null!");
return SWITCH_FALSE;
}
switch (type) {
case SWITCH_ABC_TYPE_INIT:
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "mymediabug init, user_data[%s]\n", robot_id);
}
break;
case SWITCH_ABC_TYPE_READ:
{
if (switch_core_media_bug_read(bug, &frame, SWITCH_FALSE) != SWITCH_STATUS_FALSE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "read frame: data_len=[%d], rate[%d], channels[%d], samples[%d] \n",
frame.datalen, frame.rate, frame.channels, frame.samples);
}
}
break;
case SWITCH_ABC_TYPE_CLOSE:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "mymediabug close, user_data[%s]\n", robot_id);
break;
default:
break;
}
return SWITCH_TRUE;
}
说明:
SWITCH_ABC_TYPE_READ这里就是语音流获取的地方,
switch_core_media_bug_read
即获取语音数据的接口,下面看下这个接口的声明:
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_read(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame, switch_bool_t fill);
这个接口参数比较简单, bug
就是media bug指针, frame
是语音数据结构体
2.3 media bug的原理
这里不展开说明media bug的底层实现,只是简要说一下media bug 的实现。要想了解media bug可以从接口switch_core_media_bug_add
入手,其实media bug并没有开起新线程, 从源码得知只是视频video会开线程,而音频不会,那它是如何监听音频流呢,答案是switch_core_session_read_frame
接口,此接口是读取原始语音流的,在核心中使用,这就是语音流没有单独开线程的原因。
三、media bug相关接口
上一节知道media bug创建,和在media bug回调函数中获取语音流的方法,下面列举一下和media bug相关的一些接口:
- switch_core_media_bug_add --创建media bug
- switch_core_media_bug_remove – 删除media bug
- switch_core_media_bug_get_session – 获取media bug所属的通话session
- switch_core_media_bug_read – 从media bug中读取语音数据
四、完整例子
由于代码比较多,完整例子见:https://download.csdn.net/download/xxm524/86261083
(代码示例象征性收取5个积分,如果没有积分可以私信博主即可以免费获取)
自定义模块的使用方法和拨号计划配置见:【FreeSwitch开发实践】自定义模块创建与使用
命令:
originate user/1000 123
输出:
总结
本文主要介绍了media bug相关的知识,分别有如下几3点:文章来源:https://www.toymoban.com/news/detail-440099.html
- 说明了什么是media bug
- 如何使用media bug获取通话语音流
- media bug相关接口说明
如果觉得有些帮助或觉得文章还不错,请关注一下博主,你的关注是我持续写作的动力。另外,如果有什么问题,可以在评论区留言,或者私信博主,博主看到后会第一时间回复。文章来源地址https://www.toymoban.com/news/detail-440099.html
到了这里,关于【FreeSwitch开发实践】media bug获取通话语音流的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!