🎬 第一章 FFmpeg入门简介
📄 一句话概括

Windows 上装 FFmpeg 就是三步:解压、把 bin 目录加进 PATH、重开终端。 九成人卡在第三步——不是操作错了,是不知道 PATH 是启动时的快照。

📝 本节和前面几节的关系

1.1 讲完了来历和许可证,这一节开始动手。 1.2.2 与 1.2.3 换到 Linux 与 macOS,装法不同但验证方法一样。

一、下载哪个包

官网 Download 页给 Windows 的有三种包,名字很像,用途差得远:

包名里的关键词 里面是什么 大小


essentials 只带常用编解码器,够日常转码 几十 MB full 带全套,编解码器最齐 上百 MB shared exe 与 dll 分开,给二次开发用 更大

选哪个只看一件事:你要不要那些冷门编码器。 转 mp4、抽帧、加水印,essentials 完全够;要做老格式互转才需要 full。

shared 那一版不是给普通用户准备的。 它把 exe 和 dll 拆开,是为了让别人写程序时能链接那些 dll。 你要是只打算敲命令,选它反而多一层麻烦——dll 找不到就启动不了。

二、解压到哪儿

两个条件,缺一个后面就会出怪问题:

条件 为什么 反例


路径不含空格 很多脚本和滤镜会把空格当分隔符 Program Files 路径不含中文 部分老工具的字符集处理会挂 D:\工具\ffmpeg

推荐的写法就一种:D:\ffmpeg,解压后里面直接是 bin、doc、LICENSE。 别套两层目录,别放在桌面上(桌面路径里有用户名,常常带中文)。

为什么不放 Program Files:ffmpeg 本身不怕空格, 但你会写批处理、会用别的程序去调它,那些环节未必处理得好。 与其事后排查「为什么路径带空格就失败」,不如一开始避开。

三、PATH 是启动那一刻的快照

这是整节最要紧的一段,也是「装完不能用」的唯一原因:

你以为的 实际发生的


改完 PATH,所有窗口立刻生效 只有新开的进程才读新值 PATH 是系统里的一个实时变量 每个进程启动时复制一份,之后各管各的 关掉窗口再开一个就够了 要关掉的是所有终端,包括 IDE 里的那个

所以标准流程的最后一步永远是:把所有命令行窗口都关掉,重新开一个。 包括 VS Code 里的终端、PyCharm 里的终端、资源管理器地址栏敲的 cmd。

改 PATH 的位置在「系统属性 → 环境变量 → 用户变量里的 Path」。 加的是 bin 那一层,不是 ffmpeg 目录本身:D:\ffmpeg\bin。 加错了的表现是 where ffmpeg 找不到,但文件明明在那儿。

四、装完怎么验,出错怎么查

三条命令,从粗到细:

敲什么 该看到什么 看不到说明什么


where ffmpeg 一行完整路径 PATH 没配对,或者没重开终端 ffmpeg -version 两三行,含 configuration dll 缺失,或选错了包 ffmpeg -formats 几百行格式清单 装的是 shared 版但 dll 没放对

第一种情况最常见:文件在、PATH 也对,就是开着的窗口还是旧的。 这时候别急着改 PATH,先关窗口重开——九成的「装不上」到这一步就好了。

第二种情况说明你下的是 shared 版。 exe 旁边没有 dll,或者 dll 在另一个目录,程序起不来但报错很含糊。 换 essentials 或 full 的静态版,立刻就好。

五、动手 Demo:PATH 是启动那一刻的快照

沙箱里没有真的 ffmpeg.exe,但 PATH 的机制是通用的。 下面造一个假的 ffmpeg.bat,把「改 PATH 前后」和「老进程/新进程」两种差别量出来。

import os, shutil, subprocess, tempfile

BASE = os.environ[u"PATH"]
print(u"装之前能找到吗", shutil.which(u"ffmpeg"))

td = tempfile.mkdtemp(prefix=u"fakeff_")
with open(os.path.join(td, u"ffmpeg.bat"), u"w") as f:
    f.write(u"@echo off\r\necho fake\r\n")

os.environ[u"PATH"] = td + os.pathsep + BASE
print(u"插进 PATH 后能找到吗", shutil.which(u"ffmpeg"))

old = dict(os.environ); old[u"PATH"] = BASE
new = dict(os.environ)
print(u"老环境", subprocess.run([u"cmd", u"/c", u"where", u"ffmpeg"],
                                 env=old).returncode)
print(u"新环境", subprocess.run([u"cmd", u"/c", u"where", u"ffmpeg"],
                                 env=new).returncode)

实跑输出:

--------------------------------------------------------------------
Windows 装 FFmpeg——PATH 是启动那一刻的快照
--------------------------------------------------------------------

**① 先查现状:这个沙箱里没有 ffmpeg 可执行文件**

  查什么                      结果
  ------------------------------------------------
  PATH 里能找到 ffmpeg 吗     找不到
  PATH 里一共几个目录         36
  PyAV 里的 libav* 能用吗     能,557 个 codec

**注意第三行:PyAV 能用,说明库在;第一行找不到,说明命令行工具不在。**
**这是两件不同的事——库是给程序调用的,exe 才是给你敲的。**

**② 造一个假的 ffmpeg.bat,塞进 PATH 试试**

  动作                       结果
  -----------------------------------------
  没有 ffmpeg 时 which       找不到
  把临时目录插进 PATH 后     找到了
  找到的是哪个文件           ffmpeg.bat

**这一步只改了一个东西:当前进程的 os.environ。文件本来就在硬盘上,**
**改之前找不到不是因为文件不存在,是因为 PATH 里没有那个目录。**

**③ 关键实验:老进程拿着老 PATH,新进程才看得见**

  子进程拿到的环境       where 找得到吗
  -----------------------------------------
  改之前的 PATH 快照     找不到
  改之后的 PATH 快照     找得到

**同一个可执行文件、同一个硬盘状态,只因为传进去的环境不同,结果就不同。**
**这就是「装完 FFmpeg 必须重开一个终端」的全部原因:**
**安装程序改的是注册表或用户环境变量,已经开着的终端还揣着旧的那份。**

**④ Windows 上的标准步骤,四步**

  步     做什么                               怎么验
  ---------------------------------------------------------------------
  1      下 ffmpeg-release-essentials.zip     文件能解开
  2      解到 D:\ffmpeg(路径别有空格)       bin 目录里有三个 exe
  3      把 D:\ffmpeg\bin 加进用户 PATH       环境变量窗口里能看到
  4      关掉所有命令行,重新开一个           where ffmpeg 打出路径

**第 4 步是最常被跳过的一步,也是这一步里的「新开一个」最要紧。**
**三个 exe 分别是 ffmpeg(转换)、ffplay(播放)、ffprobe(查看),少一个都不完整。**

第一张表把现状摊开:PATH 里能找到 ffmpeg 是「找不到」,但 PyAV 的 libav* 能用。 这是两件事——库是给程序调的,exe 才是给你敲的。

第二张表只改了一个变量:当前进程的 os.environ。 文件本来就在硬盘上,改之前找不到不是因为文件不存在,是 PATH 里没有那个目录。

第三张表是全节的重点:同一份环境,只是快照不同,结果就反过来。 老快照找不到、新快照找得到—— 这就是「装完要重开终端」的全部原因,一点玄学都没有。

第四张表那四步里,第 4 步最常被跳过。 而恰恰是第 4 步,才让前三步真正生效。

30 秒实验

  1. 验 PATH:改完环境变量,关掉所有终端重开一个,敲 where ffmpeg。看到一个路径就是对了,看到两个说明装了两份。
  2. 验版本:敲 ffmpeg -version,把第二行末尾那串 --enable- 复制出来,数一数有几项。这决定了你后面能做什么。
  3. 验能力:敲 ffmpeg -filters | findstr scale,有输出说明滤镜层是完整的;顺手把 scale 换成 drawtext 再试一次,很可能就没有了。

常见误区

  1. 改完 PATH 不重开终端。九成「装了但用不了」都是这一条。PATH 在进程启动时就复制走了,之后再改系统里的值,老进程看不见。
  2. PATH 里加的是 ffmpeg 目录而不是它的 bin 目录。D:\ffmpeg 下面还有一层 bin,三个 exe 都在 bin 里。加错了的表现是 where ffmpeg 找不到。
  3. 把整个路径放进引号里。环境变量的值不要自带引号,"D:\ffmpeg\bin" 会被当成一个含引号的路径,照样找不到。
自测三问(点开对答案) 1. 改完环境变量,新开的 cmd 里 `where ffmpeg` 有输出,但 VS Code 的终端里还是找不到。为什么? —— VS Code 的终端是从 VS Code 主进程派生的,主进程在你改路径之前就启动了,揣的是旧快照。关掉 VS Code 重开就好。 2. `where ffmpeg` 打出两行路径,说明什么? —— 装了两份,或者 PATH 里加了两个目录。这时生效的是排在前面的那个,另一份怎么改都没反应——排障时先看这个。 3. 为什么建议解压到 `D:\ffmpeg` 而不是 Program Files? —— Program Files 路径里有空格。ffmpeg 本身不怕,但调用它的批处理、脚本、某些滤镜参数会被空格干扰。避开比事后排查省事。

相关笔记