强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

RTMP 协议精讲 / 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;
}

注意事项

  1. 防火墙:确保开放 1935 (RTMP)、8080 (HTTP)、1985 (API) 端口
  2. ulimit:高并发场景需调高系统文件描述符限制(ulimit -n 65535
  3. 时间戳跳变:推流端时间戳异常会导致播放问题,SRS 的 atc on 可缓解
  4. HLS 延迟:HLS 的延迟主要由 hls_fragmenthls_playlist_length 决定
  5. 回源风暴:Edge 节点需配置缓存,避免所有请求都回源
  6. HTTPS:生产环境务必使用 RTMPS (TLS) 或通过 HTTPS 分发 HLS

扩展阅读


上一章08 - 音频编解码 下一章10 - 流中转与分发 — 了解 CDN、转码与录制