SRT(Secure Reliable Transport)是一种开源的视频传输协议,专为高丢包、高延迟网络环境设计,结合了UDP的低延迟和TCP的可靠性,广泛应用于直播、远程制作、视频会议等场景。
-
定位:SRT协议的官方C/C++实现库,由Haivision和社区维护,提供高可靠、低延迟的流媒体传输能力。
-
核心功能:
-
支持SRT协议的全部特性(ARQ重传、FEC、AES加密、自适应码率)。
-
跨平台(Windows/Linux/macOS),提供C API和C++封装。
-
与FFmpeg、GStreamer等主流多媒体框架集成。
-
1. SRT的核心优势
特性 | 描述 |
---|---|
低延迟 | 基于UDP,支持端到端延迟可控制在 100ms~500ms(可配置)。 |
抗丢包 | 通过ARQ(自动重传请求)和FEC(前向纠错)恢复丢包,支持 30%+ 丢包率。 |
安全性 | 内置AES加密(128/256位),防止数据窃听。 |
自适应码率 | 动态调整发送速率,避免网络拥塞。 |
多路复用 | 支持单端口多流传输,降低资源占用。 |
2. SRT的工作原理
(1) ARQ(自动重传请求)
-
丢包检测:接收端通过序列号检测丢包,发送NACK(丢包重传请求)。
-
选择性重传:仅重传丢失的包,而非全部数据,减少带宽浪费。
-
重传超时:可配置超时时间(默认250ms),超时后放弃重传,避免延迟累积。
(2) FEC(前向纠错)
-
可选功能,在数据包中加入冗余信息,允许接收端直接恢复少量丢包(无需重传)。
(3) 自适应传输
-
带宽探测:持续监测网络带宽,动态调整发送码率。
-
延迟控制:通过缓冲区(Latency Buffer)平滑网络抖动,保持稳定延迟。
3. SRT的典型应用场景
场景 | 配置建议 |
---|---|
直播推流 | 使用 SRT + FEC,码率自适应(如5Mbps动态调整),延迟设为1秒。 |
远程制作 | 低延迟模式(200ms),启用AES加密,保证实时性和安全性。 |
跨国传输 | 启用ARQ和FEC,设置冗余包比例10%~20%,对抗高丢包。 |
企业视频会议 | 使用SRT多路复用,单端口传输多路视频,降低防火墙配置复杂度。 |
4. SRT vs. 其他协议
协议 | 延迟 | 可靠性 | 适用场景 |
---|---|---|---|
SRT | 低 | 高(ARQ+FEC) | 直播、远程制作、高丢包网络 |
RTMP | 中 | 中(TCP) | 传统直播推流 |
WebRTC | 极低 | 中(部分丢包) | 实时通信、P2P场景 |
QUIC | 低 | 高(多路复用) | HTTP/3流媒体 |
5. SRT的配置与使用
(1) 常用参数
参数 | 说明 | 示例值 |
---|---|---|
latency | 端到端最大延迟(毫秒) | 1000 |
passphrase | AES加密密钥(需16/24/32字符) | MySecureKey123 |
fec | FEC冗余配置(如rows:10,cols:5 ) | rows:10 |
maxbw | 最大发送带宽(Mbps) | 10 |
(2) 推流示例(FFmpeg)
# 推流端(Publisher)
ffmpeg -i input.mp4 -c:v libx264 -preset fast -f mpegts "srt://接收端IP:9000?latency=500&passphrase=MyKey"
# 接收端(Subscriber)
ffplay "srt://0.0.0.0:9000?latency=500&passphrase=MyKey"
(3) 工具支持
-
srt-live-transmit:官方测试工具,用于中继或调试。
-
OBS Studio:支持SRT推流(设置→输出→选择SRT协议)。
-
Haivision Play Pro:SRT播放器,支持加密和低延迟模式。
6. libsrt库编译与配置
(1) 编译安装(Linux)
# 安装依赖
sudo apt-get install cmake tclsh pkg-config
# 下载源码
git clone https://github.com/Haivision/srt.git
cd srt
./configure --prefix=/usr/local --enable-shared=ON
make -j4
sudo make install
# 验证安装
srt-live-transmit --version
(2) Windows编译
1)使用CMake生成VS工程(比如:VS2019):
cmake -G "Visual Studio 16 2019" -A x64 ..
2)打开生成的.sln
文件编译ALL_BUILD
目标。
7. libsrt库使用
(1) 创建SRT Socket(C语言)
#include <srt/srt.h>
int main() {
// 初始化库
srt_startup();
// 创建Socket
SRTSOCKET sock = srt_create_socket();
if (sock == SRT_INVALID_SOCK) {
fprintf(stderr, "srt_create_socket failed\n");
return 1;
}
// 设置参数:延迟500ms,启用加密
srt_setsockflag(sock, SRTO_LATENCY, "500", sizeof(int));
srt_setsockflag(sock, SRTO_PASSPHRASE, "MySecretKey123", 13);
// 绑定端口(接收端)
struct sockaddr_in sa = {0};
sa.sin_family = AF_INET;
sa.sin_port = htons(9000);
sa.sin_addr.s_addr = INADDR_ANY;
srt_bind(sock, (struct sockaddr*)&sa, sizeof(sa));
// 进入监听模式
srt_listen(sock, 5);
// 接收连接(省略事件循环)
SRTSOCKET client = srt_accept(sock, NULL, NULL);
// 数据传输...
char buffer[1316]; // SRT最大有效载荷
int len = srt_recvmsg(client, buffer, sizeof(buffer));
// 清理
srt_close(sock);
srt_cleanup();
return 0;
}
(2) 发送数据
#include <srt/srt.h>
#include <iostream>
int send_data(SRTSOCKET sock, const char* data, size_t len) {
int ret = srt_sendmsg(sock, data, len, -1, 0);
if (ret == SRT_ERROR) {
std::cerr << "Send failed: " << srt_getlasterror_str() << std::endl;
return -1;
}
return ret; // 返回成功发送的字节数
}
(3)关键参数配置
参数名(Flag) | 类型 | 说明 | 推荐值 |
---|---|---|---|
SRTO_LATENCY | int (ms) | 端到端最大允许延迟 | 直播:1000~2000 |
SRTO_PASSPHRASE | string | AES加密密钥(长度16/24/32字节) | 强制设置 |
SRTO_OHEADBW | int (%) | FEC冗余带宽占比 | 丢包高时:20 |
SRTO_MAXBW | int64 | 最大发送带宽(bytes/sec) | 根据网络调整 |
SRTO_RCVSYN | bool | 接收操作是否阻塞 | 非阻塞:false |
(4)FFmpeg编译支持libsrt
# 配置FFmpeg时加入--enable-libsrt
./configure --enable-libsrt --extra-ldflags=-lsrt
推流、播流
# 推流端
ffmpeg -i input.mp4 -c:v libx264 -preset fast -f mpegts 'srt://192.168.1.100:9000?latency=500&passphrase=MyKey'
# 接收端
ffplay 'srt://0.0.0.0:9000?latency=500&passphrase=MyKey'
(5)高级功能
1)多路流复用
// 启用多路复用(需SRT v1.5+)
srt_setsockflag(sock, SRTO_STREAMID, "#!::r=live/stream1", 18);
2)自适应码率控制
// 动态调整发送带宽(根据网络反馈)
int64_t available_bw = ...; // 从网络探测获取
srt_setsockflag(sock, SRTO_MAXBW, &available_bw, sizeof(available_bw));
3)日志启用
// 设置日志级别
srt_setloglevel(srt_logging::LogLevel::debug);
// 自定义日志回调
srt_setloghandler(nullptr, [](void* p, int level, const char* file, int line, const char* area, const char* msg) {
printf("[SRT] %s:%d %s\n", file, line, msg);
});
4)关键统计信息
SRT_TRACEBSTATS stats;
srt_bstats(sock, &stats, 1);
printf("丢包率: %.2f%%\n", (stats.pktLossTotal * 100.0) / stats.pktSentTotal);
printf("延迟: %d ms\n", stats.msRTT);
8. 调试与优化
-
监控丢包率:通过
srt-logs
或ffmpeg
日志查看丢包和重传统计。 -
调整延迟缓冲区:
-
网络稳定时减少
latency
(如500ms→200ms)。 -
高抖动时增大
latency
(如2000ms)。
-
-
带宽自适应:设置
maxbw
为物理带宽的80%,留出冗余。
9. 注意事项
-
防火墙/NAT穿透:确保UDP端口开放(默认10000-65535),或使用SRT的Rendezvous模式。
-
加密密钥管理:定期更换
passphrase
,避免密钥泄露。 -
硬件加速:使用支持SRT的硬件编码器(如Haivision Makito X)降低CPU占用。