在srs中加功能应直接修改srssource或srsrtmpconn,避免hook或ffmpeg管道;需注意c++标准兼容性、ssl依赖、热加载手动注册回调、线程安全及调试时启用core dump。

直接改 SrsSource 或 SrsRtmpConn 是最常用的切入点
想在 SRS 里加功能(比如录制、转协议、打水印),不建议走 Hook 外部调用或 FFmpeg 管道——延迟高、崩溃风险大、状态难同步。真实项目里,90% 的定制需求都落在流接入和分发环节,对应的核心类就是 SrsSource(流源管理)和 SrsRtmpConn(RTMP 连接处理)。前者负责接收推流、缓存 GOP、维护所有订阅者;后者管握手、消息解析、命令处理。改这里能拿到原始音视频包、时间戳、客户端 IP、流名、甚至鉴权参数。
常见操作包括:
- 在
SrsSource::on_video/on_audio里插入自定义编码器或写文件逻辑(注意加锁,避免多线程写冲突) - 在
SrsRtmpConn::process_connect_app中读取 URL query 参数或 HTTP header,做流级权限控制 - 重载
SrsSource::on_reload响应配置热更新,比如动态开关某路流的录制
./configure 编译前必须确认 C++ 标准和依赖路径
SRS 主干默认用 -std=c++11,但 Ubuntu 21+、Fedora 35+ 等新系统 GCC 默认走 C++17,会导致 configure 阶段报错 “unknown attribute” 或 “no member named ‘emplace’”。这不是代码问题,是构建脚本没显式指定标准。
正确做法是:
- 编译前导出环境变量:
export CXXFLAGS="-std=c++11" - 确保
openssl-dev、libssl-dev已安装,且软链接存在(Ubuntu 21+ 常缺/usr/lib/x86_64-linux-gnu/libssl.so) - 如果用自定义 OpenSSL 路径,需加
--with-ssl=PATH,否则 configure 会跳过 SSL 检测,导致后续 RTMPS 编译失败
配置热加载不是自动生效,得手动注册回调
SRS 支持 kill -s SIGHUP $(cat objs/srs.pid) 触发热重载,但你新增的模块不会被自动通知。必须让自定义类继承 ISrsReloadHandler,并在初始化时调用 _srs_config->subscribe(this)。
典型漏点:
- 忘记在析构函数里
unsubscribe,导致重载后旧对象残留、内存泄漏 - 在
on_reload回调里直接修改正在运行的SrsSource成员,没加锁或没暂停写入,引发 crash - 误以为重载会重建所有连接,其实只刷新配置,已建立的流仍沿用旧逻辑,新流才走新配置
调试时别只看 srs.log,要开 gdb + core dump
SRS 出问题常表现为静默退出或 CPU 占满,日志里可能只有 “segmentation fault” 一行。这时候光查 srs.log 没用。必须打开 core dump:
- 执行
ulimit -c unlimited,再启动 SRS - 出问题后用
gdb ./objs/srs core.xxx,输入bt看栈帧,定位到具体哪行 C++ 代码崩了 - 特别注意指针释放后二次使用、STL 容器迭代器失效、跨线程访问未加锁的 shared_ptr
真正卡住的地方,往往不是你新加的几十行代码,而是对 SrsSharedPtr 生命周期理解偏差,或者没意识到 SrsBuffer 内存是引用计数管理的。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











