SRS(Simple Realtime Server)是一个基于MIT协议开源的高性能视频流媒体服务器。它支持RTMP、HLS、HTTP-FLV等多种协议,能够接收推流并进行协议转换后供客户端拉流播放。本文将详细介绍如何使用Docker快速搭建SRS平台,并重点实现基于HTTP回调的推流与拉流身份认证,确保流媒体服务的安全可控。
一、SRS介绍
SRS是一个功能丰富的视频服务平台,支持多种视频流协议,能够接收推流和拉流播放,同时支持音视频协议转换。例如,可以实现按RTMP格式推流,然后以HLS格式进行拉流播放。本文将演示如何通过SRS的HTTP回调(HTTP Hooks)功能,实现推流和拉流时的身份认证,为你的流媒体服务加上一把“安全锁”。
二、安装与配置
1. 准备SRS配置文件
首先,在宿主机上创建配置文件,例如 /etc/srs/auth.conf。
listen 1935;
max_connections 1000;
daemon off;
srs_log_tank console;
# 启用http服务
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
vhost __defaultVhost__ {
# 启用hls功能
hls {
enabled on;
}
# 配置回调API
http_hooks {
enabled on;
# 推流回调地址
on_publish http://192.168.2.99:8085/api/v1/hooks;
# 拉流播放回调地址
on_play http://192.168.2.99:8085/api/v1/hooks;
}
}
这个配置文件做了几件事:开启HLS支持以便生成 .m3u8 索引文件;设置了HTTP服务用于提供HLS流;最关键的是配置了 http_hooks,指定了推流(on_publish)和播放(on_play)事件发生时,SRS服务器需要去回调的认证API地址。
2. 启动Docker容器
配置好文件后,使用 Docker 一键启动SRS服务。
docker run -d -p 1935:1935 -p 1985:1985 -p 8515:8080 --name rtmp_server -v /etc/srs/auth.conf:/usr/local/srs/conf/auth.conf registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5 ./objs/srs -c conf/auth.conf
参数解释:
-v /etc/srs/auth.conf:/usr/local/srs/conf/auth.conf:将宿主机上刚创建的配置文件映射到容器内的对应路径。
-c conf/auth.conf:指定SRS启动时使用的配置文件,即我们映射进去的那个。
-p 8515:8080:将容器内部的 8080 端口(对应配置文件中的 http_server 端口)映射到宿主机的 8515 端口,后续将通过 http://宿主机IP:8515 来访问HLS流。
至此,一个支持HLS和HTTP回调的SRS流媒体服务器就运行起来了。接下来,我们需要实现它要回调的那个认证API。
三、实现身份认证API
根据SRS官方规范,认证API在验证通过时必须返回:HTTP状态码 200,且响应体为JSON格式 {“code”:0}。只要不返回200状态码,或者返回的JSON中 code 字段值不为0,SRS都会认为认证失败,从而拒绝推流或拉流请求。
下面是一个简化的Spring Boot控制器示例,演示了如何在回调API中验证一个简单的签名(sign)。
/**
* SRS权限验证,验证通过需返回json {code:0} 且 http状态码 200
*
* @param client SRS回调传入的客户端信息实体
* @return 认证结果
* @throws NoSuchAlgorithmException
*/
@PostMapping(“/hooks”)
public AuthResult auth(@RequestBody Client client) throws NoSuchAlgorithmException {
System.out.println(client);
List<String> authTypes = Arrays.asList(“on_publish”, “on_play”);
// 仅在推流与播放时验证权限
if (authTypes.stream().anyMatch(t -> t.equals(client.getAction()))) {
String sign = generate(key); // 这里是服务端根据密钥生成的预期签名
// 约定推流/拉流URL中通过sign参数传入认证信息,这里检查客户端传入的sign是否合法
String param = “?sign=” + sign;
if (!param.equals(client.getParam())) {
// 推流与播放时验证sign不通过
throw new RuntimeException(“加签验证失败”);
}
}
// 其它情况:停止推流、停止播放、或者sign验证通过:返回code 0
return AuthResult.builder().code(0).build();
}
这段代码的逻辑是:当SRS回调的动作(client.getAction())是推流(on_publish)或播放(on_play)时,会检查客户端请求中携带的参数(client.getParam())。我们约定客户端需要在推流/拉流URL中加入一个 sign 参数,API端会用同样的算法和密钥生成一个签名进行比对。匹配则通过,不匹配则抛出异常(导致返回非200状态码)。
Client 和 AuthResult 是简单的数据模型类,结构如下(仅供参考):
@Data // 使用Lombok
public class Client {
private String action; // 如 “on_publish”
private String ip;
private String vhost;
private String app;
private String stream;
private String param; // 推流/拉流URL中的参数部分,如 “?sign=xxx”
}
@Data
@Builder
public class AuthResult {
private int code;
}
四、完整测试流程
1. 推流测试(带签名)
假设你的认证服务生成的签名为 585d3f2df6ed93957ec13ad6c8680fd3,SRS服务器IP为 192.168.2.66。使用FFmpeg进行推流时,需要将签名作为参数附加在流地址后。
ffmpeg -re -i d:/1.mkv -c:v libx264 -c:a aac -f flv “rtmp://192.168.2.66/live/s1?sign=585d3f2df6ed93957ec13ad6c8680fd3”
这个命令会读取本地的 d:/1.mkv 视频文件,重新编码后,以RTMP协议推送到SRS服务器的 live 应用下的 s1 流,并携带了签名参数。
2. 网页播放HLS流(带签名)
在网页端使用 hls.js 库来播放HLS流。同样,在请求 m3u8 索引文件时也需要带上相同的签名参数。
<html>
<head>
<script src=“hls.js”></script>
<script>
window.onload = function () {
const video = document.getElementById(‘video’);
if (Hls.isSupported()) {
const hls = new Hls();
// 注意:HLS地址的端口是SRS配置中http_server映射出来的8515,路径为 /live/流名.m3u8
hls.loadSource(‘http://192.168.2.66:8515/live/s1.m3u8?sign=585d3f2df6ed93957ec13ad6c8680fd3’);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, () => video.play());
} else {
console.log(‘err…’)
}
}
</script>
</head>
<body>
<video id=“video” muted autoplay=“autoplay” controls></video>
</body>
</html>
hls.js 文件可以从公共CDN获取,例如 https://www.bootcdn.cn/。
3. 测试结果验证
当签名正确时,推流和播放都会顺利进行。如果签名错误或缺失,SRS在回调认证API得到失败响应后,会立即断开连接。
下图展示了当推流URL中签名错误时,FFmpeg会收到来自SRS的拒绝信息,推流失败:

下图展示了当签名正确时,FFmpeg成功推流并开始转码推送:

使用支持RTMP协议的播放器(如VLC)直接拉流播放时,同样需要在地址后附加签名参数,例如 rtmp://192.168.2.66/live/s1?sign=xxx。

总结
通过本文的步骤,我们利用Docker快速部署了SRS流媒体服务器,并重点实现了基于HTTP回调的推拉流身份认证机制。这种方案将权限验证逻辑从流媒体服务器中解耦,由独立的业务服务(你的API)负责,非常灵活。你可以根据实际业务需求,在认证API中集成数据库查询、Token验证、权限等级校验等复杂逻辑,从而构建一个安全、专业的流媒体服务。对于想深入探讨更多系统架构和实战细节的开发者,欢迎在云栈社区交流分享。
