09 - 流媒体服务器
流媒体服务器
9.1 服务器选型概览
| 服务器 | 语言 | License | 特点 | 适用场景 |
|---|---|---|---|---|
| SRS | C++ | MIT | 高性能、功能全面、中文社区活跃 | 直播平台、企业级 |
| Nginx-RTMP | C | BSD | 基于 Nginx、简单易用 | 中小型项目 |
| MediaSoup | C++/Node.js | MIT | SFU、WebRTC 优先 | 视频会议 |
| Wowza | Java | 商业 | 功能完整、技术支持 | 企业级 |
| Red5 | Java | Apache | Java 生态 | Java 项目 |
9.2 SRS(Simple Realtime Server)
SRS 是国内最流行的开源流媒体服务器,由 Winlin 主导开发。
9.2.1 核心特性
| 特性 | 说明 |
|---|---|
| RTMP 推流 | 完整支持,包括 Enhanced RTMP (H.265/AV1) |
| HLS 输出 | 支持 HLS/DASH/HTTP-FLV/WebRTC |
| 集群 | Origin-Edge 集群、RTMP 中转 |
| 转码 | 集成 FFmpeg 转码 |
| 录制 | FLV/MP4 录制 |
| DVR | 直播回放 |
| HTTP API | 管理和统计 API |
| WebRTC | RTMP↔WebRTC 互转 |
| GB28181 | 安防监控接入 |
9.2.2 安装方式
# Docker(推荐)
docker pull ossrs/srs:5
# 源码编译
git clone https://github.com/ossrs/srs.git
cd srs/trunk && ./configure && make
# 二进制包(Ubuntu)
sudo apt install srs
9.2.3 核心配置文件
# conf/srs.conf
# SRS 主配置文件
listen 1935;
max_connections 1000;
srs_log_tank console;
# HTTP API
http_api {
enabled on;
listen 1985;
}
# HTTP Server(HLS/HTTP-FLV)
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
# RTMP 配置
vhost __defaultVhost__ {
# 最小延迟配置
min_latency on;
# GOP Cache(关键帧缓存)
gop_cache on;
gop_cache_max_frames 2500;
# 队列配置
queue {
enabled on;
capacity 2500;
}
# 转 HLS
hls {
enabled on;
hls_fragment 2;
hls_window 10;
hls_path ./objs/nginx/html;
hls_m3u8_file [app]/[stream].m3u8;
hls_ts_file [app]/[stream]-[seq].ts;
}
# 转 HTTP-FLV
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
}
9.2.4 SRS 启动与管理
# 启动 SRS
./objs/srs -c conf/srs.conf
# Docker 启动
docker run --rm \
-p 1935:1935 \
-p 1985:1985 \
-p 8080:8080 \
-v $(pwd)/conf:/usr/local/srs/conf \
ossrs/srs:5
# 查看状态
curl http://localhost:1985/api/v1/summaries
# 查看流列表
curl http://localhost:1985/api/v1/streams
9.3 Nginx-RTMP
Nginx 的 RTMP 模块,适合轻量级场景。
9.3.1 安装
# Ubuntu
sudo apt install nginx libnginx-mod-rtmp
# 或从源码编译
wget http://nginx.org/download/nginx-1.24.0.tar.gz
git clone https://github.com/arut/nginx-rtmp-module.git
tar xzf nginx-1.24.0.tar.gz && cd nginx-1.24.0
./configure --add-module=../nginx-rtmp-module
make && sudo make install
9.3.2 配置文件
# nginx.conf
rtmp {
server {
listen 1935;
chunk_size 4096;
buflen 1s;
# 直播应用
application live {
live on;
record off;
# 关键帧缓存
wait_key on;
wait_video on;
# HLS 输出
hls on;
hls_path /var/www/hls;
hls_fragment 2s;
hls_playlist_length 10s;
hls_cleanup on;
# 录制(可选)
# record all;
# record_path /var/records;
# record_suffix -%d-%b-%y-%T.flv;
# 推流鉴权(可选)
# on_publish http://localhost:8080/auth/publish;
# on_publish_done http://localhost:8080/auth/publish_done;
}
# 点播应用
application vod {
play /var/videos;
}
# 回放应用
application hls {
play /var/www/hls;
}
}
}
http {
server {
listen 8080;
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /var/www;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
# 统计页面
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
# 推流鉴权接口
location /auth {
proxy_pass http://localhost:3000;
}
}
}
9.3.3 Nginx-RTMP vs SRS 对比
| 维度 | Nginx-RTMP | SRS |
|---|---|---|
| 性能 | 中等 | 高(优化更好) |
| 功能 | 基础 RTMP/HLS | 全功能(WebRTC、GB28181 等) |
| 配置 | Nginx 风格 | 独立配置语法 |
| HTTP API | 无原生支持 | 完整 REST API |
| 集群 | 手动配置 | 原生支持 Origin-Edge |
| 社区 | 英文为主 | 中文为主、活跃 |
| 适用 | 小型项目、快速搭建 | 中大型直播平台 |
9.4 推流与拉流测试
推流测试
# FFmpeg 推流(文件)
ffmpeg -re -i test.mp4 -c copy -f flv rtmp://localhost:1935/live/stream1
# FFmpeg 推流(摄像头+麦克风)
ffmpeg -f v4l2 -i /dev/video0 -f alsa -i default \
-c:v libx264 -preset veryfast -b:v 2000k \
-c:a aac -b:a 128k \
-f flv rtmp://localhost:1935/live/stream1
# OBS 推流设置
# 服务: 自定义
# 服务器: rtmp://your-server-ip:1935/live
# 串流密钥: stream1
拉流测试
# RTMP 播放
ffplay rtmp://localhost:1935/live/stream1
# HTTP-FLV 播放
ffplay http://localhost:8080/live/stream1.flv
# HLS 播放
ffplay http://localhost:8080/live/stream1.m3u8
# curl 检查 HLS
curl -s http://localhost:8080/live/stream1.m3u8
9.5 Origin-Edge 集群
SRS 支持 Origin-Edge 两级集群架构:
┌─────────────┐
推流端 ────RTMP───→│ Origin │
│ (源站) │
└──────┬──────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐┌──────────┐┌──────────┐
│ Edge 1 ││ Edge 2 ││ Edge 3 │
│ (边缘) ││ (边缘) ││ (边缘) │
└────┬─────┘└────┬─────┘└────┬─────┘
│ │ │
▼ ▼ ▼
观众群 1 观众群 2 观众群 3
Origin 配置
# origin.conf
listen 1935;
vhost __defaultVhost__ {
# Origin 不需要特殊配置,接收推流即可
gop_cache on;
}
Edge 配置
# edge.conf
listen 1935;
vhost __defaultVhost__ {
# Edge 模式:从 Origin 拉流
cluster {
mode remote;
origin 192.168.1.10:1935;
# 多源站(备源)
# origin 192.168.1.11:1935 192.168.1.12:1935;
}
# 回源超时
source_retry 3000;
# 本地缓存
gop_cache on;
}
9.6 SRS HTTP API
SRS 提供完整的 HTTP REST API 用于管理和监控:
常用 API
# 服务器概览
curl http://localhost:1985/api/v1/summaries
# 流列表
curl http://localhost:1985/api/v1/streams
# 特定流信息
curl http://localhost:1985/api/v1/streams?app=live&stream=stream1
# 客户端列表
curl http://localhost:1985/api/v1/clients
# 特定客户端信息
curl http://localhost:1985/api/v1/clients/{id}
# 关闭客户端(踢人)
curl -X DELETE http://localhost:1985/api/v1/clients/{id}
# 启动转码
curl -X POST http://localhost:1985/api/v1/transcode \
-d '{"app":"live","stream":"stream1",
"ffmpeg":"./objs/ffmpeg/bin/ffmpeg",
"input":{"url":"rtmp://127.0.0.1:1935/live/stream1"},
"output":{"url":"rtmp://127.0.0.1:1935/live/stream1_low",
"e":"-c:v libx264 -b:v 500k -s 640x360"}}'
# 录制
curl -X POST http://localhost:1985/api/v1/dvr \
-d '{"app":"live","stream":"stream1","action":"start"}'
9.7 推流鉴权
SRS HTTP 回调鉴权
#!/usr/bin/env python3
"""
SRS 推流鉴权服务
"""
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import urllib.parse
# 允许的推流密钥
VALID_STREAM_KEYS = {
"stream_key_abc123": "user1",
"stream_key_def456": "user2",
}
class AuthHandler(BaseHTTPRequestHandler):
def do_POST(self):
content_length = int(self.headers.get('Content-Length', 0))
body = self.rfile.read(content_length).decode('utf-8')
params = urllib.parse.parse_qs(body)
action = self.path
stream_key = params.get('stream', [''])[0]
app = params.get('app', [''])[0]
print(f"[Auth] {action} app={app} stream={stream_key}")
if action == '/api/v1/streams/auth':
# 推流鉴权
if stream_key in VALID_STREAM_KEYS:
print(f"[Auth] ✅ 允许推流: {VALID_STREAM_KEYS[stream_key]}")
self.send_response(200)
self.end_headers()
self.wfile.write(b'0')
else:
print(f"[Auth] ❌ 拒绝推流: 无效密钥")
self.send_response(403)
self.end_headers()
self.wfile.write(b'-1')
else:
self.send_response(200)
self.end_headers()
def log_message(self, format, *args):
pass # 静默日志
if __name__ == '__main__':
server = HTTPServer(('0.0.0.0', 8081), AuthHandler)
print("鉴权服务运行在 http://0.0.0.0:8081")
server.serve_forever()
SRS 配置:
vhost __defaultVhost__ {
http_hooks {
enabled on;
on_publish http://localhost:8081/api/v1/streams/auth;
on_unpublish http://localhost:8081/api/v1/streams/auth;
}
}
9.8 SRS 性能优化
配置建议
# 生产环境优化配置
listen 1935;
max_connections 1000;
min_latency on;
vhost __defaultVhost__ {
# TCP 优化
tcp_nodelay on;
# GOP Cache
gop_cache on;
gop_cache_max_frames 2500;
# 消息队列
queue {
enabled on;
capacity 2500;
# 队列等待超时(秒),超过则丢帧
jitter_algorithm default; # 或 low_latency
}
# 低延迟模式
atc on; # 绝对时间戳
# TCP 发送缓冲区
send_min_interval 10;
# 减少 chunk 头开销
chunk_size 60000;
}
注意事项
- 防火墙:确保开放 1935 (RTMP)、8080 (HTTP)、1985 (API) 端口
- ulimit:高并发场景需调高系统文件描述符限制(
ulimit -n 65535) - 时间戳跳变:推流端时间戳异常会导致播放问题,SRS 的
atc on可缓解 - HLS 延迟:HLS 的延迟主要由
hls_fragment和hls_playlist_length决定 - 回源风暴:Edge 节点需配置缓存,避免所有请求都回源
- HTTPS:生产环境务必使用 RTMPS (TLS) 或通过 HTTPS 分发 HLS
扩展阅读
上一章:08 - 音频编解码 下一章:10 - 流中转与分发 — 了解 CDN、转码与录制