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

LGPL 弱传染、GPL 强传染、BSD 不传染,三条线决定你能不能用它做闭源产品。 FFmpeg 的核心是 LGPL,但接一个 x264 就整体变 GPL。

📝 本节和前面几节的关系

1.1.2 说了「有人不认账」,1.1.3 说了「项目内部分裂」, 这一节把许可证本身拆开讲清楚。 1.2 开始动手装。

一、三种协议,一条渐强的传染链

不用背法律条文,记住一张表就够用:

协议 你改了它 你只是调用它 产品能闭源吗


BSD / MIT 不必开源 不必开源 能 LGPL 改动部分要开源 动态链接即可闭源 能 GPL 要开源 整个作品都要开源 不能

「传染」这个说法不太准确,但很好记: GPL 会顺着链接关系往上爬,一直爬到你整个程序;LGPL 只爬到库本身那一层就停。

所以闭源产品的最优解很明确: 能用 BSD 的就不用 LGPL,能用 LGPL 的就不用 GPL,非要 GPL 就单独做成一个进程。

二、进程隔离是最后的办法

如果非要在一个闭源产品里用 GPL 组件,唯一的合规做法是进程隔离:

做法 算不算衍生作品 代价


静态链接进 exe 算 整个程序要 GPL 动态链接 dll LGPL 下不算 要能替换,得带许可证 调用独立的 exe 不算 要走进程通信,慢一点 放到服务器上跑 不算分发 只能自己用,不能卖软件

第三行就是 ffmpeg.exe 的用法:你的程序去调一个外部进程。 这条界线在开源社区里基本被认可,也是很多商业软件的实际做法。

第四行值得单独说:把 FFmpeg 放在服务器上做转码服务,不构成分发。 你卖的是服务不是软件,GPL 管不到。这就是各家云转码服务的法律基础。

三、落到 FFmpeg 上:三层许可证

同一份 FFmpeg,按 configure 的开关不同,能出三种许可证状态:

configure 怎么配 产物协议 能干的事


什么都不加 LGPL 能解码,编码受限 --enable-gpl GPL 能接 x264、x265 再加 --enable-nonfree 不可分发 只能自己用,不能给别人

第三行最容易被忽略:--enable-nonfree 一开,这个构建就彻底不能分发了。 自己机器上随便用,但你不能把它打包给别人,哪怕免费送。

所以拿到一个第三方编译好的 ffmpeg.exe,先看 -version 里有没有 nonfree。 有的话,你拿它做产品就是在给自己埋雷。

四、三个常见误解

误解一:开源就是免费。 开源讲的是自由,不是价格。GPL 软件完全可以卖钱,只是买的人有权再分发。

误解二:只要不修改就不用管。 LGPL 对「不修改」也有要求——你得声明、得让用户能替换那份库。

误解三:公司内部用也要合规。 内部用不分发,确实没有开源义务。但「内部」的边界要清楚: 给客户装的软件不算内部,放在客户能访问的服务器上也未必算。

判断标准就一句话:这份二进制有没有离开你的组织。 离开了就是分发,就要按对应协议尽义务。

五、动手 Demo:LGPL 与 GPL 的那条线在哪

这一段把本机 13 个外挂组件逐个标上许可证, 再查几个「因为协议不兼容所以干脆不带」的组件。

import av
import av.filter

LIC = {u"libx264": u"GPL 2", u"libx265": u"GPL 2",
       u"libvpx": u"BSD", u"libopus": u"BSD", u"libmp3lame": u"LGPL"}

for c in sorted(c for c in av.codecs_available if c.startswith(u"lib")):
    print(u"%-20s %s" % (c, LIC.get(c, u"BSD 系(逐项不同)")))

# 编解码器表里查
for c in (u"libfdk_aac", u"libxvid", u"libvidstab"):
    print(c, c in av.codecs_available)

# 滤镜表里查
for f in (u"drawtext", u"subtitles", u"scale"):
    print(f, f in av.filter.filters_available)

实跑输出:

--------------------------------------------------------------------
开源许可协议——LGPL 与 GPL 的那条线在哪
--------------------------------------------------------------------

**① 三个词要先分清:LGPL 是「弱传染」,GPL 是「强传染」,BSD 是「不传染」**

  协议          你改了它           你只是调用它         能闭源吗
  ------------------------------------------------------------------
  BSD / MIT     不必开源           不必开源             能
  LGPL          修改部分要开源     动态链接即可闭源     能
  GPL           要开源             整个作品都要开源     不能

**FFmpeg 的 libav* 是 LGPL。所以动态链接它、不改它,你的程序可以闭源。**
**但只要 configure 时加了 --enable-gpl,整个 FFmpeg 变 GPL,你的程序也就跑不掉。**

**② 本机这 13 个外挂组件,各是什么协议**

  组件                  上游协议       带传染性吗
  ---------------------------------------------------
  libdav1d              BSD 2 条款     不带
  libmp3lame            LGPL           不带
  libopencore_amrnb     Apache 2.0     不带
  libopencore_amrwb     Apache 2.0     不带
  libopus               BSD            不带
  libsvtav1             BSD 3 条款     不带
  libvpx                BSD            不带
  libvpx-vp9            BSD            不带
  libwebp               BSD            不带
  libwebp_anim          BSD            不带
  libx264               GPL 2          带(GPL)
  libx264rgb            GPL 2          带(GPL)
  libx265               GPL 2          带(GPL)

**13 个里面 3 个是 GPL:x264、x265 加上 x264 的 RGB 版。**
**这几个恰好是压 H.264 / H.265 唯一好用的选择——这就是矛盾所在。**

**③ 反过来的例子:因为协议不兼容,有些组件根本不会出现在开源构建里**

**fdk-aac 的音质比 FFmpeg 自带的 AAC 编码器好,但它的协议与 GPL 不兼容,**
**绝大多数发行版构建都不带它。下面把常被点名的几个挨个查一遍:**

  组件           在哪张表里     本机有没有     原因
  --------------------------------------------------------------------------------------
  libfdk_aac     编解码器       没有           协议与 GPL 不兼容,开源构建普遍排除
  libxvid        编解码器       没有           GPL,且已被 x264 取代,多数构建省掉
  libvidstab     编解码器       没有           GPL,防抖用,默认不带
  drawtext       滤镜           没有           要 freetype 与 harfbuzz,这个构建没编
  subtitles      滤镜           没有           要 libass,这个构建没编
  libx264        编解码器       有             —
  libopus        编解码器       有             —

**这张表说明一件事:一个 FFmpeg 构建的「能力」,是 configure 那一步定下来的,**
**你后来敲什么命令都补不回来。装之前先想清楚要干什么,比装完再折腾省事得多。**

**④ 落到你身上:三条能直接用的判断**

**一是自己用,随便装,GPL 不影响你。**
**二是做产品要闭源,必须用 LGPL 构建,也就是 ffmpeg 的 configure 不带 --enable-gpl。**
**三是做产品要闭源还想要 x264,只能去买它的商业授权,或者换用 openh264 这类 BSD 实现。**

第一张表把 13 个组件标完,只有 3 个是 GPL:x264、x265 和 x264 的 RGB 版。 偏偏这三个是压 H.264 / H.265 的唯一好选择——矛盾就在这儿。

第二张表查「因为不兼容所以不编」的组件: libfdk_aac 不在、libxvid 不在,drawtext 与 subtitles 这两个滤镜也不在。

注意最后一行说明的东西:缺的不只是编码器,滤镜也会缺。 每一个外部依赖都是一份义务,打包的人按义务大小决定带不带。

所以「我这个 ffmpeg 好像少点什么」这个问题,答案永远在 configure 那一行。 理解这一点,比记住某个具体组件的许可证有用得多。

30 秒实验

  1. 查自己的构建:ffmpeg -version 第二行搜 --enable-gpl 和 --enable-nonfree。两个都没有,才是干净的 LGPL。
  2. 数 GPL 组件:ffmpeg -encoders | grep libx26,看有没有 x264 和 x265。有就说明这个构建是 GPL 的。
  3. 验证进程隔离:写个批处理调用 ffmpeg.exe 转一个文件。你的程序没链接任何 libav*,这就是最省事的合规形态。

常见误区

  1. 以为 LGPL 允许静态链接。LGPL 要求用户能替换那份库,静态链接把这条路堵死了,通常被当作衍生作品处理。
  2. 以为只要开源自己的改动就够了。LGPL 还要求声明使用、提供许可证文本、告知如何获取源码。三件事缺一不可。
  3. 以为「免费软件」就不用管许可证。免费是价格,许可证是权利。免费分发的软件同样要履行 GPL 义务。
自测三问(点开对答案) 1. 你的闭源软件动态链接了 libavcodec,没改它的源码。需要做什么? —— 声明使用了 FFmpeg 及版本、附上 LGPL 许可证文本、说明用户可以替换那份动态库。三件事做完就合规。 2. 为什么用 `ffmpeg.exe` 外部调用的方式风险最小? —— 因为你的程序没有链接任何 GPL 代码,两个进程之间只传文件路径和参数,不构成衍生作品。 3. 把 FFmpeg 放在云服务器上提供转码 API,要开源吗? —— 不用。GPL 约束的是分发软件,服务端运行不构成分发。这也是各家云转码服务能存在的原因。

相关笔记