VLC 除了播放,还能用一条命令把文件变成 RTSP 服务。 它挑 8554 而不是标准的 554,是因为端口权限。
3.2.3 讲怎么把声音画成图,这一节跳出 ffmpeg,讲一个能当服务器用的工具。 3.3 回到 ffprobe,把「看信息」这件事讲透。
一、VLC 的三个角色
同一个程序,换个参数就是另一个角色:
角色 怎么做 用途
客户端 直接打开地址 看别人的流 服务器 用 sout 参数推流 把本地文件变成 RTSP 转码器 在 sout 里挂 transcode 边推边换编码
第二行的写法是 --sout 后面接一段 #rtp{sdp=rtsp://:8554/x}。
拆开读就是三件事:按 RTP 打包、对外宣告一个 RTSP 地址、监听 8554 端口。
第三行是它的加分项:不用先转码再推,可以边推边换。 但要注意——转码那一步会吃 CPU,一台机器同时推几路就撑不住了。
二、为什么是 8554 不是 554
RTSP 的标准端口是 554,但 VLC 默认用 8554:
端口 说明 跨平台差异
554 RTSP 标准端口 类 Unix 要 root 才绑得上 8554 VLC 的默认替代 任何用户都能绑
类 Unix 系统规定 1024 以下端口只有 root 能绑,这是为了防冒充系统服务。 Windows 没有这条限制,所以在本机测 554 也能绑下来——那是平台差异,不是规则不存在。
这条差异的实际影响是:同一份脚本,在 Windows 上跑得好好的, 搬到 Linux 服务器上就抛 PermissionError。那时候要么退到 8554,要么给它加权限。
三、排障顺序:先 ffprobe 再 ffplay
服务起来之后,验证的步骤有明确顺序:
步骤 命令 看到什么算成功
起服务 vlc 片子.mp4 --sout … VLC 不退出 探流 ffprobe rtsp://127.0.0.1:8554/x 打出流信息 拉流 ffplay rtsp://127.0.0.1:8554/x 出画面
为什么先 ffprobe?因为它只需要「SDP 协商通过」就能打出流信息,不需要真的解码显示。 所以它能通过,说明网络这一层没问题,后面的问题就一定在显示那一层。
反过来,如果 ffprobe 都打不出东西,那 ffplay 一定也不行—— 这时候去查播放器设置是白费功夫,该查的是地址、端口、防火墙。
四、动手 Demo:一条命令起一个服务
沙箱里没有 VLC,也没有摄像头,但可以直接验证「端口这一层」。 这一段实测本机两个 RTSP 端口能不能绑,并说明哪一层测不到。
import socket
# 只看端口能不能绑,不起真服务
for port in (554, 8554):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
s.bind((u"127.0.0.1", port))
print(u"%d 能绑" % port)
except OSError as e:
print(u"%d 绑不上,错误码 %d" % (port, e.errno))
finally:
s.close()
实跑输出:
--------------------------------------------------------------------
VLC 作为 RTSP 流媒体服务器——一条命令起一个服务
--------------------------------------------------------------------
**① VLC 除了播放,还能当服务器用**
角色 怎么做 用途
-------------------------------------------------------------
客户端 直接打开地址 看别人的流
服务器 用 sout 参数推流 把本地文件变成 RTSP
转码器 在 sout 里挂 transcode 边推边换编码
**第二行的写法是 `--sout` 后面接一段 `#rtp{sdp=rtsp://:8554/x}`——**
**意思是「按 RTP 打包,对外宣告一个 RTSP 地址,端口 8554」。**
**② 为什么用 8554 而不是标准的 554**
端口 说明 跨平台差异
--------------------------------------------------------
554 RTSP 标准端口 类 Unix 要 root 才绑得上
8554 VLC 的默认替代 任何用户都能绑
**类 Unix 系统规定 1024 以下端口只有 root 能绑,这是为了防冒充系统服务。**
**Windows 没有这条限制,所以下面实测可能显示 554 也能绑——那是平台差异,不是规则不存在。**
**③ 本机这两个端口能不能绑,直接试**
端口 结果 说明
--------------------------
554 能绑 空着
8554 能绑 空着
**本机 554 也能绑下来,因为这是 Windows——没有 1024 以下端口要特权的规定。**
**换到 Linux 上同一行代码会抛 PermissionError,那时候就必须退到 8554。**
**注意「能绑」不等于「服务能跑」:这里只证明端口没被别的程序占着,**
**RTSP 协议那一层要 VLC 真的起来才有,沙箱里没有 VLC,只能验到端口这一层。**
**④ 拉流端用 ffplay 验证,三行就够**
步骤 命令 看到什么算成功
--------------------------------------------------------------------------------
起服务 vlc 片子.mp4 --sout "#rtp{sdp=rtsp://:8554/x}" VLC 不退出
拉流 ffplay rtsp://127.0.0.1:8554/x 出画面
探流 ffprobe rtsp://127.0.0.1:8554/x 打出流信息
**第三行是关键:ffprobe 能打出 stream 信息,说明 SDP 协商通了。**
**这一步不通,ffplay 一定也不通——所以排障顺序是先 ffprobe 再 ffplay。**
SO_REUSEADDR 是为了避免「刚关掉马上重开」时报端口占用。
它不影响结论,只是让实验能连续跑。
本机 554 也能绑下来,因为这是 Windows。
同一段代码在 Linux 上会抛 PermissionError(错误码 13),那就得退到 8554。
「能绑」不等于「服务能跑」:这里只证明端口没被别的程序占着。 RTSP 协议那一层要 VLC 真的起来才有,沙箱里没有 VLC,只能验到这一步。
这个分层的判断方法可以推广:任何「服务起不来」的问题, 先分清楚是「端口占不着」还是「协议不通」——两者的处理方向完全不同。
30 秒实验
- 起一个:
vlc 片子.mp4 --sout **探一次**:ffprobe rtsp://127.0.0.1:8554/x`,能打出 stream 就说明 SDP 通了。 - 换端口:把 8554 改成 554 再试一次,在 Linux 上会看到权限错误。
常见误区
- 在 Linux 上直接用 554。1024 以下端口要 root,普通用户会 PermissionError。用 8554。
- 以为 ffprobe 打不出流就是播放器的问题。ffprobe 只要 SDP 通就能出信息,它失败说明网络层就没通。
- 边推边转码还推多路。转码吃 CPU,几路一起推就会掉帧,最后表现是「拉流端卡」。
自测三问(点开对答案)
1. VLC 默认为什么用 8554 端口? —— 因为类 Unix 系统规定 1024 以下端口只有 root 能绑。8554 是它挑的替代端口,普通用户就能用。 2. 验证 RTSP 服务为什么先跑 ffprobe 而不是 ffplay? —— ffprobe 只需要 SDP 协商通过就能打出流信息,不能显示画面。它通过了说明网络层没问题,问题在显示层。 3. `#rtp{sdp=rtsp://:8554/x}` 这段参数做了几件事? —— 三件:按 RTP 打包、宣告一个 RTSP 地址、监听 8554 端口。地址里留空主机名表示监听所有网卡。- ☐ (本节完,下一节 3.3 ffprobe 工具简介)