copyparty 官方镜像为何不再支持 HEVC/HEIC:no265 构建的法律边界与 ffmpeg 定制构建实现
【免费下载链接】copypartyPortable file server with accelerated resumable uploads, dedup, WebDAV, SFTP, FTP, TFTP, zeroconf, media indexer, thumbnails++ all in one file项目地址: https://gitcode.com/GitHub_Trending/co/copyparty
本文围绕 docs/bad-codecs.md 展开:它解释了 copyparty 官方 Docker 镜像与可启动 U 盘镜像为何出于法律原因无法解码 HEVC/H.265 视频和 HEIF/HEIC 图片(iPhone 拍摄的照片与视频首当其冲,包括缩略图)。读完本篇,你既能理解这一决策背后的专利池困境与作者的法律立场,也能从仓库源码层面看清“HEVC 被物理剥离”的完整构建流水线——版本锚定、codec 移除清单、AAC-LC 专属补丁,以及最终如何验证构建产物。
一、受影响范围:官方发行版丢失了哪些能力
根据 docs/bad-codecs.md 的说明,受法律因素限制,copyparty 的Docker 镜像与可启动 U 盘(bootable flashdrive)镜像无法解码和显示某些特定编码的图片与视频:
- iPhone 拍摄的照片和视频将无法工作,部分三星手机可能同样受影响(作者对此不完全确定);
- 上述媒体的缩略图同样无法生成——因为缩略图管线正是调用 ffmpeg 解码视频帧后生成的。
这一变更在版本日志中有明确记录:docs/changelog.md 中v1.20.8版本的标签即为 “no265”,其中注明:由于法律原因,官方 docker 镜像与可启动 U 盘镜像从此无法为 HEVC/h265 视频和 HEIF/HEIC 图片创建缩略图。
需要强调的是,这不是运行时的“功能开关”,而是二进制层面的移除——官方发行版里的 ffmpeg 里根本没有 HEVC 解码器。下文会解释为什么以及怎么做到的。
二、为什么移除 HEVC:专利纠缠与作者的法律立场
文档明确声明:以下分析是作者的个人理解,“大概率是错的”(IANAL,我不是律师)。以下是其梳理的完整逻辑链:
- H.265/HEVC 是专利受限的编解码器,分发在法律上有麻烦:
- 存在多个专利池,各专利持有方的要求互相冲突且边界不清;
- 即使是 FOSS 也不被豁免——HEVC 标准虽有“免费软件条款”(costless-software provision),但作者认为该条款并未真正免除支付要求;
- 该条款的要求(如按“销量”计费)如何映射到 FOSS 项目,作者毫无头绪;而copyparty 没有 telemetry,因此无论要求如何定义,官方发行版在原则上都无法满足。
- 主流浏览器集体回避:Chrome 和 Firefox 都拒绝内置 HEVC 解码器。作者推测(未咨询律师,仅为推断)原因在于它们做过法律评估。
- HEIF/HEIC 图片同样麻烦:大多数 HEIF/HEIC 图片的压缩编码就是 HEVC,因此问题同构。Safari 是唯一愿意解码显示 HEIF/HEIC 照片的浏览器——按作者的说法,是“出于自身难辞其咎的原因”(即苹果本身是专利利益相关方)。
- 替代方案已经存在:作者认为根本没必要使用 HEVC——AV1 能在更小文件体积下提供更高画质、完全免费,且其 HEIF 对应格式 AVIF 已在全平台浏览器中获得广泛支持。
三、为什么只影响 Docker 镜像与 U 盘镜像
文档给出了一个耐人寻味的比喻:版税责任像拼图——谁放下最后一块拼图,谁就有责任收拾那一摊子烂摊子。Docker 镜像把 copyparty 和它需要的一切软件打包成“一大坨”,从源码结构看,这正是法律风险的集中点。
关键在于:ffmpeg 是 copyparty 生态中唯一处理 HEVC 的组件。因此受影响的只有“内置 ffmpeg”的发行形态,即 Docker 镜像与可启动 U 盘镜像。反过来:
- 如果你以其他方式(pip、源码、包管理器、自托管等)安装 copyparty,你需要自行获取并提供给 copyparty 使用的 ffmpeg,因此对你而言什么都没变——你提供的 ffmpeg 里有没有 HEVC 解码器,由你的构建决定。
仓库中多处源码印证了“copyparty 只是 ffmpeg 的调用者”这一事实:
- scripts/docker/Dockerfile.ac 显示
ac镜像(copyparty + Pillow + FFmpeg,用于图片/音视频缩略图、音频转码、媒体标签)基于alpine:latest,仅添加mimalloc2、bubblewrap、py3-pillow、py3-paramiko等少量包,然后通过innvikler.sh ac安装 copyparty 及其配套的定制 ffmpeg 构建; - 缩略图生成实现在 copyparty/th_srv.py 的
conv_ffmpeg方法中:先ffprobe探测流信息,识别“视频套壳的纯音频”或attached_pic内嵌封面,随后由_ffmpeg_im(同文件 L951-L961)拼装一条ffmpeg -i <in> -map 0:v:0 -vf scale=... -frames:v 1命令解码一帧并写出 JPEG。整个管线完全委托给外部的 ffmpeg/ffprobe 二进制——copyparty 代码本身确实“不知道也不关心 HEVC 是什么”,正如文档所抱怨的:这一切都发生在 ffmpeg 那一侧。有趣的是,conv_ffmpeg 中甚至对h265扩展名做了专门的 seek 策略分支,但能否真正解码仍完全取决于所用的 ffmpeg 构建里有没有对应解码器。
四、移除是如何做到的:定制 ffmpeg 构建的源码剖析
官方做法是:用一套定制 ffmpeg 构建替换 Alpine Linux 仓库里的常规 ffmpeg 包,HEVC 解码器被“物理剥离”——不是“禁用”(disabled from use),而是从构建配置中彻底排除,使 HEVC 代码路径不存在于任何官方 copyparty 发行版中。构建脚本全部位于 scripts/docker/base/。
1. 版本锚定:verchk.sh 与 Makefile
定制构建并非另起炉灶,而是追踪 Alpine 官方源的 ffmpeg。scripts/docker/base/verchk.sh 的工作机制:
- 固定
AVER=3.24(即 alpine 3.24-stable); - 从 alpinelinux/aports 拉取该分支下
musl、python3和community/ffmpeg三个APKBUILD,与本地缓存副本逐一cmp; - 一旦 ffmpeg 的
APKBUILD发生变化(即上游更新了构建配置),就触发make -C.. ff重新构建定制包。
scripts/docker/base/Makefile 中的ff目标注释为 “legally comfy”(法律上心安理得),它驱动构建脚本完成从源码拉取到打包成 Alpine APK 的全过程。构建脚本 arbeidspakke.sh(“arbeidspakke” 即“工作包/任务包”之意)生成的构建物以时间戳+脚本 MD5 作为 configuration 字符串烧进二进制,这一签名在 scripts/docker/base/ffmpeg-features.txt 中可见(configuration: arbeidspakke-2026-06-26-...),可用于核对线上镜像与仓库脚本是否同源。
2. HEVC/VVC 移除清单:“yeet h265”
arbeidspakke.sh 首先拉取 aports 中 alpine 3.24-stable 分支的 ffmpegAPKBUILD及其全部源码包,然后用一条sed把构建参数--enable-libx265原地替换为一长串--disable-*开关,覆盖每一个HEVC/VVC 相关入口:
| 类别 | 被移除的对象(举例) |
|---|---|
| 解码器 | hevc、hevc_qsv、hevc_rkmpp、hevc_v4l2m2m、hevc_amf、hevc_cuvid、hevc_mediacodec、hevc_oh,以及vvc |
| 编码器 | hevc_rkmpp、hevc_amf、hevc_mediacodec、hevc_mf、hevc_nvenc、hevc_oh、hevc_qsv、hevc_v4l2m2m、hevc_vaapi、hevc_videotoolbox、hevc_vulkan |
| 硬件加速 | hevc_d3d11va、hevc_d3d11va2、hevc_d3d12va、hevc_dxva2、hevc_nvdec、hevc_vaapi、hevc_vdpau、hevc_videotoolbox、hevc_vulkan、vvc_vaapi |
| bitstream filter | hevc_metadata、hevc_mp4toannexb、vvc_metadata、vvc_mp4toannexb |
| 解析器/解复用器/复用器 | hevc、vvc的 parser、demuxer、muxer |
同一条sed还顺带删除了x265-dev构建依赖。值得注意的是,VVC(H.266)的痕迹也一并被剥离——文档解释原因是该编码“胎死腹中”,无法与 AV1(以及即将到来的 AV2)竞争。脚本里还保留了一行注释掉的grep(arbeidspakke.sh L27),展示作者是如何从allcodecs.c、hwaccels.h等源文件中枚举出全部ff_hevc_*/ff_vvc_*符号以生成完整移除清单的。
3. 只保留 AAC-LC:aac-lc-only.patch
文档还提到 AAC 支持“也被动过手脚”:现在只能解码 AAC-LC,作者认为这覆盖了约 99% 的 AAC 文件(几乎没人用 HE-AAC 或 AAC-LD),且 LC-AAC 在相关地区已全部实现免版税。
仓库中的实现是 scripts/docker/base/patch/ffmpeg/aac-lc-only.patch,其文件头注释直言:“移除所有高级 AAC 特性,只保留在任何相关地区都不再受专利限制的 AAC-LC(反正 99% 的 AAC 文件都是 LC,无所谓)”。补丁的关键改动:
decode_ga_specific_config:检测到m4ac->sbr > 0(SBR 是 HE-AAC 的核心)直接返回AVERROR_DECODER_NOT_FOUND;decode_eld_specific_config:整个函数体被替换为return AVERROR_DECODER_NOT_FOUND(“kill ELD support”);AOT_ER_AAC_LD分支从音频特定配置的分发逻辑中删除;decode_extension_payload遇到EXT_SBR_DATA时提前返回(“kill HE/SBR support”),SBR 频谱表读取路径(read_sbr_grid)也被植入直接终止。
prepare()阶段除了打这个补丁(arbeidspakke.sh L33-L48),还会用一段awk把libavcodec/aac/aacdec_tab.c中所有 SBR/HE 相关查找表的内容替换为无害的{ 1, 1 }占位。配套的改动源文件保存在 scripts/docker/base/patch/ffmpeg/libavcodec/ 目录(aacps.c、aacsbr.c、aacsbr_fixed.c、aacsbrdata.h)。
4. 瘦身与“copyparty 专用白名单”
移除 HEVC 之外的两个脚本段落进一步解释了体积收益的来源:
- shrink-ray(arbeidspakke.sh L51-L59):禁用
libbluray/dvdnav/dvdread/placebo/rav1e/shaderc/vdpau,替换--enable-libxcb为禁用并连带去掉ffplay、opus编码器与metasound/twinvq解码器,删除sdl2-dev依赖。脚本内注释记录了每步的体积收益,例如 “metasound+twinvq = +450 KiB apk”。 - golflympics(arbeidspakke.sh L61-L100):标题即意图——“decode-only, super-specific for copyparty only”。它把 ffmpeg 从全功能多媒体工具收敛成 copyparty 真正需要的最小子集:只保留
flac、libjxl、libmp3lame、libopus、libwebp、mjpeg、png、pcm_*等编码器,白名单 muxer(aiff、apng、matroska、mp3、webm、webp等十余种)、少量滤镜(scale、crop、showspectrumpic等),并成批禁用冷门视频/音频解码器与几乎所有字幕解码器。
5. 构建产物的验证快照:ffmpeg-features.txt
scripts/docker/base/ffmpeg-features.txt 是定制构建的ffmpeg -version+ codec/format 全量输出的存档(ffmpeg 8.1.1,Alpine gcc 15.2.0),可用于逐条核对“移除是否彻底”:
- 解码器列表中没有任何
hevc/vvc条目(视频侧可见的是h264、vp9、libdav1d等); - 音频侧保留
aac、aac_fixed、aac_latm解码器(其高级特性已被补丁在运行时拒绝); - muxer 列表与“golflympics”白名单完全一致(
aiff、apng、caf、ffmetadata、fifo、flac、image2、matroska、mp3、opus、pcm_f32le、s16le、wav、webm、webp、yuv4mpegpipe等),说明该快照确实来自同一套构建配置。
五、附带收益:镜像体积减半
文档把这件事称为“乌云上的银边”:剥离后官方 Docker 镜像明显变小,ac镜像直接腰斩——
| 指标 | 之前 | 之后 |
|---|---|---|
| 压缩后(gzipped) | 67 MiB | 35 MiB |
| 安装后(installed) | 195 MiB | 99 MiB |
从构建脚本看,体积收益来自多因素叠加:libx265/x265-dev与全部硬件加速后端消失、SBR 相关码表被掏空、冷门 codec/demuxer/字幕解码器成批移除,以及 bluray/vdpau/sdl 等无关依赖的清理。
六、如果你需要 HEVC:文档的立场与源码给出的事实
文档对“如何重新启用 HEVC 支持”的回答只有六个字:“祝你好运”。作者明确声明:他在法律上无法提供帮助,甚至认为提供“如何做到”的技术解释本身都可能构成“facilitate access”(协助获取)。他的原话大致是:copyparty 只是调用ffmpeg生成缩略图,copyparty 甚至不知道 HEVC 是什么,这一切都纯属 ffmpeg 侧的事情——但即便如此他也不再展开。
抛开作者的法律立场,仓库源码提供了两个可核实的事实,供自行评估:
- 非官方镜像的部署完全不受此约束。文档原文:如果你以其他方式安装 copyparty,获取和提供 ffmpeg 是你自己的责任。源码印证了这一点——缩略图管线(copyparty/th_srv.py)只依赖 PATH/配置中找到的
ffmpeg/ffprobe二进制,且版本日志中记录过“支持自定义 ffmpeg/ffprobe 二进制名称/路径”的选项。也就是说,在自管部署中,你使用哪个 ffmpeg 构建,就拥有哪个 ffmpeg 的解码能力;相应地,该构建的合规性也完全由使用者自己承担。 - 官方镜像内的定制 ffmpeg 以 Alpine APK 形式分发(见 scripts/docker/base/README.md),构建脚本与补丁全部开源可审计。如果你关心自己的 HEVC 需求,理解 arbeidspakke.sh 中那段移除清单,就是理解“官方构建到底删了什么”的最直接入口。
小结
docs/bad-codecs.md 记录的不是一次普通的依赖变更,而是 FOSS 项目面对专利池压力时的一次“二进制层面切割”:HEVC 解码器连同全部 VVC 痕迹从官方发行版中被物理移除,AAC 收敛到免版税的 LC 子集,同时借“copyparty 专用白名单”把官方镜像瘦身近半。对使用者而言,规则简单清晰——官方 Docker/U 盘镜像不提供 HEVC 与 HEIC 解码;其余部署方式则完全取决于你自己提供的 ffmpeg。仓库中的 scripts/docker/base/ 目录是这一决策全部技术细节的唯一权威来源,建议与 docs/changelog.md 中no265条目对照阅读。
【免费下载链接】copypartyPortable file server with accelerated resumable uploads, dedup, WebDAV, SFTP, FTP, TFTP, zeroconf, media indexer, thumbnails++ all in one file项目地址: https://gitcode.com/GitHub_Trending/co/copyparty
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考