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

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

  1. 切一段:ffplay -ss 30 -t 10 片子.mp4 -autoexit,加 -autoexit 才能自动结束。
  2. 只要画面:ffplay -an 片子.mp4,配合 -fs 全屏看细节。
  3. 小窗预览:ffplay -x 320 -y 180 -autoexit 片子.mp4,批量过片时省屏幕。

常见误区

  1. 把 -an 和 -vn 记反。a 是 audio、n 是 no,所以 -an 是关音频。记不住就想「an=audio no」。
  2. 脚本里不加 -autoexit。放完不退,批量任务就卡在那儿,看起来像死锁。
  3. 以为 -x -y 能改变输出分辨率。它只改窗口大小,源文件的分辨率一点没变。
自测三问(点开对答案) 1. `-ss 30 -t 10` 和 `-ss 30 -to 10` 有什么区别? —— 前者放第 30 到 40 秒,后者要放到第 10 秒——终点在起点之前,结果是什么都不放。`-t` 是时长,`-to` 是绝对位置。 2. 为什么脚本里必须加 `-autoexit`? —— 不加它播放器放完会停在最后一帧等人按键,脚本就永远等在这里,批量任务会卡住。 3. `-x -y` 改了窗口大小,画质会变吗? —— 文件本身不变,但显示时会缩放。放大看着更糊是因为把已有像素拉开了,不会凭空生出细节。

相关笔记