官网有一页叫 Hall of Shame,专门挂「用了 FFmpeg 却不履行 LGPL 义务」的产品。 这一页的存在,说明 FFmpeg 的许可证不是一句「开源免费」能说清的。
1.1.1 讲了去哪儿查,这一节讲「查到了也不能随便用」。 1.1.3 讲这个项目自己历史上闹过的一次分裂。
一、耻辱柱上挂的到底是什么行为
LGPL 允许你闭源使用,但要求两件事:
义务 具体要做什么 违反了会怎样
声明 在文档里写明用了 FFmpeg 及版本 被挂上耻辱柱 回馈 改过 FFmpeg 源码就要公开改动 被要求开源或下架 可替换 动态链接,让别人能换掉这份库 被认定为衍生作品
三条里最容易踩的是第三条:静态链接。 把 libav*.a 直接编进自己的 exe,用户就没法换库了,这在 LGPL 下算衍生作品。
所以商业播放器的常规做法是:动态链接 libav*.dll,随包附上许可证文本, 在「关于」里写一句「本产品使用 FFmpeg」。这三件事做完,才算干净。
二、从代码里能看见的那条边界
FFmpeg 自己的代码和它调用的外部库,在名字上就分开了:
名字长什么样 谁写的 许可证归谁
h264、aac、vp8 FFmpeg 自己写 LGPL libx264、libx265 外部项目,FFmpeg 去调 GPL libvpx、libopus 外部项目,FFmpeg 去调 BSD libfdk_aac 外部项目,协议不兼容 通常不编进来
这条分界线非常好用:看到名字以 lib 开头,就去看那个项目自己的许可证; 没有 lib 前缀的,是 FFmpeg 自己的,归 LGPL。
所以「FFmpeg 是什么许可证」这个问题的正确答案是: 看你装的这一份 configure 怎么写的。裸装是 LGPL,加了 --enable-gpl 就整体变 GPL。
三、为什么商业产品绕不开这个坑
因为最好的 H.264 编码器就是 x264,而 x264 是 GPL。
选择 编码质量 许可证代价
用 libx264 最好 整个产品要 GPL 用 openh264 够用 BSD,但要另装 用硬件编码 看芯片 驱动自带的,通常没这个问题 付钱买授权 最好 花钱,但能闭源
四条路的取舍很清楚:要么开源、要么换实现、要么买授权。 耻辱柱上的产品,基本都是选了第一条路却不想承担后果。
顺带说一句:个人用完全不用管这些。 GPL 约束的是「分发」,你自己编一个放自己机器上用,怎么折腾都行。
四、同一份源码,编出不同能力
这一点在本机的构建上能直接看到:有些滤镜有,有些没有。
滤镜 依赖什么 很多构建里没有
scale 无,纯算法 一定有 overlay 无,纯算法 一定有 drawtext freetype 与 harfbuzz 常见缺 subtitles libass 常见缺
这跟许可证是同一件事的两面: 每多接一个外部库,就多背一份许可证义务和多一层依赖。 打包的人为了省事,能关就关。
所以你手上这份 FFmpeg 的能力,是别人替你做的取舍。 知道自己缺什么,比抱怨「教程里的命令跑不通」有用得多。
五、动手 Demo:谁在偷偷用它,又不想认
这一段把「外挂」与「自研」两类编解码器数出来, 再看一个「同一份源码、不同构建」的实例。
import av
import av.filter
libs = sorted([c for c in av.codecs_available if c.startswith(u"lib")])
print(u"外挂组件", len(libs), libs)
print(u"自研组件", len(av.codecs_available) - len(libs))
for n in (u"scale", u"overlay", u"drawtext", u"subtitles"):
print(n, n in av.filter.filters_available)
实跑输出:
--------------------------------------------------------------------
FFmpeg 耻辱柱——谁在偷偷用它,又不想认
--------------------------------------------------------------------
**① 耻辱柱上挂的不是「盗版」,是「违反 LGPL 却不改」**
**FFmpeg 的核心是 LGPL:你可以闭源用,但两个义务必须尽到——**
**一是声明用了它,二是把对它的修改也开源。**
**大量商业播放器两样都不做,被挂到官网的 Hall of Shame 页。**
**② 耻辱柱的判据,在代码里能直接验证:库的边界在哪个符号上**
**本机这 13 个编解码器是「外挂」的,名字以 lib 开头:**
外挂组件(上半) 外挂组件(下半)
------------------------------------------
libdav1d libvpx-vp9
libmp3lame libwebp
libopencore_amrnb libwebp_anim
libopencore_amrwb libx264
libopus libx264rgb
libsvtav1 libx265
libvpx
**名字里带 lib 的,是 FFmpeg 去调别人的库;不带 lib 的,是 FFmpeg 自己写的。**
**这一条分界线,就是许可证的分界线。**
**③ 自己写的那些,才是 LGPL 覆盖的范围**
类别 数量 许可证归谁
-------------------------------------------------------
FFmpeg 自写 544 LGPL 2.1 起
外挂第三方库 13 看各家,多半是 GPL 或 BSD
**所以「FFmpeg 是什么许可证」这个问题没有单一答案:**
**裸装是 LGPL,一旦 configure 时加了 --enable-gpl 去接 x264,整个产物就变 GPL。**
**④ 一个能亲手验证的例子:这个构建里没有 drawtext**
滤镜 本机有没有 为什么
-----------------------------------------------------------------
scale 有 纯算法,不需要外部库
overlay 有 纯算法,不需要外部库
drawtext 没有 要 freetype 与 harfbuzz,没编进来
**同一份 FFmpeg 源码,别人编出来有 drawtext,这个构建没有——**
**差别不在版本,在 configure 时开了哪些开关。**
**耻辱柱上的产品,很多就是在这个环节把 GPL 组件编进了闭源程序。**
第一张表把 13 个外挂组件摊开,两列排。 名字里带 lib 的,是 FFmpeg 去调别人;不带的,是 FFmpeg 自己写的。
第二张表是这条分界线的量化:557 个里 544 个自研、13 个外挂。 LGPL 覆盖的只是那 544 个的代码,不包括 x264 那三个。
第三张表最有意思:drawtext 不在这个构建里。 同一份源码,官方完整版编得出 drawtext,这个构建编不出来—— 差别不在版本,在 configure 时开没开 freetype。
所以「耻辱柱」这件事往深了看,其实是个很朴素的道理: 每个外部组件都带着一份义务,编进去容易,甩掉难。
30 秒实验
- 数外挂:
ffmpeg -encoders | grep lib(Linux/Mac)或ffmpeg -encoders | findstr lib(Windows),看你的构建挂了几个外部库。 - 查 GPL:
ffmpeg -version第二行里搜--enable-gpl。有这一项,你这个构建就是 GPL 的,别拿它做闭源产品。 - 找一个缺失的:
ffmpeg -filters | grep drawtext,如果没输出,说明你的构建也没编 freetype,第六章的文字水印得换机器做。
常见误区
- 以为「开源」等于「随便用」。LGPL 只是允许闭源,不是允许不认账。声明、回馈、可替换三条义务,少一条就算违反。
- 以为 GPL 会传染到「用了 FFmpeg 的网站」。GPL 约束的是分发软件,你搭个网站在服务器上跑,不构成分发,没有开源义务。
- 以为静态链接更省事。在 LGPL 下静态链接反而更麻烦——用户换不了库,就得按衍生作品处理。省的那点部署成本,往往要用许可证风险来还。
自测三问(点开对答案)
1. 一个商业播放器动态链接了 libavcodec.dll,没改源码,需要在「关于」里写什么? —— 写明使用了 FFmpeg、给出许可证文本、说明怎么获取源码。三件事都做了,就不算违反 LGPL。 2. 为什么 libfdk_aac 常常不在开源构建里? —— 它的许可证与 GPL 不兼容,而很多构建同时开了 GPL 组件。两者放一起会冲突,所以打包者干脆不带它。 3. 「FFmpeg 是 LGPL 的」这句话在什么情况下是错的? —— 当这个构建 configure 时加了 --enable-gpl(比如为了接 x264)时,整个产物按 GPL 分发,这句话就错了。- ☐ (本节完,下一节 1.1.3 Libav 政变)