news 2026/5/27 14:55:18

FreeSWITCH Media Bug 框架详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FreeSWITCH Media Bug 框架详解

本文系统性整理 FreeSWITCH Media Bug 的设计理念、核心数据结构、API 使用方式以及典型应用场景,适合FreeSWITCH / VoIP / 媒体处理方向的开发者作为参考文档或源码导读。


目录

  • 一、概述

  • 二、核心数据结构

  • 三、标志位说明

  • 四、回调类型

  • 五、核心 API

  • 六、工作流程

  • 七、使用示例

  • 八、最佳实践

  • 附录


一、概述

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 的核心结构体,定义于:

src/include/private/switch_core_pvt.h
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. 回调函数类型

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

标志位定义在:

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. 标志位组合示例

// 双向立体声录音 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_INITBug 创建成功
SWITCH_ABC_TYPE_CLOSEBug 移除
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

switch_core_media_bug_add( session, "record", filename, callback, user_data, 0, flags, &bug );

2. 移除 Media Bug

switch_core_media_bug_remove(session, &bug); switch_core_media_bug_remove_all_function(session, "record");

3. 读取混合音频

switch_core_media_bug_read(bug, &frame, SWITCH_TRUE);

六、工作流程

1. 音频处理流程(简化)

Codec Decode → Media Bug → 应用处理 → Codec Encode

2. 生命周期

  1. switch_core_media_bug_add

  2. INIT 回调

  3. READ / WRITE 回调

  4. switch_core_media_bug_remove

  5. 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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/20 13:04:25

为什么要学习大模型?小白+程序员必看,建议收藏深耕

在科技迭代日新月异的今天,大模型早已不是遥不可及的“黑科技”,而是成为驱动人工智能产业变革的核心引擎,更是程序员突破职业瓶颈、小白抢占时代风口的关键抓手。2025年,大模型的应用已经渗透到各行各业的核心场景,从…

作者头像 李华
网站建设 2026/5/22 10:05:28

基于springboot + vue蘑菇百科系统

蘑菇百科 目录 基于springboot vue蘑菇百科系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取: 基于springboot vue蘑菇百科系统 一、前言 博主介绍:✌️大…

作者头像 李华
网站建设 2026/5/21 0:47:11

国自然基金申请书撰写新思路:如何合理利用AI提高本子竞争力?

最近许多学术同仁询问我:如何合理利用AI辅助撰写国家自然科学基金(NSFC)申请书? 其实,用好AI的前提是严守红线:基金委明令禁止使用生成式人工智能直接生成申报材料。核心原则就一条:AI只能是辅助工具,而不是代写者。 界限在哪?请看这张“红绿灯”清单: 🟢 绿灯区…

作者头像 李华
网站建设 2026/5/23 5:08:12

【计算机毕业设计案例】基于SpringBoot的4S店试驾平台系统微信小程序基于springboot的4S店试驾平台小程序(程序+文档+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华