--with-rtc 一个开关,牵出加密库、SRTP、UDP 端口三样东西。 前两样编不过会立刻发现,第三样要等观众连上来才暴露。
11.4 讲的都是 TCP 那一侧,这一节换成 UDP。 11.5.2 推流还是 RTMP,11.5.3 才用 WebRTC 播。
一、一条开关,三层依赖
./configure --with-rtc 看着只是加一个参数,实际牵动三样:
① OpenSSL:DTLS 加密与证书指纹,缺了直接编不过。 ② libsrtp:SRTP 加密媒体流,缺了编译期报找不到头文件。 ③ UDP 端口:媒体走 UDP 不走 TCP,防火墙没放行就白配。
这三层里最容易漏的是第三层。 前两层是编译期问题,编不过会立刻发现; 第三层是运行期问题,服务器自己觉得一切正常,就是观众画面出不来。
编译命令大概长这样:
./configure --with-rtc --with-ssl --with-hls --with-http-server
make -j4
./objs/srs -c conf/rtc.conf
编完一定要看 objs/srs 有没有变大。
带 RTC 的版本明显大一圈,这是最直观的「编进去了」的证据。
二、真查加密库与候选端口
DTLS 要求 OpenSSL 1.1.1 以上,本机实测是 3.5.7,够用。
但要注意:这个版本号是 Python 自带的那份 OpenSSL,
编译 SRS 用的是系统里的 openssl-devel,两者可能不是同一个。
真要确认,得在命令行敲 openssl version。
候选端口也要提前看: WebRTC 要在 SDP 里告诉对方「往哪个 IP、哪个端口发」。 本机 UDP 8000 到 8009 十个端口全都能绑,说明没被别的进程占着。 但「能绑」不等于「外部能访问」,云服务器还要单独放行 UDP 安全组。
这一节最实用的判断是这一条: 先在本机把所有候选 IP 列出来,看有几个是回环。 回环地址放进 SDP 没有任何意义——观众那边访问不到 127.0.0.1。 「本机能看、别人看不了」十次有八次是这个原因。
三、候选地址还有优先级
SDP 里每个候选都带一个优先级数字,公式是固定的:
优先级 = 类型偏好 × 2^24 + 本地偏好 × 2^8 + (256 - 分量)。
类型偏好只有四档:host 126、prflx 110、srflx 100、relay 0。 代入之后得到四个固定值:host 是 2130706431,relay 只有 16777215。 差了整整一百多倍。
这个排序就是 NAT 穿透的顺序: 先试直连(host),不通再打洞(srflx),最后才走中继(relay)。 能用直连就不用中继——中继要多绕一圈服务器,延迟和带宽都吃亏。 所以看到 SDP 里最后选中 relay,通常意味着网络环境比较差。
四、动手 Demo:编一个带 WebRTC 的 SRS,多要什么
先查依赖,再列候选地址与端口, 最后把四个类型偏好的优先级算出来。
import ssl, socket
print(ssl.OPENSSL_VERSION) # DTLS 要 1.1.1 以上
# 候选 IP:本机有几个就得列几个
ips = set()
for info in socket.getaddrinfo(socket.gethostname(), None):
ips.add(info[4][0])
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("223.5.5.5", 53)) # 只为拿出口地址,不发包
ips.add(s.getsockname()[0])
# 候选端口:能绑 = 没被占
ok = []
for pt in range(8000, 8010):
u = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
u.bind(("0.0.0.0", pt))
ok.append(pt)
except OSError:
pass
u.close()
# 优先级公式
for name, tp in (("host", 126), ("prflx", 110),
("srflx", 100), ("relay", 0)):
print(name, (tp << 24) + (65535 << 8) + 255)
实跑输出:
--------------------------------------------------------------------
编一个带 WebRTC 的 SRS,多要什么
--------------------------------------------------------------------
**① 一条开关,三层依赖**
**`./configure --with-rtc` 看起来只是加一个参数,实际牵动三样东西。**
多出来的 作用 缺了会怎样
------------------------------------------------------------------
OpenSSL DTLS 加密与证书指纹 编不过,或握手直接失败
libsrtp SRTP 加密媒体流 编译期报找不到头文件
UDP 端口 媒体走 UDP,不走 TCP 防火墙没放行,能连不能看
**这三层里最容易漏的是第三层。**
**前两层是编译期问题,编不过会立刻发现;**
**第三层是运行期问题,服务器自己觉得一切正常,就是观众画面出不来。**
**编译命令大概是:**
./configure --with-rtc --with-ssl --with-hls --with-http-server
make -j4
./objs/srs -c conf/rtc.conf
**② 真查本机的加密库够不够**
**DTLS 要 OpenSSL 1.1.1 以上,先看版本。**
项目 实测值 DTLS 够不够
-------------------------------------------------------------
OpenSSL 版本 OpenSSL 3.5.7 9 Jun 2026 够
版本号数值 3.5 -
TLS 1.3 支持 有 -
**这台机器是 3.5.7,按门槛算够用。**
**注意:Python 里的 OpenSSL 和编译 SRS 用的不一定是同一个。**
**真编译时要看 `openssl version` 与 `openssl-devel` 包,**
**不是这里查到的这个号。这一条只能当参考。**
**③ 真枚举候选地址与 UDP 端口**
**WebRTC 要在 SDP 里告诉对方「往哪个 IP、哪个端口发」。**
**这些 IP 就是候选地址,本机有几个就得列几个。**
候选 IP 来源 能用吗
-------------------------------------------
127.0.0.1 回环 只在本机
192.168.3.152 网卡地址 可以
**本机一共 2 个 IPv4 地址,其中 1 个是回环。**
**回环地址放进 SDP 没有意义:观众那边访问不到 127.0.0.1。**
**这就是「本机能看、别人看不了」最常见的原因。**
端口范围 能绑几个 说明
----------------------------------------------------------
UDP 8000~8009 10 个 能绑 = 没被别的进程占着
**端口能绑不代表外部能访问,防火墙是另一回事:**
**云服务器要单独放行 UDP,安全组里那条规则经常被忘掉。**
**④ 候选地址还有优先级**
**SDP 里每个候选都带一个优先级数字,公式是固定的:**
**`优先级 = 类型偏好 × 2^24 + 本地偏好 × 2^8 + (256 - 分量)`。**
类型 类型偏好 优先级数值 含义
--------------------------------------------------------
host 126 2130706431 本机地址,直连
prflx 110 1862270975 对端反射
srflx 100 1694498815 STUN 反射
relay 0 16777215 TURN 中继
**host 排在最前,relay 排在最后:**
**能用直连就不用中继,中继要多绕一圈服务器,延迟和带宽都吃亏。**
**这也是 NAT 穿透的顺序:先试直连,不通再打洞,最后才走中继。**
本机两个 IPv4 地址,其中一个是回环,后者放进 SDP 没有意义。 UDP 8000 到 8009 十个端口全能绑,说明没有冲突。 四个优先级:2130706431、1862270975、1694498815、16777215。 host 与 relay 差一百多倍,这就是「先直连后中继」的数值依据。
30 秒实验
- 把 UDP 范围改成 8000 到 8001,猜还剩几个能绑——还是两个,除非别的进程占着。
- 把
origin里的 IP 换成回环,看优先级变不变——不变,优先级只看类型,不看地址。 - 用
openssl version查系统那份,和 Python 报的比一比——可能不一样,编译看的是系统那份。
常见误区
- 「加了
--with-rtc就能用」——还要开 UDP 端口,否则能连不能看。 - 「relay 优先级高」——最低,它是最后的退路。
- 「回环地址也能当候选」——能当,但只有本机访问得到。
自测三问(点开对答案)
1. `--with-rtc` 会多要哪三样? —— **OpenSSL、libsrtp、UDP 端口。** 2. DTLS 要求 OpenSSL 什么版本? —— **1.1.1 以上。** 3. host 与 relay 的优先级差多少倍? —— **约一百多倍**,所以永远先试直连。- ☐ (本节完,下一节 11.5.2 推送 RTMP 视频流)