本文系统性整理 FreeSWITCH Media Bug 的设计理念、核心数据结构、API 使用方式以及典型应用场景,适合 FreeSWITCH / VoIP / 媒体处理 方向的开发者作为参考文档或源码导读。
目录
一、概述
1. 什么是 Media Bug?
Media Bug 是 FreeSWITCH 内部提供的一套 媒体流拦截(Hook)与处理框架 。开发者可以在通话会话(switch_core_session_t)中动态挂载一个或多个 Media Bug,用于捕获、分析、修改音频 / 视频 / 文本流。
它的核心思想是:
在编解码之后、媒体送达应用之前,提供一个可插拔的处理点。
支持的能力包括:
-
🎙 音频录制(读 / 写流)
-
🔁 实时音频替换与注入
-
📊 语音分析(VAD / DTMF / Tone / ASR)
-
🎥 视频捕获、处理、监控
-
👂 通话监听(Spy / Whisper)
-
💬 文本流(Text / RTCP / Data channel)处理
2. 典型应用场景
-
通话录音(单声道 / 立体声)
-
实时语音识别(ASR)
-
语音信箱 / 应答机检测(VMD / AVMD)
-
回声消除、降噪、语音增强
-
视频录制、截图、水印、转码
-
通话质量监控(MOS / RTP)
-
通话注入提示音、混音
二、核心数据结构
1. switch_media_bug_t
Media Bug 的核心结构体,定义于:
cpp
src/include/private/switch_core_pvt.h
cpp
struct switch_media_bug {
/* 音频缓冲区 */
switch_buffer_t *raw_write_buffer; // 写入流缓冲
switch_buffer_t *raw_read_buffer; // 读取流缓冲
/* 帧替换(REPLACE 模式) */
switch_frame_t *read_replace_frame_in;
switch_frame_t *read_replace_frame_out;
switch_frame_t *write_replace_frame_in;
switch_frame_t *write_replace_frame_out;
/* 原生帧 */
switch_frame_t *native_read_frame;
switch_frame_t *native_write_frame;
/* 回调与上下文 */
switch_media_bug_callback_t callback;
void *user_data;
/* 线程安全 */
switch_mutex_t *read_mutex;
switch_mutex_t *write_mutex;
/* 会话信息 */
switch_core_session_t *session;
uint32_t flags;
uint8_t ready;
time_t stop_time;
switch_thread_id_t thread_id;
/* 标识 */
char *function;
char *target;
/* 编解码信息 */
switch_codec_implementation_t read_impl;
switch_codec_implementation_t write_impl;
/* 录制相关 */
uint32_t record_frame_size;
uint32_t record_pre_buffer_count;
uint32_t record_pre_buffer_max;
/* 视频相关 */
switch_frame_t *video_ping_frame;
switch_queue_t *read_video_queue;
switch_queue_t *write_video_queue;
switch_queue_t *spy_video_queue[2];
switch_image_t *spy_img[2];
switch_vid_spy_fmt_t spy_fmt;
switch_thread_t *video_bug_thread;
/* 文本流 */
switch_buffer_t *text_buffer;
char *text_framedata;
uint32_t text_framesize;
/* 链表 */
switch_mm_t mm;
struct switch_media_bug *next;
/* 临时缓冲 */
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
int16_t tmp[SWITCH_RECOMMENDED_BUFFER_SIZE];
};
💡 一个会话可以同时挂载 多个 Media Bug,它们以链表形式存在。
2. 回调函数类型
cpp
typedef switch_bool_t (*switch_media_bug_callback_t)(
switch_media_bug_t *bug,
void *user_data,
switch_abc_type_t type
);
-
bug:当前 Media Bug 实例 -
user_data:创建时传入的用户上下文 -
type:当前触发的回调类型
三、标志位说明
1. switch_media_bug_flag_t
标志位定义在:
cpp
src/include/switch_types.h
| 标志位 | 说明 |
|---|---|
SMBF_READ_STREAM |
捕获 incoming audio |
SMBF_WRITE_STREAM |
捕获 outgoing audio |
SMBF_READ_REPLACE |
替换读取流 |
SMBF_WRITE_REPLACE |
替换写入流 |
SMBF_STEREO |
立体声录制 |
SMBF_ANSWER_REQ |
应答后才开始 |
SMBF_BRIDGE_REQ |
桥接后才开始 |
SMBF_ONE_ONLY |
同 function 只允许一个 |
SMBF_TAP_NATIVE_READ |
原生读取帧 |
SMBF_TAP_NATIVE_WRITE |
原生写入帧 |
SMBF_READ_VIDEO_STREAM |
读取视频流 |
SMBF_VIDEO_PATCH |
视频补丁 |
SMBF_READ_TEXT_STREAM |
文本流 |
2. 标志位组合示例
cpp
// 双向立体声录音
flags = SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_STEREO;
// 仅应答后录制 incoming audio
flags = SMBF_READ_STREAM | SMBF_ANSWER_REQ;
// 替换 outgoing audio
flags = SMBF_WRITE_REPLACE;
四、回调类型
switch_abc_type_t
| 类型 | 触发时机 |
|---|---|
SWITCH_ABC_TYPE_INIT |
Bug 创建成功 |
SWITCH_ABC_TYPE_CLOSE |
Bug 移除 |
SWITCH_ABC_TYPE_READ |
读取流数据 |
SWITCH_ABC_TYPE_WRITE |
写入流数据 |
SWITCH_ABC_TYPE_READ_REPLACE |
读取替换 |
SWITCH_ABC_TYPE_WRITE_REPLACE |
写入替换 |
SWITCH_ABC_TYPE_READ_VIDEO_PING |
视频心跳 |
SWITCH_ABC_TYPE_READ_TEXT |
文本数据 |
返回值说明:
-
SWITCH_TRUE:继续执行 -
SWITCH_FALSE:停止并移除该 Media Bug
五、核心 API
1. 添加 Media Bug
cpp
switch_core_media_bug_add(
session,
"record",
filename,
callback,
user_data,
0,
flags,
&bug
);
2. 移除 Media Bug
cpp
switch_core_media_bug_remove(session, &bug);
switch_core_media_bug_remove_all_function(session, "record");
3. 读取混合音频
cpp
switch_core_media_bug_read(bug, &frame, SWITCH_TRUE);
六、工作流程
1. 音频处理流程(简化)
Codec Decode → Media Bug → 应用处理 → Codec Encode
2. 生命周期
-
switch_core_media_bug_add -
INIT 回调
-
READ / WRITE 回调
-
switch_core_media_bug_remove -
CLOSE 回调
七、使用示例
示例:双向立体声录音
flags = SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_STEREO;
八、最佳实践
1. 线程安全
-
回调运行在 媒体线程
-
共享资源务必加锁
2. 内存管理
-
使用
switch_core_session_alloc -
不要使用
malloc / free
3. 性能建议
-
回调中避免阻塞
-
使用异步队列
-
仅订阅必要的流
附录
A. 关键源码
-
switch_core_media_bug.c -
switch_core_pvt.h
B. 常见模块
-
mod_vmd -
mod_avmd -
mod_spy -
mod_snapshot
总结
Media Bug 是 FreeSWITCH 媒体处理的基石能力之一。
通过合理使用 Media Bug,可以实现:
-
高性能录音
-
实时音频 / 视频处理
-
通话监控与分析
-
ASR / TTS / AI 媒体接入
如果你在做 语音平台、呼叫中心、AI 语音、VoIP 内核开发,Media Bug 是绕不开的一块核心能力。
FreeSWITCH :1.10.x