FFmpeg发展轶事
2015-12-01 11:17:10 阿炯

本站赞助商链接,请多关照。 FFmpeg常用参数



1、能力集列表
-formats:列出支持的文件格式。
-codecs:列出支持的编解码器。
-decoders:列出支持的解码器。
-encoders:列出支持的编码器。
-protocols:列出支持的协议。
-bsfs:列出支持的比特流过滤器。
-filters:列出支持的滤镜。
-pix_fmts:列出支持的图像采样格式。
-sample_fmts:列出支持的声音采样格式。

2、常用输入选项
-i filename:指定输入文件名。
-f fmt:强制设定文件格式,需使用能力集列表中的名称(缺省是根据扩展名选择的)。
-ss hh:mm:ss[.xxx]:设定输入文件的起始时间点,启动后将跳转到此时间点然后开始读取数据。

对于输入,以下选项通常是自动识别的,但也可以强制设定。
-c codec:指定解码器,需使用能力集列表中的名称。
-acodec codec:指定声音的解码器,需使用能力集列表中的名称。
-vcodec codec:指定视频的解码器,需使用能力集列表中的名称。
-b:v bitrate:设定视频流的比特率,整数,单位bps。
-r fps:设定视频流的帧率,整数,单位fps。
-s WxH : 设定视频的画面大小。也可以通过挂载画面缩放滤镜实现。
-pix_fmt format:设定视频流的图像格式(如RGB还是YUV)。
-ar sample rate:设定音频流的采样率,整数,单位Hz。
-ab bitrate:设定音频流的比特率,整数,单位bps。
-ac channels:设置音频流的声道数目。

3、常用输出选项
-f fmt:强制设定文件格式,需使用能力集列表中的名称(缺省是根据扩展名选择的)。
-c codec:指定编码器,需使用能力集列表中的名称(编码器设定为”copy“表示不进行编解码)。
-acodec codec:指定声音的编码器,需使用能力集列表中的名称(编码器设定为”copy“表示不进行编解码)。
-vcodec codec:指定视频的编码器,需使用能力集列表中的名称(编解码器设定为”copy“表示不进行编解码)。
-r fps:设定视频编码器的帧率,整数,单位fps。
-pix_fmt format:设置视频编码器使用的图像格式(如RGB还是YUV)。
-ar sample rate:设定音频编码器的采样率,整数,单位Hz。
-b bitrate:设定音视频编码器输出的比特率,整数,单位bps。
-ab bitrate:设定音频编码器输出的比特率,整数,单位bps。
-ac channels:设置音频编码器的声道数目。
-an 忽略任何音频流。
-vn 忽略任何视频流。
-t hh:mm:ss[.xxx]:设定输出文件的时间长度。
-to hh:mm:ss[.xxx]:如果没有设定输出文件的时间长度的画可以设定终止时间点。

4、流标识
FFMPEG的某些选项可以对一个特定的媒体流起作用,这种情况下需要在选项后面增加一个流标识。流标识允许以下几种格式:

流序号。譬如“:1”表示第二个流。
流类型。譬如“:a“表示音频流,流类型可以和流序号合并使用,譬如“:a:1”表示第二个音频流。
节目。节目和流序号可以合并使用。
流标识。流标识是一个内部标识号。

假如要设定第二个音频流为copy,则需要指定-codec:a:1 copy

5、音频选项
-aframes:等价于frames:a,输出选项,用于指定输出的音频帧数目。
-aq:等价于q:a,老版本为qscale:a,用于设定音频质量。
-atag:等价于tag:a,用于设定音频流的标签。
-af:等价于filter:a,用于设定一个声音的后处理过滤链,其参数为一个描述声音后处理链的字符串。

6、视频选项
-vframes:等价于frames:v,输出选项,用于指定输出的视频帧数目。
-aspect:设置宽高比,如4:3、16:9、1.3333、1.7777等。
-bits_per_raw_sample:设置每个像素点的比特数。
-vstats:产生video统计信息。
-vf:等价于filter:v,用于设定一个图像的后处理过滤链,其参数为一个描述图像后处理链的字符串。
-vtag:等价于tag:v,用于设定视频流的标签。
-force_fps:强制设定视频帧率。
-force_key_frames:显式控制关键帧的插入,参数为字符串,可以是一个时间戳,也可以是一个 “expr:”前缀的表达式。如“-force_key_frames 0:05:00”、“-force_key_frames expr:gte(t,n_forced*5)”

7、滤镜选项
-filter_simple 添加简单滤镜

-filter_complex FILTER 添加复杂滤镜

8、高级选项
-re:要求按照既定速率处理输入数据,这个速率即是输入文件的帧率。
-map:指定输出文件的流映射关系。例如 “-map 1:0 -map 1:1”要求将第二个输入文件的第一个流和第二个流写入到输出文件。如果没有-map选项,ffmpeg采用缺省的映射关系。

9、ffprobe参数
简单的说,ffprobe是一个多媒体流分析工具。它从多媒体流中收集信息,并且以人类和机器可读的形式打印出来。它可以用来检测多媒体流的容器类型,以及每一个多媒体流的格式和类型。它可以作为一个独立的应用来使用,也可以结合文本过滤器执行更复杂的处理。

-f format 强制使用某种格式
-sexagesimal 时间单元格式化 HOURS:MM:SS.MICROSECONDS
-pretty 格式美化
-print_format format 格式化(可选值: default, compact, csv, flat, ini, json, xml)
-of format -print_format别名
-select_streams stream_specifier 选择指定流
-sections 打印节的结构和信息
-show_data 显示包数据
-show_data_hash 显示包数据哈希值
-show_error 显示文件探测/检测错误
-show_format 显示格式或者容器信息
-show_frames 显示帧信息
-show_format_entry entry 根据格式/容器信息显示指定entry
-show_packets 显示包信息
-show_programs 显示程序信息
-show_streams 显示流信息
-show_chapters 显示章节信息
-count_frames 统计每个流的帧数
-count_packets 统计每个流的包数
-show_program_version 显示ffprobe版本
-show_library_versions show library versions
-show_versions show program and library versions
-show_pixel_formats 显示像素格式
-show_private_data show private data
-private same as show_private_data
-bitexact force bitexact output
-read_intervals read_intervals set read intervals
-default generic catch all option

10、ffplayer参数
-x 强制设置视频显示窗口的宽度
-y 强制设置视频显示窗口的高度
-S 设置视频显示的宽高
-fs 强制全屏显示
-an 屏蔽音频
-vn 屏蔽视频
-Sn 屏蔽字幕
-ss 根据设置的秒进行定位拖动
-t 设置播放视频/音频长度
-Bytes 设置定位拖动的策略,0为不可拖动,1为可拖动,-1为自动
-Nodisp 关闭图形化显示窗口
-f 强制使用设置的格式进行解析
-window_title 设置显示窗口的标题
-af 设置音频的滤镜
-Codec 强制使用设置的codec进行解码
-autorotate 自动旋转视频
-ast 设置将要播放的音频流
-vst 设置将要播放的视频流
-sst 设置将要播放的字幕流
-Stats 输出多媒体播放状态
-Fast 非标准化规范的多媒体兼容优化
-sync 音视频同步设置可设置根据音频视频进行参考,视频时间参考,或者外部扩展时间进行参考
-autoexit 多媒体播放完毕自动退出ffplay,ffplay默认播放完毕不退出播放器
-exitonkeydown 当有按键按下事件产生时退出ffplay
-exitonmousedown 当有鼠标按键事件产生时退出ffplay
-loop 设置多媒体文件循环播放次数
-framedrop 当CPU资 源占用过高时,自动丢帧
-infbuf 设置无极限的播放器buffer,这个选项常见于实时流媒体播放场景
-vf 视频滤镜设置
-acodec 强制使用设置的音频解码器
-vcodec 强制使用设置的视频解码器
-scodec 强制使用设置的字幕解码器

11、主要函数介绍
FFmpeg提供了丰富的功能,包括但不限于视频和音频的编码、解码、转码、过滤、播放等操作,几乎涵盖了多媒体处理的各个方面。在视频编辑软件、流媒体服务器,还是各种多媒体相关的开发项目中其也提供了丰富的函数调用:

1)av_register_all()
这是一个初始化函数。在使用 FFmpeg 的大多数功能之前,需要调用这个函数来注册所有可用的编解码器、解复用器、复用器等组件。它为后续的多媒体处理操作准备环境,确保系统能够识别和使用各种相关的模块。例如:
av_register_all();

2)avformat_open_input()
用于打开一个输入媒体文件。它接受文件路径和一个 AVFormatContext 指针作为参数。这个函数会尝试探测文件的格式,并初始化 AVFormatContext,为后续读取媒体文件中的流信息等操作做准备。示例代码如下:
AVFormatContext *pFormatCtx = avformat_alloc_context();
if (avformat_open_input(&pFormatCtx, input_filename, NULL, NULL)!= 0) {
    // 处理打开文件失败的情况
}

3)avformat_find_stream_info()
此函数用于读取输入媒体文件中的流信息,如音频流和视频流的参数(编码格式、帧率、分辨率、采样率等)。它需要一个已经打开的 AVFormatContext。通过这个函数,可以获取到媒体文件中各个流的详细信息,以便后续对这些流进行处理。

if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
    // 处理查找流信息失败的情况
}

4)avcodec_find_decoder()
用于查找指定的解码器。它接受一个编解码器 ID 作为参数,在已注册的解码器中查找匹配的解码器。在多媒体解码过程中,这是一个关键步骤,找到合适的解码器才能对媒体流进行正确的解码。例如:
AVCodec *pCodec = avcodec_find_decoder(codec_id);
if (!pCodec) {
    // 处理找不到解码器的情况
}

5)avcodec_open2()
这个函数用于打开找到的解码器,并初始化相关的上下文。它接受一个 AVCodecContext 和一个 AVCodec 指针作为参数,完成解码器的初始化工作,为后续的解码操作做好准备。

AVCodecContext *pCodecCtx = avcodec_alloc_context3(pCodec);
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
    // 处理打开解码器失败的情况
}

6)av_read_frame()
用于从输入媒体文件中读取一个帧数据。它从已经打开的 AVFormatContext 中读取下一个音频或视频帧,并将其存储在 AVPacket 结构体中。这个函数是在读取媒体文件数据过程中的核心函数之一。

AVPacket packet;
if (av_read_frame(pFormatCtx, &packet) >= 0) {
    // 处理读取到的帧数据
}

7)avcodec_decode_video2()(对于视频解码)和 avcodec_decode_audio4()(对于音频解码)
这两个函数分别用于解码视频帧和音频帧。它们接受相应的 AVCodecContext 和存储帧数据的结构体指针作为参数,对从媒体文件中读取到的帧数据进行解码操作,将解码后的数据存储在相应的结构体中,如 AVFrame 结构体。

// 视频解码示例
AVFrame *pFrame = av_frame_alloc();
int got_frame;
avcodec_decode_video2(pCodecCtx, pFrame, &got_frame, &packet);
if (got_frame) {
    // 处理解码后的视频帧
}

// 音频解码示例
AVFrame *pAudioFrame = av_frame_alloc();
int got_audio_frame;
avcodec_decode_audio4(pAudioCodecCtx, pAudioFrame, &got_audio_frame, &packet);
if (got_audio_frame) {
    // 处理解码后的音频帧
}

8)av_write_frame() 和 av_write_trailer()(用于输出媒体文件)
在生成输出媒体文件时,av_write_frame()函数用于将编码后的帧数据写入到输出文件中。而 av_write_trailer()则用于在写入所有帧数据后,写入文件的结尾信息,完成输出媒体文件的生成过程。

// 写入帧数据
av_write_frame(pOutputFormatCtx, &packet);

// 完成输出
av_write_trailer(pOutputFormatCtx);


射手播放器项目公开谴责腾讯违反开源协议


如果你觉得腾讯影音最新的功能十分眼熟,那么恭喜你,你猜对了。2009年岁未,射手播放器开源项目的开发日志正式发文谴责了腾讯影音的抄袭工作。

原文如下:腾讯作为一家上市公司,一家极具影响力的大型企业,以你中国互联网行业的领军者的地位,本应成为年轻人的表率。但自QQ影音推出以来,腾讯多次无视授权协议,执意践踏开源社区的知识产权的行为,实在令人难以苟同。今年11月,更被国际著名的ffmpeg发现而列入耻辱榜,作为一家具有国际影响力的华人公司,这真是情何以堪。

开源社区是人们试图用最有效率的方式集合各自的智慧、能力与时间,进而创造出改变世界的物件或思考方法的地方。是集中了所有开发者的自我价值实现。腾讯以一个超大型公司的身份,受益于开源社区,却坚持违反开源社区规则。这绝不仅仅是文字游戏,这是在这儿切切实实的拿出刀子,血淋淋地割下中国年轻开发者的活力和创造力!

开源社区的规则很简单,可以说要的不多,你甚至可以在使用开源社区的资源后,冠上自己的品牌。唯一的要求,只是继续保持开放并以此(也仅仅以此)来回馈开源社区。以一个年收入以亿计的公司,连这样简单的要求都不肯遵守,实在做了一个极不良的表率。你的行为代表说,人人都不需要尊重他人创造和贡献,完全可以只索取不回报,甚至撕破面皮,过河拆桥,唯利是图。

我想提醒腾讯的是,所谓“出乎尔者,反乎尔者”。不要创造一个可以肆意践踏规则的环境,否则终将害人害己。身为国际上市公司,你应该承担起大公司的社会责任,结束违反GPL协议的行为。更不要让中国开发者蒙羞!

Linux Firefox发行版将默认采用 FFmpeg

2015年12月上旬消息,绝大部分Linux发行版中都包含了FFmpeg,最近Mozilla也决定在Firefox中采用最新的FFmpeg包,这个决定应该也不会让人感觉到意外,虽然对Firefox而言这也是个比较重要的变化。FFmpeg是知名的多媒体框架,这套解决方案本身已经相当流行。绝大部分Linux发行版都采用该方案,且默认融入到系统中,或者至少也有其一席之地。Linux系统之一的Debian就从Libav转到了FFmpeg

FFmpeg说得具体些,是提供播放任意多媒体数据的各种应用与库的集合。它并不仅针对Linux,Windows平台上也有。它能够从源码中编译,而且对各种架构都是适用的,包括x86、ARM、PowerPC等。

关于Firefox采用FFmpeg,最早是在9月份就提出的,该特性现已加入到Firefox 43 beta版中,很快稳定版分支也将加入。Firefox的Bugzilla如此描述这项BUG条目:“将默认采用FFmpeg PDM(如果ffmpeg在系统中可用的话),默认将使用libav 9或FFmpeg 2.2。如果设置media.fragented-mp4.ffmpeg.enabled,则将允许使用libav 0.7和ffmpeg 0.8或更新版本。”

2004年11月9日,Firefox 发布了首个版本,向垄断了整个浏览器市场的 IE 发起了挑战。从某种意义上它成功了,在 Firefox 诞生之初,IE 占据了九成以上的份额,到了 2009 年 Firefox 成功占据了三分之一的市场份额。但随后由于 Google Chrome 的出现 Firefox 的份额开始萎缩,原因之一是 Chrome 确实性能更为出色,其它原因还有搜索巨头的实力要比非盈利的 Mozilla 强大得多,有足够的预算进行推广。

2016 年 Mozilla 宣布了 Quantum 计划,以致力于大幅改进浏览器性能。2017 年它发布了首个基于 Quantum 的版本,大受好评。Firefox 源于 Netscape,1998 年 Netscape 宣布将在 Mozilla 名义下开源其代码,1999 年 AOL 收购了 Netscape。

Mozilla Firefox 最早的名字叫 Phoenix,意思就是从 Netscape 灰烬中涅槃而生。但 BIOS 开发商 Phoenix Technologies 当时有个运行在 BIOS 上的浏览器叫 Phoenix browser,所以因为商标争议它改名 Firebird,但 Firebird 也有人用,当时一个流行的开源数据库就叫 Firebird,最后它更改为现在的名字 Firefox。

开发的VP9解码器比Google官方的更快

2014年3月上旬消息,开源编解码器项目FFmpeg编写的VP9解码器FFvp9比Google开发的更快。VP9是Google主导开发的下一代开源视频编解码器,压缩效率比H264高一倍,是私有编解码器H265的竞争对手。FFvp9声称在不同机器上其解码速度比Google开发的快25~50%,其多线程性能有显著改进。这一结果并不出人意料,FFmpeg开发的VP8解码器也比Google的快。

参考文档:The world’s fastest VP9 decoder: ffvp9

项目负责人 Michael Niedermayer 辞职

2015年8月上旬消息,FFmpeg社区再次发生了一件“戏剧性”的事件:担任 FFmpeg 项目负责人长达11年的 Michael Niedermayer宣布辞职

Michael 的辞职与 Libav 分支有关。Debian 项目上个月宣布用 FFmpeg 取代 Libav,一个主要理由是 Libav 的安全更新没有FFmpeg 及时。Debian 抛弃 Libav 对其打击非常大。Libav 是在2011年“起义”脱离 FFmpeg 创建的一个分支,一度吸引了包括 Debian 在内的发行版采用。但过去几年 FFmpeg 在 Michael 的领导下比 Libav 发展更快更活跃,因此许多发行版回到了 FFmpeg 的怀抱,Debian 是仅剩的一个继续使用 Libav 的主流发行版,它抛弃 Libav 项目意味着 Libav 可能会死亡。

Libav 项目开发者则指责 Michael 盗用了他们的成果。他将 Libav 的代码合并到 FFmpeg,让他成为了 FFmpeg 最大的贡献者,他递交代码一度占了新增代码的80%。但 Michael 的支持者则持相反意见。其在辞职信中称,他希望两个社区最终能合并,Libav 能重新加入 FFmpeg。但即使 Debian 准备移除 Libav,仍然没有迹象显示 Libav 考虑加入 FFmpeg。双方的分歧显然非常大,他希望他的辞职能让双方坐下来,避免彻底的分裂。

龙芯 FFmpeg 进入 v5.0 时代,全力支持 LoongArch 生态


2022年1月消息,伴随FFmpeg v5.0 的正式发布,新版本集成了对 LoongArch 生态的支持和优化。近日,龙芯中科就龙芯 v5.0 版本工作及规划进行了系统介绍。v5.0 是 FFmpeg 社区近年来最为重要的一个版本,此版本不仅增加了诸多新功能,在 API 方面也进行了重大升级。整合对 LoongArch 的支持意味着后续的开源操作系统在从上游社区集成 FFmpeg 时,都将自动包含对 LoongArch 架构的支持,免去了以往繁重的代码移植和测试工作,对于 LoongArch 生态建设至关重要。据介绍,伴随着支持 LoongArch 的 v5.0 版本发布,龙芯5000桌面处理器平台能更好地释放潜能,为龙芯电脑终端带来更佳的音视频体验,具体到使用体验以及技术支持上将有以下重要提升:

支持 4K 高码率
v5.0版本中集成了对H264、H265、VP8、VP9、MPEG4、WMV3等视频格式的最新解码优化。以H264格式为例,结合支持LoongArch架构的龙芯3A5000平台测试,性能相比龙芯3A4000平台提升75%以上,纯软件解码播放4K H264视频可以支持达到50Mbps高码率。

支持多人流畅视频及录屏
v5.0版本不仅仅针对编解码avcodec模块做了优化,还针对像素处理swscale模块做了优化,结合龙芯团队在X264项目上的编码优化以及mesa的渲染优化,可实现对视频会议系统以及录屏类应用的良好支持。以网动视频会议为例,在流畅支持多人视频会议和本地桌面共享时,龙芯CPU占用率维持在40%左右。

更全面及时的社区支持工作
龙芯团队将更为密切地与社区开发者互动,更加全面的支持LoongArch生态和FFmpeg社区建设。龙芯团队将持续为FFmpeg社区提供基于LoongArch架构的patchwork实时测试服务和FATE状态定期更新服务。希望更多的社区爱好者能够关注支持,加入到LoongArch生态的建设中。

龙芯FFmpeg展望
下一阶段,龙芯团队将持续优化龙芯5000桌面平台视频编解码软硬件协同工作,稳定保障FFmpeg社区支持工作,增加LoongArch架构对滤镜filter模块的支持,为更加出色的LoongArch生态影音体验不懈努力。

英特尔在 FFmpeg 中实现了 AV1 QSV 编码器

2022年8月,英特尔为 FFmpeg 提供了 openVPL 支持,可用于将视频编码/解码为 AV1 和其它格式。2022年10月下旬,英特尔工程师又为 FFmpeg 提供了一个 AV1 快速同步视频 (Quick Sync Video - QSV) 编码器。“快速同步” 视频编码器是指将视频从例如 DVD 或蓝光光盘快速转码为适用于手机等智能设备格式(主要是 H.264)的用例,对专业的视频工作场景非常有效。新的 qsvenc_av1/av1_qsv编码器已合并到 FFmpeg 主线。在 Windows 和 Linux 上,QSV API 可通过 Intel Media SDK 获得,Intel Quick Sync Video AV1 编码器在底层使用 oneVPL 作为视频处理库,该库是 Intel 优秀的开源 oneAPI 软件套件的一部分。从该提交可以看到 AV1 QSV 编码器的源代码,该编码器仅在启用 libvpl 时可用,MSDK 不支持 AV1 编码。

英特尔最新的 DG2/Alchemist GPU(例如最近推出的 Arc  A750 和 A770 显卡)可使用独立显卡硬件加速 AV1 编码。对于无法进行 AV1 编码的 GPU 用户,FFmpeg 在针对 libaom、rav1e 或英特尔开发的 SVT-AV1 构建时也支持基于 CPU 的 AV1 编码。其工程师于2022年12月上旬发布了最新的 “2022Q3” 以及 “2022Q41 RC1”   FFmpeg 补丁集,最新的补丁用于改进 FFmpeg 视频加速与英特尔图形,存放在英特尔的 “cartwheel-ffmpeg” 仓库中,该仓库是英特尔开发者的暂存区,用于为 FFmpeg 贡献未合并的英特尔硬件补丁。换而言之,这是一个试验区,所有补丁都需要经过审查、适当的测试,最终才能合并到上游。据外媒 Phoronix 介绍,最新的 2022Q3 系列 FFmpeg 补丁具有以下优化:
新增 Raptor Lake S 平台的 FFmpeg 支持
ffmpeg-vaapi 添加了 av1 编码支持、
ffmpeg-qsv vpp 缩放通过支持 EU、VDBOX 或 VEBOX 的 oneVPL 添加模型选择,用户可以使用 “scale_mode” 选项来选择硬件型号
对 H.265 QSV 编码的自适应 I/B 支持
ffmpeg dnn:OpenVINO 完整的 GPU 检测和分类支持
ffmpeg dnn:启用 Torch 库作为 FFmpeg DNN 后端之一

此外还有 2022Q41 RC1 系列补丁,但此系列目前尚无更改日志。对于使用 Intel Arc Graphics 硬件的用户,Intel 的 FFmpeg cartwheel 可提供最新和最好的图像驱动支持。目前英特尔的大部分工程重点都放在 DG2/Alchemist 系列显卡的支持上。但在英特尔图形硬件上进行的测试结果显示: FFmpeg 补丁的优化范围可以追溯到带集成显卡的 Tigerlake/Icelake/JasperLake 架构上,甚至还有一些 Kabylake/Comet Lake 覆盖。

喊话Google,要么交钱,否则别提Bug

FFmpeg 2025年11月表示 Google 你要么资助,要么别提 Bug,不要把压力转给免费的志愿者,可见 Google 犯了众怒。

FFmpeg 是全世界最流行的多媒体库,其核心的 libavcodec、libavformat 库应用很广泛。VLC、Kodi、Plex、Google Chrome、Firefox、YouTube 等著名软件底层都会用它,可它本身是由志愿者维护的,并没有报酬。

此外 FFmpeg 核心使用汇编语言开发的,编写汇编语言并不容易,间接也说明维护并非易事。最近出了一个很有意思的事情,Google 的一个 AI 智能体报了一个 Bug,但非常冷门,也并没有太多的危害,FFmpeg 称为“CVE 垃圾”。那为什么 FFmpeg 这么不痛快呢?不光没钱拿,还被人各种要求,换谁都不痛快。

早在今年5月份,Google 安全组织 Project Zero 发布了一个新透明政策,一旦发现 Bug,7 天内就会公开宣布 Bug 相关情况,而且 90 天内不管是否修改都会公开细节,这给所有团队带来很大的压力,尤其像 FFmpeg 这样的公益组织。所以 FFmpeg 就喊话 Google,你坐拥万亿美元的市值,既然产品很依赖 FFmpeg,可一分钱也不掏显然不合理,至少在提交Bug的时候附带修复补丁。简单来说,你要么 Show 出补丁,否则别嚷嚷!

瑞芯微就 MPP 开源合规事件致歉:启动整改工作并积极与 FFmpeg 及 GitHub 沟通

2026年2月下旬瑞芯微发布关于 MPP 开源合规事件的通告称,近期公司开源媒体框架软件 MPP 因部分代码开源许可证条款合规问题,导致其 GitHub 仓库被暂时冻结。在此向开源社区、所有受影响的合作伙伴、开发者致歉。


瑞芯微还表示,公司在事发后启动整改工作,并积极与 FFmpeg 及 GitHub 组织沟通。目前相关代码已全部替换为自主研发、符合开源协议的全新代码,并已提交至 GitHub。

据了解,此前近两年间,FFmpeg 曾多次公开指控瑞芯微存在许可违规行为,并于 2025 年 12 月 18 日向 GitHub 提交 DMCA 删除请求后,指控瑞芯微从 FFmpeg 的 libavcodec 库中抄袭数千行代码 —— 包括 H.265、AV1 和 VP9 格式的解码器,删除原始版权声明,虚假宣称著作权,并以 Apache 宽松许可证而非原始 LGPL 许可证重新分发代码。

更早之前的2024年2月,FFmpeg 就指控瑞芯微 “公然将 FFmpeg 代码直接复制粘贴” 至其驱动程序中,但该芯片制造商的最后回应表明其无意解决此事。

FFmpeg 作者轶事1

文作者:Can Artuc,源自 Medium

标题:《Every Video on Earth Runs Through His Code. He Chose Poverty. Google Sent AI Bugs.》

副标题:Its creator left in 2003. One developer chose minimum income for 11 years to keep it running. Google sent bugs, not money.

本站本节转自“非理性的程序”(2026年6月)。

地球上每个视频都经过他代码的处理。而他自己选择了贫穷。Google则发来了AI发现的漏洞。

它的创建者于 2003 年离开。一位开发者为了维持项目运转,过了 11 年最低收入的生活。Google送来了漏洞列表,而不是钱。

每天有数十亿的视频流。一个男人在维也纳靠最低收入过着贫困潦倒的生活。

你今天观看的每一个视频,无论是在 YouTube、Netflix、TikTok,还是朋友通过 WhatsApp 发给你的片段,都经过了一个叫 FFmpeg 的软件。创建它的人二十三年前就离开了,去开发别的东西。而在接下来的十年里,那个让它活下去的人,为了做这件事,刻意选择了贫穷。而 Google,这家在 Chrome 和 YouTube 中使用 FFmpeg、2025 年收入超过 4000 亿美元的公司,最近给 FFmpeg 发来了一份用AI生成的安全漏洞列表。没有补丁,没有钱,只有一个 90 天的修复倒计时。

这是 Fabrice Bellard 的故事,他可能是当今世上最高产的程序员,却选择了离开。这也是 Michael Niedermayer 的故事,他放弃了一切来承担 Bellard 留下的重担。同时,这也是一个关于整个行业如何袖手旁观,看着他无偿付出的故事。

我在科技行业工作了二十多年,专注于媒体领域,特别是视频流媒体。我知道生产环境中那些“没人管的依赖项”长什么样。这个故事并非独一无二。但它的规模之大,足以让你愤怒。

你可能从未听说过的最强程序员


Fabrice Bellard 是一位法国程序员,1972 年出生于 Grenoble。他在 2000 年以化名“Gérard Lantau”创建了 FFmpeg。他还创建了 QEMU,一个在云基础设施中广泛使用的开源虚拟化平台。他构建了 Tiny C 编译器,曾创下将圆周率计算到 2.7 万亿位的世界纪录,三次赢得国际 C 语言混乱代码大赛,并用 JavaScript 编写了一个完整的 PC 模拟器。

Terraform 和 Ghostty 的创建者 Mitchell Hashimoto 的评价很简单:“Fabrice Bellard 绝对是个现象级天才。”

可以把 Bellard 想象成一位建筑师,他设计了摩天大楼,然后把钥匙交给别人,自己立刻转身去设计下一座。他领导 FFmpeg 直到 2003 年,然后离开去创建 QEMU。接着在 2012 年又创立了电信公司 Amarisoft。

Bellard 创造了改变世界的软件,然后继续前行。而留下的人,则永远背负起了重担。

那个选择了贫穷的人

Michael Niedermayer 是一位奥地利开发者,住在维也纳。他最初是 MPlayer 的贡献者,构建了视频后处理库和 libswscale。当 Bellard 在 2003 年离开 FFmpeg 时,Niedermayer 站了出来。

他从 2004 年到 2015 年,领导了 FFmpeg 整整十一年。

根据另一位开发者 Kostya Shishkov 对 FFmpeg 历史的记述,Niedermayer 的故事与其他开源维护者截然不同:他刻意过着最低收入的生活,以避免在其他工作上浪费时间。他很少与人见面,在维护 FFmpeg 的那些年里,完全避开了各种会议。他的整个生命就是 FFmpeg。

他创建了 H.264 解码支持(你现在手机就在用这个解码器)。他构建了 FFV1 和 Snow 编码器。他编写了无数 x86 汇编优化代码,那种代码地球上只有几百人能读懂,更不用说写了。他提交了超过 4800 个补丁。

在他的辞职邮件中,Niedermayer 写道:“这并不是一个我真正喜欢过的角色,更多是我最终不得不承担的角色。”

他描述了每个人对这个角色的解读:“那个做完所有没人愿意做的工作,承担所有没人愿意承担的责任的家伙。”

想象一下,你的邻居自愿维护你所在城市每栋建筑的管道系统。不是因为有人要求他这么做,而是因为没有其他人愿意做。再想象一下,这位邻居几乎不赚钱,以便能把醒着的每一刻都花在做这件事上。

那就是 Niedermayer。

2011 年 3 月:半数团队成员出走


2011 年 3 月 13 日,一群 FFmpeg 开发者分叉了项目,并称之为 Libav。

这主要是个人原因,尽管 API 设计上的分歧也起了一定作用。开发者们对 Niedermayer 的风格感到不满。他们想要控制权。这次分叉分裂了社区、代码库以及那本就少得可怜、能在这个级别上从事多媒体工作的开发者群体。

Fabrice Bellard 仍然拥有 ffmpeg.org 域名,他拒绝将其交给“叛变”派系。一个小细节,却产生了巨大影响。这保住了 FFmpeg 的身份认同。

Niedermayer 在 Libav 阵营的持续压力下,将 FFmpeg 阵营团结在一起长达四年。这就像一个家族企业,半数员工出走,在街对面开了家竞争店铺,用着同样的配方,而最初的创始人拒绝介入。

Libav 的最后一次发布是在 2018 年,到 2020 年,该项目被普遍认为已被放弃。Niedermayer 是对的。这次分叉毫无必要。但“正确”的代价是,他在贫穷、孤立和维护着被数十亿人使用的软件的重压之上,又承受了四年额外的压力。

“FFmpeg 是你们的了”

2015 年 7 月 31 日,Niedermayer 辞职了。结束了作为领袖的十一年。他写道:“社区分裂了,当一个人身处分裂的一边,而另一边想尽一切办法要把他赶出去时,是很难继续担任领导者的。”

关于那些耗尽他生命的 Libav 合并工作:“合并带来的工作和压力是我辞职的主要原因。”

他的告别语:“FFmpeg 是你们的了。”还有一句单独的话:“FFmpeg 属于 FFmpeg 开发者和 FFmpeg 社区!”

他表示愿意继续担任顾问。他的名字至今仍在 FFmpeg 的顾问页面上。地点是:奥地利,维也纳。

一个为了项目放弃了经济保障和任何正常生活十一年的人,最终被他团结在一起的社区排挤出去。他最后的话里没有怨恨,只有一种无奈的放手。

Google的 4000 亿美元问题


这件事的荒谬程度,如果不是真的,简直可以当笑话看。

Google的 Big Sleep AI(与 DeepMind 合作开发)在 2025 年扫描了 FFmpeg 的代码库,发现了 13 个漏洞。Google将这些报告给了 FFmpeg 的志愿维护者。没有附带任何补丁,只有一个 90 天的披露倒计时:要么修复,要么我们公开。

其中一个漏洞,编号 CVE-2025-59734,是一个存在于《义军同盟 II》视频解码器中的内存漏洞。这是一款 1995 年的《星球大战》游戏。志愿者们于 2025 年 10 月 30 日免费修复了它。一个存在于三十年前用 CD-ROM 发行的游戏的解码器中的安全漏洞。

Google年收入超过 4000 亿美元。它在 Chrome 和 YouTube 中使用 FFmpeg。它承诺向 Linux 基金会的“安全开源”项目捐赠 100 万美元。但它付给 FFmpeg 的钱,是零。

FFmpeg 的维护者称这些人工智能生成的报告是“CVE 垃圾”。项目方对Google的回应一针见血:“别在那儿自嗨了,直接提交个补丁吧。”该项目的立场一直很明确:要么发补丁,要么给钱。

支撑互联网的“人们的业余爱好代码”

可以把 FFmpeg 想象成隐藏在你进入的每栋建筑墙壁后的电线。你从来都看不见它,也从来不去想它。如果它出了故障,一切都将陷入黑暗。

FFmpeg 是用 C 语言和汇编语言写的,只比原始硬件指令高一个级别。能够维护它的人才库极其微小,全球可能只有几百人。而这套软件,正如维护者们自己所描述的那样,是“人们的业余爱好代码”。

2025 年,该项目将主要开发工作从 GitHub 迁移到自托管的 Forgejo 实例(code.ffmpeg.org)。原因是成千上万的低质量拉取请求和议题,都是些寻找拼写错误来修正的人提交的。这个处理互联网上每一个视频的项目,因为不堪噪音骚扰,将其贡献流程从世界上最大的代码平台搬走了。

2025 年 1 月,Taner Sener 宣布停止维护 FFmpegKit,这是一个让 iOS 和安卓应用轻松使用 FFmpeg 的移动端封装库。自 2022 年底起,他就无法投入足够的时间。围绕 MPEG 专利的法律问题(Via-LA 收购了专利池管理方 MPEG LA,且不回应许可查询)让情况雪上加霜。FFmpeg 拼图的又一块,悄然消失。

流水线已无工人


如果你在科技行业工作,或者只要你在网上看视频——也就是说,每一个人——这件事都该让你感到担忧。

FFmpeg 的代码库已有二十六年历史。它包含了许多汇编语言优化代码,其编写者已不再参与贡献。Michael Niedermayer 写了其中成千上万行。他仍在顾问名单上,但不再是领导者。

Fabrice Bellard 创建了项目,于 2003 年离开。2011 年的分叉流失了人才。2015 年的辞职移走了定海神针。2025 年离开 GitHub 则进一步收窄了贡献者的流入渠道。

这不是一个假设的风险。这是一个倒计时。那些能维护这些代码的人正在老去、耗尽心力,或者两者皆有。没有公司在培养接班人。没有大学在教授 FFmpeg 的汇编优化。这些知识只存在于那些因为热爱视频编解码器而在 21 世纪初就投身其中的人的脑海里。

你今天看了一个视频

如果你觉得这个故事听起来很熟悉,确实没错。之前发过关于 Daniel Stenberg 维护的 curl 面临同样遭遇的故事。同样的万亿美元市值公司依赖着志愿者的代码,同样的模式:索取一切,却分文不还。

但 FFmpeg 的故事有着 curl 没有的东西。它有一位离开的天才,和一位选择贫穷来填补空缺的人。它有一个自我分裂的社区,以及一位在双方都将他当作出气筒时,仍苦苦支撑了四年的维护者。而在这一切的最后,他的话语中没有愤怒,只是说:“FFmpeg 是你们的了。”

今天用了 FFmpeg 你不知道。你没为此付钱,那些从中赚取数十亿美元的公司也没付。

FFmpeg 的立场很明确。要么提交补丁,要么给钱;你至少可以做到,别发送人工智能生成的错误报告。

如果这个故事让你感到不安,请点赞并分享,让更多工程师看到。这不仅仅是 FFmpeg 的问题。这是互联网视频运行的基础,是由那些选择为自己所相信的东西牺牲的人,苦苦支撑起来的。

你是否也维护过某个大公司依赖的开源软件?当你请求支持时,发生了什么?

FFmpeg 作者轶事2

FFmpeg是现在互联网流量最庞大的“隐形巨人”。

本节转自《码农翻身》,感谢原作者。

1、诸侯割据的时代

把时钟拨回到20多年前。当时互联网正从“文字时代”迈向“音视频时代”,宽带开始普及,人们疯狂下载歌曲、MV和电影。为了争夺未来的网络媒体入口,各大厂商纷纷推出自己的媒体格式和播放器生态:

微软推出 ASF/WMV,希望借助 Windows 的优势推广 Windows Media Player;
RealNetworks 的 RM/RMVB 一度成为网络视频事实标准,RealPlayer 几乎是装机必备软件;
苹果则主推 MOV 格式和 QuickTime 生态,在 Mac 和多媒体创作领域影响巨大。

各种“方言”导致了一个悲惨的结果:视频/编码高度碎片化,互不兼容,解码器几乎全是闭源、商业化的。更糟糕的是,很多视频格式在压缩时,深度依赖 Windows 系统的底层组件(如 DirectShow 或 VFW DLLs),这些组件是微软操作系统的核心秘密,Linux 上根本没有,巨头公司根本不屑于为市场份额极小的 Linux 系统开发官方播放器。

不过这难不倒聪明的黑客。他们想出了一个非常奇葩和极端的黑客办法:“借尸还魂”。他们编写了一些特殊的底层补丁(著名的如早期 MPlayer 的 w32codec),在 Linux 中模拟部分 Windows 多媒体接口,强行加载 Windows 系统的 .dll 动态链接库文件。这种做法虽然勉强能用,但是极不稳定,极不安全,在法律上也是非常危险的灰色地带。正是在这种“天下大乱、生态真空”的时刻,天才程序员Fabrice Bellard站了出来:是时候搞一套属于开源世界的,不依赖任何Windows技术的“多媒体底层普通话”了!

这个“普通话”就叫做FFmpeg,主要完成两个事情:
1.完成一个精妙的顶层设计,把容器和编码彻底分开。

2.用纯 C 语言,把市面上那些闭源的、复杂的商业视频和音频解码算法,全部“逆向工程”并重新纯手写一遍!

这两件事儿有多疯狂呢,一个一个来看。

2、精妙的顶层设计

在多媒体领域,任何一个视频文件其实都由两部分组成,它们的职责完全不同。容器的职责是“打包”。负责把音频流、视频流、字幕、甚至封面图片以某种特定的数据结构“捆绑”在一起,我们通常通过文件的后缀来区分(video.mp4, movie.avi)。


编码的职责是“压缩”,视频用H.264或MPEG-2压缩,音频用MP3或AAC压缩。现在很容易想到,在实现软件播放器的时候,应该把这两层分开,让他们独立变化。但在当时的商业多媒体领域,性能压力和商业策略,让大量播放器与 SDK 选择了强耦合设计,把容器和编码绑死在了一起。作为一个纯粹的学院派加硬核极客,Fabrice Bellard可不管你这那的,这两者一定得分开:

1.libavformat
专注于容器的解包和打包,当它读取一个 video.mkv 时,唯一的任务就是拆开它,把一小段一小段的、依然处于压缩状态的二进制原始数据( AVPacket)源源不断地吐出来。

2.libavcodec
专注于解压和压缩,它是一个纯粹的数学计算黑盒子,它只接受 libavformat 丢给它的压缩数据(AVPacket),通过各种算法,把它们还原成一帧一帧没有经过压缩的数据( AVFrame)。

不但如此,Fabrice Bellard用天才的手法,用最接近硬件的手段(手写 SIMD 汇编、查表法、缓存对齐)把计算性能压榨到物理极限,甚至很多时候,FFmpeg 比官方 SDK 还快。

但FFmpeg更伟大的地方,不仅仅是“支持很多格式”,它把整个音视频世界抽象成了一套统一的数据流管道(就像Unix的数据流管道一样)

以我们最常见的“视频转码”(比如把一个高码率的 AVI 视频转成手机能播放的 MP4 视频)为例,在 FFmpeg 的管道里,数据是这样像水流一样流淌的:


无论任何格式,解码,滤镜,转码,都能在流水线任意组合,非常优雅和漂亮,展示了Fabrice Bellard深厚的架构功力。

3、疯狂的逆向工程

前面说过,黑客们拿不到源代码。他们只能通过反汇编工具,将机器码翻译成人能勉强看懂的汇编代码;然后用动态调试等技术来进行分析,例如让 Windows 官方播放器慢动作播放一个视频,黑客在后台死死盯着 CPU 的寄存器和内存变化。

视频压缩本质上是高等数学通过观察汇编指令中的常数和循环结构,黑客们能够反向推导:“哦!原来 RealMedia 的音频格式用的是改进的离散余弦变换(MDCT),这里的参数是这样设置的。”他们还会制作一些极其特殊的测试视频文件:
一个纯黑、只有 1 像素、长达 1 秒的视频

一个纯白、有 2 像素、长达 2 秒的视频

然后用十六进制编辑器对比这两个文件的二进制数据。

“看,第一秒和第二秒的文件里,第 0x40 字节的数据从 01 变成了 02。这意味着这个位置存放的是视频时长!”

“这里有一串固定的字符 mdat,后面跟着一串数据。这说明 mdat 后面就是真正的音视频原始数据(Media Data)了!”

当然,很多所谓的“闭源商业格式”,其实是基于行业公开标准魔改出来的。

对于 Fabrice Bellard 这样的顶级专家,他不需要从零去猜,他只需要把公开标准作为模版去比对:“让我看看微软在这里到底改了哪几个参数?” 一旦找出这些变动,逆向工程就容易多了。

正是用这种办法,Fabrice Bellard 和无数逆向工程师一点点拆开了巨头们筑起的技术围墙。那些原本被锁在闭源播放器里的格式规范、编码算法和数据结构,被重新理解、重新实现,最终变成了干净、免费、向全世界公开的 C 语言代码。

4、贫穷的维护者

Fabrice Bellard是一个极度内敛、低调,甚至有些社恐的程序员。但有人的地方就有江湖。只要开源软件社区规模扩大,势必出现各种纷争。所以我们经常看到这样一个模式:Bellard把一个大厦的基座和主体完成后,就立刻放手,去挑战另一个领域。

挥一挥衣袖,不带走一片云彩。这次也不例外。

FFmpeg走上正轨后,他把维护权交给了 Michael Niedermayer,自己转身投入了另一个改变世界的基础设施项目:QEMU(虚拟机模拟器)。

Michael这个人,比Bellard还要低调,甚至可以说神秘。他几乎不参加技术会议或线下聚会,所有交流都通过邮件列表。我在网上甚至找不到他的照片。他本来是MPlayer播放器的开发者,但MPlayer底层高度依赖FFmpeg的解码能力,他的核心代码开始大量并入FFmpeg。

接管FFmpeg之后,他做出了一个让世俗社会无法理解的决定:全职守护FFmpeg。

要知道,当时视频网站已经兴起,他但凡接受任何一家硅谷大厂的offer,或者开一家顾问公司,就能轻松获得巨额年薪,但他都拒绝了。

共事多年的核心开发者Kostya(Konstantin Shishkov)曾回忆证实:Michael长期住在奥地利的乡下,过着维持“最低收入”的生活。

他几乎没有任何商业赞助,全靠微薄的零星捐款和极低的个人开销度日。

Michael甚至认为,出去接私活或者为了生计去上班,是对优化编解码器的时间浪费。

他每天工作十几个小时,一个人完成了FFmpeg中极其庞大且晦涩的汇编级优化。

他是个疯狂的Bug修复机——安全团队提交的上千个Bug中,有超过650个是他一个人修复的。

他长期保持着日均1次核心Commit的高强度全职工作状态。

5、技术背变:一个人对抗全世界

但是,技术天才Michael的管理风格也有问题。他过于强硬且保守,极其注重向下兼容和极致性能,经常在核心代码中加入各种特例。很多年轻开发者认为,他的代码风格太“不现代”、太难维护。社区开始积怨。

终于在2011年,一批核心开发者对 Michael 忍无可忍,他们发动了一场技术“政变”,反对派在未经Michael同意的情况下,带走了原项目的服务器、缺陷追踪系统等基础设施,另立门户创建了一个叫做 Libav 的新分支项目。

幸运的是,Fabrice Bellard 依然控制着ffmpeg.org 的 DNS,并且拒绝交给“叛军”,FFmpeg的品牌可以保全,这一点非常关键。

重量级的Linux发行版(Debian、Ubuntu 等)站在了反对派一边,将系统默认的多媒体库换成了 Libav,FFmpeg 在 Linux 生态中的主导地位受到巨大冲击。

面对“背叛”,Michael没有去打口水仗,他的反击非常纯粹:疯狂写代码。

他不仅疯狂地优化FFmpeg的代码,更是紧盯libav,只要一出新功能,他几天内就能合并进FFmpeg,并且利用恐怖的优化能力写得更好!而libav那边处于政治原因,绝不合并FFmpeg的代码。

Libav 阵营为了追求所谓的“现代化重构和干净的 API”,导致开发速度极其缓慢;而FFmpeg 在 Michael 的死守下,“把事情做完”的效率高得惊人。

几年下来,程序员们震惊地发现,FFmpeg 不仅完全兼容 Libav 的特性,而且由于 Michael 的疯狂输出,FFmpeg 的性能更强、支持的格式更多、Bug 修复得更快。

2015年,Debian决定将系统默认的多媒体库 从Libav重新切换回FFmpeg。随后Ubuntu等所有主流发行版也纷纷跟进。这成为了压垮Libav的最后一根稻草。

2015 年 8 月,在带领 FFmpeg 彻底赢回主流生态、并将 Libav 的分裂风波平息之后,身心俱疲的Michael决定辞职,他说:我加入 FFmpeg 已经 14 年了,担任 Leader 也已经 11 年。我感觉我并不是最适合继续担任 Leader 职位的人..... 我希望我的辞职能够让两个团队重新找回彼此、走到一起,从而避免更彻底的分裂...... 合并工作(Merges)所带来的巨大工作量和精神压力,是我辞职的核心原因...... FFmpeg 是你们的,它是属于每一个人的。

6、结语

20多年过去了,FFmpeg早已成为互联网隐形的基础设施。YouTube、Netflix、Chrome、抖音,快手,视频号,甚至你手机上的任何视频应用,每天都在使用FFmpeg,它是数字世界的空气,你意识不到它,但是它无处不在。但讽刺的是,开发FFmpeg的那帮极客们,长期缺钱,几乎没有名气,“近乎燃烧生命”,Michael Niedermayer 就是其中最典型的代表。很多人不理解,他们能一直坚持下来,图的是啥呢?个人想主要有三层驱动力:

1.兴趣
这些极客们在做自己喜欢的事情,热爱是无与伦比的驱动力。

2.成长
FFmpeg需要非常硬核的开发者,在这里,有最厉害的两类人,1.写汇编的 2.做逆向工程的。

想在这里做贡献,得理解CPU架构、内存层级、IO机制这些底层的东西,你的代码会被最资深的程序员逐行审查,在这种环境下成长起来的开发者,往往会变得极其强悍。

3.成就感
相关代码在几十亿的设备上运行,被几十亿用户使用,这种成就感是无与伦比的。


该文章最后由 阿炯 于 2026-06-21 20:12:54 更新,目前是第 3 版。