🎬 第十四章 FFmpeg直播应用综合案例分析
📄 一句话概括

五个开源项目,选型只看三个问题。 三个都答「是」,就只剩两个。

📝 本节和前面几节的关系

14.2.1 讲了一个系统要有什么,这一节讲拿什么来搭。 14.3 开始用 FFmpeg 真推流。

一、五个项目分别是什么

前面各章陆续出现过五个开源项目,这里把它们摆在一起看:

项目 形态 起点 一句话定位 适合


Live555 C++ 库 2003 协议栈小而全,改多过用 教学与定制 EasyDarwin Go 重写 2012 开箱即用,功能少 快速验证 nginx-rtmp C 模块 2013 寄在 Nginx 里 已有 Nginx SRS C++ 2013 国产,集群与 WebRTC 都做 中大型自建 ZLMediaKit C++ 2017 协议最全,接口最现代 多协议接入

注意「形态」这一列:前两个是独立进程,第三个是模块。 模块这一类的部署方式完全不同——它不是「起一个服务」, 而是「往已有的 Nginx 里加一段配置再重编」。

这就是第 10.3 节为什么要自己编译 nginx-rtmp-module,而不是 apt install。 因为它根本不是一个能装的东西,它是一个源码目录。

二、能力矩阵

把「支持哪些协议」摊开,比看文档快:

项目 RTSP RTMP HTTP-FLV HLS WebRTC GB28181


Live555 有 无 无 无 无 无 EasyDarwin 有 有 有 无 无 无 nginx-rtmp 无 有 无 有 无 无 SRS 有 有 有 有 有 有 ZLMediaKit 有 有 有 有 有 有

六种协议全支持的只有两个:SRS 与 ZLMediaKit。 这不是巧合——它们也是现在自建直播平台的两个主流选择。

协议越全,意味着「来什么流都能接」,这在真实项目里比性能更值钱。 因为性能不够可以加机器,协议不支持只能换服务器。

反过来,Live555 只支持 RTSP 一种,但它在 RTSP 这一种上做得最深。 所以它适合「就是要做 RTSP,别的不要」的场景,比如摄像头接入网关。 它的定位从来不是「通用服务器」,而是「RTSP 工具箱」。

三、选型只看三个问题

与其比参数,不如先回答三个业务问题:

问题 答是 答否


要不要接摄像头或国标设备 必须支持 RTSP/GB28181 RTMP 加 HLS 就够 要不要在浏览器里低延迟 必须支持 WebRTC 用 HTTP-FLV 也行 要不要多台机器一起扛 必须支持集群 单机够用

三个都答「是」,就只剩 SRS 与 ZLMediaKit。 这就是教材最后那个综合案例的选择逻辑——它不是随便挑的。

还有一条现实里的第四个问题,教材没写但很重要: 团队里有没有人改得动 C++。 这两个项目出问题时,最后都要读源码。 没有人能读,就只能等社区,而社区不一定理你。

所以选型建议是反过来的:先看团队能维护什么,再看需求。 能用 Go 的团队选 EasyDarwin,哪怕功能少一点,也比选一个看不懂的 C++ 项目强。

四、配置结构才是日常差别

同一份需求(收 RTMP、开 HLS),两边的配置只差三行,但结构完全不同:

项目 配置行 块数 写在哪


nginx-rtmp 5 1 nginx.conf 里 SRS 8 3 独立一份 srs.conf

nginx-rtmp 的配置寄生在 nginx.conf 里, 好处是复用 Nginx 的静态服务与 HTTPS; SRS 是独立进程,配置自成一体,好处是不用为了改直播参数去碰 Web 服务器。

这个差别在日常运维里很具体: 改一个 HLS 切片长度,前者要动整个 Nginx 的配置,后者只动一个文件。 而 Nginx 那份配置往往还管着别的站点,改错一处全站崩。

所以「哪个更好」没有统一答案,要看这个服务器还兼不兼别的活。 专机专用,SRS 这种独立进程更清爽;已经有一台 Nginx 在跑网站,挂个模块更省事。

五、动手 Demo:开源的流媒体服务器项目应用——五个项目怎么选

把五个项目的形态、起点、能力摊成表,再看协议覆盖。 最后真数一遍两套方案的配置行数。

PROJS = [
    ("Live555", "C++ 库", 2003, [1, 0, 0, 0, 0, 0]),
    ("EasyDarwin", "Go 重写", 2012, [1, 1, 1, 0, 0, 0]),
    ("nginx-rtmp", "C 模块", 2013, [0, 1, 0, 1, 0, 0]),
    ("SRS", "C++", 2013, [1, 1, 1, 1, 1, 1]),
    ("ZLMediaKit", "C++", 2017, [1, 1, 1, 1, 1, 1]),
]
PROTO = ["RTSP", "RTMP", "HTTP-FLV", "HLS", "WebRTC", "GB28181"]

for name, form, year, cap in PROJS:
    print("%-12s %-8s %d  支持 %d 种" % (name, form, year, sum(cap)))

full = [n for n, _f, _y, c in PROJS if sum(c) == len(PROTO)]
print("六种全支持:", full)

# 同一份需求,两边配置差多少
def count(text):
    kv = [x for x in text.splitlines() if ";" in x]
    blk = [x for x in text.splitlines() if x.rstrip().endswith("{")]
    return len(kv), len(blk)

NGINX = "listen 1935;\napplication live {\nlive on;\nhls on;"
SRS = "listen 1935;\nmax_connections 1000;\ndaemon on;\n"
SRS += "http_server {\nenabled on;\nlisten 8080;\n}\n"
SRS += "vhost __defaultVhost__ {\nhls {\nenabled on;\n}\n}\n"
print("nginx-rtmp", count(NGINX), "SRS", count(SRS))

实跑输出:

--------------------------------------------------------------------
开源的流媒体服务器项目应用——五个项目怎么选
--------------------------------------------------------------------
**① 先看它们分别是什么**

  项目           形态        起点     一句话定位                   适合
  -------------------------------------------------------------------------------
  Live555        C++ 库      2003     协议栈小而全,改多过用       教学与定制
  EasyDarwin     Go 重写     2012     开箱即用,功能少             快速验证
  nginx-rtmp     C 模块      2013     寄在 Nginx 里                已有 Nginx
  SRS            C++         2013     国产,集群与 WebRTC 都做     中大型自建
  ZLMediaKit     C++         2017     协议最全,接口最现代         多协议接入

  **注意「形态」这一列:前两个是独立进程,第三个是模块。**
  **模块这一类的部署方式完全不同——它不是「起一个服务」,**
  **而是「往已有的 Nginx 里加一段配置再重编」。**
  **这就是第 10.3 节为什么要自己编译 nginx-rtmp-module,而不是 `apt install`。**

**② 能力矩阵:把「支持哪些协议」摊开看**

  项目           RTSP     RTMP     HTTP-FLV     HLS     WebRTC     GB28181
  ----------------------------------------------------------------------------
  Live555        有       无       无           无      无         无
  EasyDarwin     有       有       有           无      无         无
  nginx-rtmp     无       有       无           有      无         无
  SRS            有       有       有           有      有         有
  ZLMediaKit     有       有       有           有      有         有

  **六种协议全支持的只有 2 个:SRS、ZLMediaKit。**
  **这两个也是现在自建直播平台的两个主流选择,不是巧合——**
  **协议越全,意味着「来什么流都能接」,这在真实项目里比性能更值钱。**

  **反过来,Live555 只支持 RTSP 一种,但它在 RTSP 这一种上做得最深。**
  **所以它适合「就是要做 RTSP,别的不要」的场景,比如摄像头接入网关。**

**③ 选型只看三个问题**

  问题                         答是                       答否
  ----------------------------------------------------------------------------
  要不要接摄像头或国标设备     必须支持 RTSP/GB28181     RTMP 加 HLS 就够
  要不要在浏览器里低延迟       必须支持 WebRTC            用 HTTP-FLV 也行
  要不要多台机器一起扛         必须支持集群               单机够用

  **三个都答「是」,就只剩 SRS 与 ZLMediaKit。**
  **这就是教材最后那个综合案例的选择逻辑——它不是随便挑的。**

  **还有一条现实里的第四个问题,教材没写但很重要:**
  **团队里有没有人改得动 C++。**
  **这两个项目出问题时,最后都要读源码。**
  **没有人能读,就只能等社区,而社区不一定理你。**

**④ 同一份需求,两边的配置差多少**

  项目           配置行     块数     写在哪
  --------------------------------------------------------
  nginx-rtmp     5          1        nginx.conf 里
  SRS            8          3        独立一份 srs.conf

  **两者只差 3 行,差别在结构:**
  **nginx-rtmp 的配置寄生在 nginx.conf 里,好处是复用 Nginx 的静态服务与 HTTPS;**
  **SRS 是独立进程,配置自成一体,好处是不用为了改直播参数去碰 Web 服务器。**
  **这个差别在日常运维里很具体:**
  **改一个 HLS 切片长度,前者要动整个 Nginx 的配置,后者只动一个文件。**

五个项目里,支持协议从 1 种到 6 种,跨度很大。 六种全支持的只有 SRS 与 ZLMediaKit,这两个也是现在的主流选择。 配置那份对比:nginx-rtmp 是 5 行 1 块,SRS 是 8 行 3 块,只差三行。 差的三行全在「结构」上——SRS 多了一个 http_server 块和一个 hls 块。 这点行数差异在部署时几乎感觉不到,但在改配置时差别很大。 所以选型不要只看「谁功能多」,要看「谁的结构适合你的运维方式」。

30 秒实验

  1. 只接一路摄像头做监控,猜选哪个——Live555 或 EasyDarwin 都够,不必上 SRS。
  2. 要在浏览器里看 200 毫秒延迟的直播,猜必须有什么——WebRTC,于是只剩 SRS 与 ZLMediaKit。
  3. 已有的 Nginx 在跑三个网站,猜挂模块有什么风险——改错一处全站崩,所以要单独做配置测试。

常见误区

  1. 「功能最多的就是最好的」——还要看团队能不能维护。
  2. 「nginx-rtmp 是 apt 装的」——它是源码模块,要自己编。
  3. 「Live555 不能用于生产」——RTSP 网关场景它是最优解。
自测三问(点开对答案) 1. 六种协议全支持的是哪两个项目? —— **SRS 与 ZLMediaKit**。 2. 选型要先回答哪三个问题? —— **接不接摄像头、要不要低延迟、要不要集群**。 3. nginx-rtmp 与 SRS 的配置差别在哪? —— **前者寄生在 nginx.conf,后者独立一份配置**。

相关笔记