ffplay 比另外两个多要三样东西:SDL2、图形界面、声卡。 少了任何一样,它就连窗口都开不起来。
3.1 讲了三个工具的分工,这一节专门讲那个「要窗口」的。 3.2.1 到 3.2.4 分别讲它的常用参数、高级参数、可视化与外部服务器。
一、它比另外两个多要什么
同样是链接那七个库,ffplay 还额外要三样系统层面的东西:
依赖 ffmpeg 要吗 ffplay 要吗
libav* 七个库 要 要 SDL2 不要 要 图形界面 不要 要 声卡设备 不要 要
这张表解释了一个非常常见的现象:服务器上 ffmpeg 跑得好好的,ffplay 一敲就报 SDL 错。 不是装坏了,是那台机器本来就没有图形环境——SDL 起来找不到窗口系统。
那种场合要做的是「把流转出去」而不是「在本地看」,也就是第八章的推流。 所以「ffplay 起不来」不是故障,是选错了工具。
二、三种启动方式
区别只在输入是什么,参数一个都不用改:
输入 命令 要注意什么
本地文件 ffplay 片子.mp4 最常用,直接开 网络流 ffplay rtmp://… 或 http://… 要等缓冲,起播慢 采集设备 ffplay -f dshow -i video=… 平台相关,要先列设备
第二行的「等缓冲」是可以调的:默认会先攒一段再开始放。
想快就 -fflags nobuffer,但代价是网络一抖就卡;想稳就 -infbuf,代价是吃内存。
第三行的 -f dshow 是必须的:设备没有扩展名,ffmpeg 猜不出来。
这也是 3.11.4 那一节要专门讲设备的原因——它是 demuxer 里最特殊的一类。
三、窗口里那几个键
参数表背不下来没关系,这几个键更常用:
按键 作用 什么时候用
q 或 Esc 退出 随时 空格 或 p 暂停/继续 想看清某一帧 s 单帧步进 逐帧检查画面 f 全屏切换 看画质细节 ← → 快退/快进十秒 跳着看
第三行那个 s 是排查画面问题的第一把工具。
一帧一帧往前走,能看清哪一帧开始花屏、哪一帧偏色——反复重播是看不出这个的。
还有一个没写在表上的:按 a 切换音轨。
多语言素材里这条键比参数好用,因为它不用重开文件。
四、动手 Demo:它比另外两个多要三样东西
沙箱起不了播放窗口,但可以验证它「要吃的那份数据」是通的。 这一段确认解码链能走通,并明确标出哪一层测不到。
import os
import av
import numpy as np
# 造一份 5 秒素材,就是 ffplay 要吃的东西
c = av.open(u"src.mp4", u"w")
s = c.add_stream(u"libx264", rate=25)
s.width, s.height, s.pix_fmt = 160, 90, u"yuv420p"
for i in range(125):
a = np.zeros((90, 160, 3), dtype=np.uint8)
a[:, :, 0] = (i * 2) % 256
f = av.VideoFrame.from_ndarray(a, format=u"rgb24")
for pk in s.encode(f):
c.mux(pk)
for pk in s.encode(None):
c.mux(pk)
c.close()
# 验证解码链(ffplay 的第一半工作)
c = av.open(u"src.mp4")
st = c.streams.video[0]
n = sum(1 for _ in c.decode(video=0))
c.close()
print(u"文件 %d 字节" % os.path.getsize(u"src.mp4"))
print(u"解出 %d 帧 分辨率 %dx%d" % (n, st.width, st.height))
实跑输出:
--------------------------------------------------------------------
ffplay 工具简介——它比另外两个多要三样东西
--------------------------------------------------------------------
**① ffmpeg 只用库,ffplay 还要用系统的东西**
依赖 ffmpeg 需要吗 ffplay 需要吗
-----------------------------------------------------
libav* 七个库 要 要
SDL2 不要 要
图形界面 不要 要
声卡设备 不要 要
**这张表解释了一个常见现象:服务器上 ffmpeg 跑得好好的,ffplay 一敲就报 SDL 错。**
**不是装坏了,是那台机器本来就没有图形环境。**
**② 三种启动方式,区别只在「输入是什么」**
输入 命令 注意
--------------------------------------------------------
本地文件 ffplay 片子.mp4 最常用
网络流 ffplay rtmp://… / http://… 要等缓冲
采集设备 ffplay -f dshow -i video=… 平台相关
**第二种要留意缓冲:默认会先攒一段再开始放,表现是「敲下去要等几秒才出画面」。**
**调 `-fflags nobuffer` 或者 `-probesize` 能把这个等待压短。**
**③ 播放窗口里那几个键,比参数表更好用**
按键 作用 什么时候用
---------------------------------------------------
q 或 Esc 退出 随时
空格 或 p 暂停/继续 想看清某一帧
s 单帧步进 逐帧检查画面
f 全屏切换 看画质细节
← → 快退/快进 10 秒 跳着看
**`s` 那个键是排查画面问题的第一把工具:一帧一帧看,比反复重播有用得多。**
**④ 沙箱里没有 ffplay.exe,但可以确认它的数据源是通的**
项 值 说明
-------------------------------------------------------
素材存在 9606 字节 ffplay 要吃的东西
能解出帧 125 帧 说明解码链通
分辨率 160x90 窗口初始大小
ffplay.exe 没有 沙箱只装了库,没装外壳
**最后一行是关键:这一段证明的是「解码链通」,不是「窗口能开」。**
**窗口那一层要 SDL 和桌面,沙箱给不了,所以文案里不写「实测播放成功」。**
这一段证明的是「解码链通」,不是「窗口能开」。 窗口那一层要 SDL 和桌面环境,沙箱给不了,所以文案里不写「实测播放成功」。
这个区分不是文字游戏:很多「ffplay 放不了」的问题,原因是权限、显卡驱动、 远程桌面会话没有 3D 加速——这些都在窗口那一层,跟解码一点关系都没有。
判断到底是哪一层出问题,有个简单办法:先跑 ffprobe。 ffprobe 能打出流信息,说明文件和解码器都没问题,锅在窗口那一层。
30 秒实验
- 放一次:
ffplay 片子.mp4,然后按s步进、按p暂停,体会「一帧一帧」是什么感觉。 - 关掉一路:
ffplay -vn 片子.mp4只听不看,-an则只看不听。两个字母分别对应 video 与 audio。 - 看时间戳:
ffplay -debug_ts 片子.mp4,它会打出每一帧的 pts,同步问题一眼可见。
常见误区
- 在无桌面的服务器上用 ffplay。它依赖 SDL,需要图形界面。那种场合该推流,不是本地播放。
- 以为「ffplay 打不开」就是文件坏了。先跑 ffprobe,它能读说明文件没问题,锅在窗口层。
- 把 ffplay 当日常播放器。它没播放列表、没设置界面,定位是「验证文件」的工具。
自测三问(点开对答案)
1. ffplay 需要而 ffmpeg 不需要的三样东西是什么? —— SDL2、图形界面、声卡设备。前两个决定能不能开窗口,第三个决定有没有声音。 2. 为什么「ffplay 起不来」在服务器上是正常现象? —— 因为没有图形环境,SDL 找不到窗口系统。这不是故障,是工具选错了——该用推流而不是本地播。 3. 播放时想逐帧检查画面,按哪个键? —— `s`。按一次前进一帧,配合 `p` 暂停可以停在任意一帧上细看。- ☐ (本节完,下一节 3.2.1 ffplay 常用参数)