ffplay 的常用参数只分三组:控制窗口、控制内容、控制结束。 九个头参数就够覆盖绝大多数场合。
3.2 讲了它是什么,这一节讲怎么调。 3.2.2 接着讲同步、丢帧、缓冲这三组更细的。
一、控制窗口:三个
这三个只影响「怎么显示」,不碰数据:
参数 作用 例子
-x / -y 窗口宽 / 高 -x 640 -y 360 -fs 全屏启动 -fs -noborder 去掉窗口边框 -noborder
-x -y 只改窗口大小,不改视频本身的分辨率。
它是有缩放但不变码流——缩放发生在显示那一侧,源文件一个字节没动。
所以「窗口放大了画质会不会变差」这个问题的答案是:会看着更糊,但文件没坏。 因为放大是把已有的像素拉开,不会凭空生出细节。
二、控制内容:四个
这四个决定「放哪一段、放哪一路」:
参数 作用 例子
-an 不放音频 -an -vn 不放视频 -vn -ss 秒 从第几秒开始 -ss 30 -t 秒 只放多久 -t 10
前两个的字母容易记反:a 是 audio,n 是 no。所以 -an 是「没有音频」。
同理 -vn 是「没有视频」,-sn 是「没有字幕」。
后两个配起来做片段预览很顺手:-ss 30 -t 10 就是「第 30 秒起放 10 秒」。
注意这里的 -t 是从 -ss 那个位置往后算,不是绝对位置。
要绝对位置得用 -to:-ss 30 -to 40 和 -ss 30 -t 10 结果一样,
但 -ss 30 -to 10 就什么都不放了——终点在起点之前。
三、控制结束:两个
这两个在脚本里比在手动使用时更重要:
参数 作用 不加会怎样
-autoexit 放完自动退出 停在最后一帧等人按键 -loop N 循环 N 次 只放一遍
-autoexit 是脚本里必加的一项。
不加它,播放器放完不退,脚本就永远等在这里——表现是「批量预览跑到一半卡住了」。
-loop 0 是个特殊值,意思是无限循环。
做展台循环播放时用它,但要配合超时或者外部信号才能停。
四、动手 Demo:九个够用的开关
这九个参数全是 ffplay 外壳自己的逻辑,库里没有对应物。 所以这一段做的是「逐个对上库里的等价能力」,能对上的说明库这一层,对不上的老实标出来。
import av
# ffmpeg/ffplay/ffprobe 都是薄外壳,能力在库里
print(u"库里能选流:", hasattr(av.container.InputContainer, u"streams"))
# -ss 的等价物是 seek
c = av.open(u"src.mp4")
c.seek(2 * 1000000) # 跳到第 2 秒
f = next(c.decode(video=0))
print(u"seek 之后落在 %.2f 秒" % f.time)
c.close()
# -an / -vn 的等价物是按类型取流
c = av.open(u"src.mp4")
print(u"视频流 %d 条" % len(c.streams.video))
print(u"音频流 %d 条" % len(c.streams.audio))
c.close()
实跑输出:
--------------------------------------------------------------------
ffplay 常用参数——九个够用的开关
--------------------------------------------------------------------
**① 控制窗口的三个**
参数 作用 例子
------------------------------------------------
-x / -y 窗口宽 / 高 -x 640 -y 360
-fs 全屏启动 -fs
-noborder 去掉窗口边框 -noborder
**`-x -y` 只改窗口大小,不改视频本身的分辨率——它是有缩放但不变码流。**
**② 控制内容的四个**
参数 作用 例子
--------------------------------------
-an 不放音频 -an
-vn 不放视频 -vn
-ss 秒 从第几秒开始 -ss 30
-t 秒 只放多久 -t 10
**这两个搭配起来做「片段预览」很顺手:`-ss 30 -t 10` 就是「第 30 秒起放 10 秒」。**
**③ 控制结束行为的两个**
参数 作用 不加会怎样
-------------------------------------------------------
-autoexit 放完自动退出 停在最后一帧等人按键
-loop N 循环 N 次 只放一遍
**`-autoexit` 是脚本里必加的一项:不加它,播放器放完不退,脚本就永远等在这里。**
**④ 这九个参数全是 ffplay 专属,库里没有对应物**
参数 在 PyAV 里有对应吗 为什么
-----------------------------------------------------------------
-x / -y 没有 窗口是 SDL 的事
-an / -vn 有,就是不取那一路 靠 select 流实现
-ss / -t 有,就是 seseek 与截断 库里有同一套能力
-autoexit 没有 循环与退出是外壳逻辑
**所以这一节的验证方式只能到「库这一层」:能确认取流与跳转通了,确认不了窗口行为。**
**凡是「窗口」「按键」「声音从哪张声卡出」这类问题,都必须用真 exe 才能验。**
seek 对应 -ss,c.streams.video / c.streams.audio 对应 -vn / -an。
能对上的只有这两个——窗口、全屏、自动退出这些,库里完全没有概念。
这个差别不是「库不完整」,而是分工不同:
库管数据,外壳管交互。-autoexit 这种「放完退出」的事,本质上是外壳的循环逻辑。
所以「哪些参数能用库验证」这件事有个简单判据: 它改的是数据(选流、跳转、缩放),还是改的是界面(窗口、按键、退出)。 前者能验,后者只能真跑 exe。
30 秒实验
- 切一段:
ffplay -ss 30 -t 10 片子.mp4 -autoexit,加-autoexit才能自动结束。 - 只要画面:
ffplay -an 片子.mp4,配合-fs全屏看细节。 - 小窗预览:
ffplay -x 320 -y 180 -autoexit 片子.mp4,批量过片时省屏幕。
常见误区
- 把
-an和-vn记反。a是 audio、n是 no,所以-an是关音频。记不住就想「an=audio no」。 - 脚本里不加
-autoexit。放完不退,批量任务就卡在那儿,看起来像死锁。 - 以为
-x -y能改变输出分辨率。它只改窗口大小,源文件的分辨率一点没变。
自测三问(点开对答案)
1. `-ss 30 -t 10` 和 `-ss 30 -to 10` 有什么区别? —— 前者放第 30 到 40 秒,后者要放到第 10 秒——终点在起点之前,结果是什么都不放。`-t` 是时长,`-to` 是绝对位置。 2. 为什么脚本里必须加 `-autoexit`? —— 不加它播放器放完会停在最后一帧等人按键,脚本就永远等在这里,批量任务会卡住。 3. `-x -y` 改了窗口大小,画质会变吗? —— 文件本身不变,但显示时会缩放。放大看着更糊是因为把已有像素拉开了,不会凭空生出细节。- ☐ (本节完,下一节 3.2.2 ffplay 高级参数)