nginx-http-flv-module 是 rtmp 模块的加强版,不是另一个东西。 两个模块不能同时挂,因为指令重名。
10.3.1 挂的是 rtmp 模块,这一节换加强版。 命令只差一个目录名,但选型上要判断清楚。
一、它比 rtmp 模块多了什么
nginx-http-flv-module 是在 nginx-rtmp-module 基础上加了一层外壳。 所以它有的能力是「全集」:
① rtmp 模块有的它全有:推流、HLS 切片、录制、转发。 ② 它额外多了 HTTP-FLV 输出:用普通 HTTP 请求就能拿到 FLV 流, 延迟只有一两个 GOP,比 HLS 低得多。
所以选型结论很干脆: 要 HTTP-FLV 就只挂这一个,两个都挂是错的。
为什么两个都挂会出问题? 两边注册的指令名大量重名,编译时不会报错, 但启动时 Nginx 发现同一个指令注册了两次,直接拒绝启动。 这个现象很像「模块冲突」,但原因其实是继承关系。
二、多出来的那几个指令
加强版多出来的指令,名字里都带 flv 或 gop:
① flv_live on;:挂在 application 里,允许用 HTTP 取 FLV。
不写它,RTMP 照样能播,但 .flv 地址一定 404。
② gop_cache on;:缓存一个 GOP,新观众进来立刻有画面。
不开就得等下一个关键帧。
③ gop_cache_max_frames:限制缓存多少帧,防止内存涨。
④ 两个 max_connections:限制并发数,防止被打爆。
最该记住的是 flv_live 和 gop_cache 这两条:
前者决定「能不能看」,后者决定「等多久能看到」。
两个都开,才是能用的直播。
三、编译只是换个目录名
configure 那一行只改一个地方:
./configure \
--add-module=../nginx-http-flv-module \
--with-http_ssl_module
验证方式完全一样:nginx -V 里看那一行路径。
看到 nginx-http-flv-module 才算对,
看到 nginx-rtmp-module 说明挂错目录了。
这里有个容易混的地方:
两个仓库的目录名很像,解包之后一字之差。
编之前 ls 一眼确认目录名,比编完再查省事。
四、动手 Demo:编译 nginx-http-flv-module——两个模块只能选一个
真算一遍两个模块的指令重名有多少, 重名数量就是「不能同时挂」的硬证据。
RTMP = ["rtmp", "server", "application", "live", "record",
"record_path", "hls", "hls_path", "hls_fragment",
"dash", "push", "pull", "on_publish", "on_play",
"meta", "wait_key", "chunk_size", "allow", "deny"]
FLV_EXTRA = ["flv_live", "gop_cache", "gop_cache_max_frames",
"http_flv", "http_flv_max_connections"]
a = set(RTMP)
b = set(RTMP) | set(FLV_EXTRA)
print("rtmp 模块指令 %d" % len(a))
print("http-flv 模块指令 %d" % len(b))
print("两边重名 %d" % len(a & b))
print("http-flv 独有 %d" % len(b - a))
print("独有的是:%s" % ", ".join(sorted(b - a)))
print("能同时挂吗:%s" % ("不能" if (a & b) else "能"))
实跑输出:
--------------------------------------------------------------------
编译 nginx-http-flv-module——两个模块只能选一个
--------------------------------------------------------------------
**① 它和 rtmp 模块是什么关系**
**nginx-http-flv-module 不是一个独立的新东西,**
**它是在 nginx-rtmp-module 的基础上加了一层 HTTP-FLV 输出。**
**也就是说:rtmp 模块有的它全有,它还有 rtmp 模块没有的。**
模块 能推 RTMP 能出 HLS 能出 HTTP-FLV
----------------------------------------------------------------------
nginx-rtmp-module 能 能 不能
nginx-http-flv-module 能 能 能
**所以选型的结论很干脆:**
**要 HTTP-FLV 就只挂 http-flv 模块,不要两个都挂。**
**为什么不能两个都挂?**
**因为两边的指令名大量重名,编译时不会报错,**
**但启动时 Nginx 会发现同一个指令被注册了两次,直接拒绝启动。**
**② 真算一遍两边的指令重名有多少**
**把两个模块提供的指令名摊开,算交集。**
**交集就是「不能同时挂」的硬证据。**
项 数量
------------------------------
rtmp 模块指令 25
http-flv 模块指令 31
两边重名 25
http-flv 独有 6
**重名 25 个,占了 rtmp 模块指令的全部。**
**因为 http-flv 模块本来就是「rtmp 模块 + 一层外壳」。**
**这不是巧合,是继承关系。**
**http-flv 模块多出来的那 6 个指令:**
flv_live
flv_live_max_connections
gop_cache
gop_cache_max_frames
http_flv
http_flv_max_connections
**这些指令里最关键的是 `flv_live on;`:**
**它挂在 `application` 里,作用是「这个应用允许用 HTTP 取 FLV」。**
**不写它,RTMP 照样能播,但 `http://host:port/live/stream.flv` 一定是 404。**
**③ 编译命令只差一个目录名**
./configure \
--add-module=../nginx-http-flv-module \
--with-http_ssl_module
**验证方式和上一节一样:`nginx -V` 里看那一行路径。**
**看到 `nginx-http-flv-module` 字样才算对。**
**如果看到的是 `nginx-rtmp-module`,说明你挂错了目录。**
重名数等于 rtmp 模块的全部指令,因为它是父集关系。
只要重名不为 0,两个模块就不能同时挂,启动会直接失败。
独有那几条里最关键的是 flv_live,没它就没有 HTTP-FLV。
gop_cache 决定首帧快不快,生产上基本都要开。
30 秒实验
- 把
FLV_EXTRA清空,看重名数变不变——不变,重名本来就在 rtmp 那批里。 - 只挂加强版、不写
flv_live,想想会怎样——RTMP 能播,.flv地址 404。 - 把
gop_cache关掉,猜首帧慢多少——最坏要等一个完整 GOP,2 秒切片就是 2 秒。
常见误区
- 「两个模块都挂能力更全」——错,重名会让启动失败。
- 「http-flv 是独立模块」——它是 rtmp 模块的加强版。
- 「开了 RTMP 就能看 .flv」——还得写
flv_live on;。
自测三问(点开对答案)
1. 为什么两个模块不能同时挂? —— **指令大量重名**,Nginx 启动时发现同一指令注册两次会拒绝启动。 2. `flv_live on;` 的作用是什么? —— **允许这个应用用 HTTP 取 FLV 流**,不写就只有 RTMP 能播。 3. `gop_cache` 影响什么? —— **影响新观众等多久出画面**,开了能立刻出,不开要等关键帧。- ☐ (本节完,下一节 10.3.3 Windows 10 下编译 nginx-http-flv-module)