🎬 第三章 FFmpeg三大常用工具及应用选项详解
📄 一句话概括

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 秒实验

  1. 起一个:vlc 片子.mp4 --sout **探一次**:ffprobe rtsp://127.0.0.1:8554/x`,能打出 stream 就说明 SDP 通了。
  2. 换端口:把 8554 改成 554 再试一次,在 Linux 上会看到权限错误。

常见误区

  1. 在 Linux 上直接用 554。1024 以下端口要 root,普通用户会 PermissionError。用 8554。
  2. 以为 ffprobe 打不出流就是播放器的问题。ffprobe 只要 SDP 通就能出信息,它失败说明网络层就没通。
  3. 边推边转码还推多路。转码吃 CPU,几路一起推就会掉帧,最后表现是「拉流端卡」。
自测三问(点开对答案) 1. VLC 默认为什么用 8554 端口? —— 因为类 Unix 系统规定 1024 以下端口只有 root 能绑。8554 是它挑的替代端口,普通用户就能用。 2. 验证 RTSP 服务为什么先跑 ffprobe 而不是 ffplay? —— ffprobe 只需要 SDP 协商通过就能打出流信息,不能显示画面。它通过了说明网络层没问题,问题在显示层。 3. `#rtp{sdp=rtsp://:8554/x}` 这段参数做了几件事? —— 三件:按 RTP 打包、宣告一个 RTSP 地址、监听 8554 端口。地址里留空主机名表示监听所有网卡。

相关笔记