Skip to content

Commit 83fcb36

Browse files
xingbofengcodex
andcommitted
fix(windows): 固定可复现的 FFmpeg 发布源
1) 目标与背景:修复 Windows Release 因 BtbN 每日构建资产被清理而返回 404、无法打包的问题。 2) 文件与行为:将 FFmpeg 运行时切换到固定版本 DevEnvy LGPL NuGet 包,更新下载、解包、清单、运行时身份、发布校验、许可证说明和打包契约。 3) 影响与兼容性:仅影响 Windows x64 内置 FFmpeg 的来源与受控文件哈希;继续提供 ffmpeg/ffprobe 和同名共享库,不改变应用调用边界。 4) 验证结果:Windows governance、traceability、CI contract、packaging contract、credential scanner 全部通过;PowerShell 真机下载与安装包构建交由 GitHub Windows runner 继续验证。 Co-authored-by: OpenAI Codex <codex@openai.com>
1 parent 958366a commit 83fcb36

7 files changed

Lines changed: 62 additions & 66 deletions

File tree

VoxFlow.Windows/THIRD-PARTY-NOTICES.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Windows installer.
99
| Component | Source | License | Distribution rule |
1010
| --- | --- | --- | --- |
1111
| antirez/qwen-asr | https://github.com/antirez/qwen-asr | MIT | Pin an audited revision, preserve its copyright and MIT license, and record local patches in `native/qwen-asr/UPSTREAM.md`. |
12-
| FFmpeg `n8.1.2-22-g94138f6973-20260710` | https://github.com/BtbN/FFmpeg-Builds/releases/tag/autobuild-2026-07-10-13-44 and https://github.com/FFmpeg/FFmpeg/commit/94138f6973 | LGPL-3.0-or-later build | Ship the reviewed `win64-lgpl-shared-8.1` executables and shared libraries together, preserve `LICENSE.txt`, publish the corresponding FFmpeg source, build configuration, file sizes, and SHA-256 values, and never replace the package with a GPL/nonfree variant or a PATH executable. |
12+
| DevEnvy FFmpeg `8.0.1.4` | https://www.nuget.org/packages/DevEnvy.FFmpeg.Binaries.LGPL/8.0.1.4 | LGPL-2.1-or-later build | Ship only the reviewed Windows x64 CLI executables and shared libraries, preserve `THIRD_PARTY_NOTICES.md`, retain the immutable NuGet package URL, file sizes, and SHA-256 values, and never replace the package with a GPL/nonfree variant or a PATH executable. |
1313
| VoxFlow Agent sidecar | This repository, `agent-cli/` | MIT component within the GPL-3.0-or-later VoxFlow distribution | Preserve the crate's declared MIT terms and the project GPL license. Build only the locked `builtin-agent` feature for `x86_64-pc-windows-msvc` with static CRT; stage it at `runtime/agent/`, record source revision/size/SHA-256, and never discover a replacement through PATH. |
1414
| Tesseract `5.5.2` | https://github.com/tesseract-ocr/tesseract/tree/5.5.2 | Apache-2.0 | Build only from the reviewed source on Windows x64/MSVC with vcpkg baseline `03e366fb91e38b9432ebd5f8cc79f7c8f55e96ab` and triplet `x64-windows-static`; preserve the 11,358-byte Apache license and stage only a hash-verified `runtime/ocr/` payload. |
1515
| tessdata_fast `87416418657359cb625c412a48b6e1d6d41c29bd` | https://github.com/tesseract-ocr/tessdata_fast/tree/87416418657359cb625c412a48b6e1d6d41c29bd | Apache-2.0 | Ship only `eng`, `chi_sim`, `chi_tra`, `jpn`, and `kor`, each with the fixed size/SHA-256 in `TESSERACT_RUNTIME_MANIFEST.json`; do not locate additional system data or models through PATH. |
@@ -49,15 +49,12 @@ license. The release gate requires the exact dependency names, versions,
4949
source URLs, license expressions, notice paths, file sizes, and SHA-256 values;
5050
an added, removed, or modified native input fails packaging.
5151

52-
The FFmpeg archive is
53-
`ffmpeg-n8.1.2-22-g94138f6973-win64-lgpl-shared-8.1.zip`, GitHub asset
54-
`472524907`, with SHA-256
55-
`cd39114d50ad2d17d892571d896f67fbe8b25333958682430f095eeffbb58598`.
56-
It is built for `x86_64-w64-mingw32` with `--enable-shared`,
57-
`--disable-static`, `--disable-libx264`, `--disable-libx265`,
58-
`--disable-libxvid`, and without `--enable-gpl` or `--enable-nonfree`.
59-
The package reports GNU Lesser General Public License version 3. The exact
60-
runtime inventory and build provenance are in `runtime/ffmpeg/`.
52+
The FFmpeg archive is the immutable NuGet package
53+
`devenvy.ffmpeg.binaries.lgpl.8.0.1.4.nupkg`, with SHA-256
54+
`d80010128975b46e1b2b74505c464250a3413e23681cc331c6943a9cf1046fda`.
55+
The package declares LGPL-2.1-or-later and documents `--disable-gpl`,
56+
`--disable-nonfree`, `--enable-shared`, and `--disable-static`. The exact
57+
Windows x64 runtime inventory and build provenance are in `runtime/ffmpeg/`.
6158

6259
## Agent sidecar Cargo runtime inventory
6360

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
11
{
22
"schemaVersion": 1,
3-
"runtimeId": "ffmpeg-n8.1.2-22-g94138f6973-20260710-win64-lgpl-shared",
3+
"runtimeId": "devenvy-ffmpeg-lgpl-8.0.1.4-win-x64",
44
"architecture": "x64",
5-
"license": "LGPL-3.0-or-later",
5+
"license": "LGPL-2.1-or-later",
66
"licenseFile": {
7-
"path": "LICENSE.txt",
8-
"size": 7651,
9-
"sha256": "da7eabb7bafdf7d3ae5e9f223aa5bdc1eece45ac569dc21b3b037520b4464768"
7+
"path": "THIRD_PARTY_NOTICES.md",
8+
"size": 2174,
9+
"sha256": "39d65c5952106502f000d66c41c3bd23d2c0550a8c3270bb224c7642b3cccf9e"
1010
},
1111
"archive": {
12-
"fileName": "ffmpeg-n8.1.2-22-g94138f6973-win64-lgpl-shared-8.1.zip",
13-
"size": 70508421,
14-
"sha256": "cd39114d50ad2d17d892571d896f67fbe8b25333958682430f095eeffbb58598",
15-
"assetId": 472524907,
16-
"releaseTag": "autobuild-2026-07-10-13-44"
12+
"fileName": "devenvy.ffmpeg.binaries.lgpl.8.0.1.4.nupkg",
13+
"size": 195504127,
14+
"sha256": "d80010128975b46e1b2b74505c464250a3413e23681cc331c6943a9cf1046fda",
15+
"downloadUrl": "https://api.nuget.org/v3-flatcontainer/devenvy.ffmpeg.binaries.lgpl/8.0.1.4/devenvy.ffmpeg.binaries.lgpl.8.0.1.4.nupkg",
16+
"runtimePath": "ffmpeg/win-x64",
17+
"noticePath": "THIRD_PARTY_NOTICES.md"
1718
},
1819
"files": [
19-
{ "path": "avcodec-62.dll", "size": 70881792, "sha256": "06f15c16294f59d6ae63279443f59c32c11c682975b4c90fccc09295a37b295f" },
20-
{ "path": "avdevice-62.dll", "size": 3699712, "sha256": "93e150e2e8e8107deb5c17e652691da65d5ab5a56740edc957485ca029ce11f0" },
21-
{ "path": "avfilter-11.dll", "size": 29816320, "sha256": "5086c95910729913ebb0c812d63ace8060c99513e644dfaa09c46675ddf57180" },
22-
{ "path": "avformat-62.dll", "size": 22070784, "sha256": "3d61acda2f552e40cbb706e32c0d2bbf3bd4e71cd98677f1ed33a90e23c9be00" },
23-
{ "path": "avutil-60.dll", "size": 2937856, "sha256": "efe39d566fe0dcaab6edc3921efbefb582000ccb65ad32ee4ad10b07839ed3e9" },
24-
{ "path": "ffmpeg.exe", "size": 542208, "sha256": "150a59fcec879bc7b4c084afa51657e0dec29257a81cc01fd3595b6fe917367a" },
25-
{ "path": "ffprobe.exe", "size": 227840, "sha256": "86427747d48175c22485950dbfee4e883912df583f0986e0070ac7cff9c9f823" },
26-
{ "path": "swresample-6.dll", "size": 723968, "sha256": "8d03a589f26f038585ffc2cf3fb4f1f2aa88f024584029c5aa1f4c94d8fe250d" },
27-
{ "path": "swscale-9.dll", "size": 12570624, "sha256": "6c3a0f0b2b7fbe5e1ac293856c03cd20dd2bbc0946542f4a53945c0aec556d16" }
20+
{ "path": "avcodec-62.dll", "size": 19073024, "sha256": "2329808efd0bc8e9a0503ccf6bb49a18d8f0f082e83db85dee664ea6a49feca0" },
21+
{ "path": "avdevice-62.dll", "size": 138240, "sha256": "22a273ce8fc48ba3a6ea3f7b1684c1072bb9a982022954a2989ba82ed7a40887" },
22+
{ "path": "avfilter-11.dll", "size": 5422592, "sha256": "2810c397ee3be9ca91b071eadeed1f7b34a7020e19287df976240b65268bfd7b" },
23+
{ "path": "avformat-62.dll", "size": 2689024, "sha256": "2473b92a50499f391a77f4fd3bad46510b39a90c5d84c77dd5693ee8707a9263" },
24+
{ "path": "avutil-60.dll", "size": 1583104, "sha256": "f449c41dafeaa9d79b9b79802addcd4a8c1ea7d98153b1731b8ecf290a507003" },
25+
{ "path": "ffmpeg.exe", "size": 448000, "sha256": "a485d921008bea1eb3923c17b64c16f9ac2231d57b41c49dc479a953fecfa867" },
26+
{ "path": "ffprobe.exe", "size": 209920, "sha256": "266a5b7da88ed1b81822c18888a3cc00bc372815982e056575f5a43ced55fd02" },
27+
{ "path": "swresample-6.dll", "size": 140288, "sha256": "97d61a29afa853e79418a39fb50ec9808732e066f06cea3daf9da8d58199603b" },
28+
{ "path": "swscale-9.dll", "size": 1750016, "sha256": "d5ee6dd71c6a6cc49140a0fbf6ffdaba33fed5dc9a8276ff3f6d792a905dccbc" }
2829
]
2930
}
Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
# FFmpeg runtime provenance
22

3-
VoxFlow Windows locks FFmpeg to the BtbN release
4-
`autobuild-2026-07-10-13-44`, asset `472524907`:
3+
VoxFlow Windows locks FFmpeg to the immutable NuGet package
4+
`DevEnvy.FFmpeg.Binaries.LGPL` version `8.0.1.4`:
55

6-
- package: `ffmpeg-n8.1.2-22-g94138f6973-win64-lgpl-shared-8.1.zip`
7-
- FFmpeg version: `n8.1.2-22-g94138f6973-20260710`
8-
- FFmpeg source revision: `94138f6973`
9-
- target: `x86_64-w64-mingw32`
10-
- license reported by the package: LGPL version 3
6+
- package: `devenvy.ffmpeg.binaries.lgpl.8.0.1.4.nupkg`
7+
- FFmpeg version: `8.0.1`
8+
- target: Windows x64
9+
- license declared by the package: LGPL-2.1-or-later
1110
- package mode: shared libraries, not static linking
1211

1312
Upstream URLs:
1413

15-
- https://github.com/BtbN/FFmpeg-Builds/releases/tag/autobuild-2026-07-10-13-44
16-
- https://github.com/FFmpeg/FFmpeg/commit/94138f6973
14+
- https://www.nuget.org/packages/DevEnvy.FFmpeg.Binaries.LGPL/8.0.1.4
1715
- https://ffmpeg.org/legal.html
1816

1917
The reviewed configuration enables shared libraries and disables static
@@ -23,7 +21,7 @@ codec integrations including libx264, libx265, and libxvid are disabled.
2321
startup and by release checks. `ffplay.exe` is intentionally excluded because
2422
VoxFlow uses NAudio for playback.
2523

26-
Release packaging must include the package's unmodified `LICENSE.txt`, the
27-
corresponding FFmpeg source archive and build configuration link, and all nine
28-
manifested runtime files. The application may only resolve this directory; it
29-
must not search `PATH` or download a replacement.
24+
Release packaging must include the package's unmodified
25+
`THIRD_PARTY_NOTICES.md` and all nine manifested runtime files. The application
26+
may only resolve this directory; it must not search `PATH` or download a
27+
replacement.

VoxFlow.Windows/scripts/check-release-layout.ps1

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -317,25 +317,27 @@ $reviewedFfmpegManifestPath = Join-Path $windowsRoot 'runtime/ffmpeg/FFMPEG_RUNT
317317
$reviewedFfmpegManifestHash = (Get-FileHash -LiteralPath $reviewedFfmpegManifestPath -Algorithm SHA256).Hash.ToLowerInvariant()
318318
$publishedFfmpegManifestHash = (Get-FileHash -LiteralPath $ffmpegManifestPath -Algorithm SHA256).Hash.ToLowerInvariant()
319319
if ($reviewedFfmpegManifestHash -ne
320-
'957ee658b3acbc8683c40131db499147c48e4d11cff745b15e332443798e1038' -or
320+
'edcea9157fcb9789645879111299739d9da1bb1e4656bba1c0352740d84f5110' -or
321321
$publishedFfmpegManifestHash -ne $reviewedFfmpegManifestHash) {
322322
Fail 'The published FFmpeg manifest does not match the reviewed source manifest.'
323323
}
324324
$ffmpegManifest = Get-Content -LiteralPath $ffmpegManifestPath -Raw | ConvertFrom-Json
325325
if ($ffmpegManifest.schemaVersion -ne 1 -or
326-
$ffmpegManifest.runtimeId -ne 'ffmpeg-n8.1.2-22-g94138f6973-20260710-win64-lgpl-shared' -or
326+
$ffmpegManifest.runtimeId -ne 'devenvy-ffmpeg-lgpl-8.0.1.4-win-x64' -or
327327
$ffmpegManifest.architecture -ne 'x64' -or
328-
$ffmpegManifest.license -ne 'LGPL-3.0-or-later' -or
329-
$ffmpegManifest.archive.fileName -ne 'ffmpeg-n8.1.2-22-g94138f6973-win64-lgpl-shared-8.1.zip' -or
330-
[long]$ffmpegManifest.archive.size -ne 70508421 -or
328+
$ffmpegManifest.license -ne 'LGPL-2.1-or-later' -or
329+
$ffmpegManifest.archive.fileName -ne 'devenvy.ffmpeg.binaries.lgpl.8.0.1.4.nupkg' -or
330+
[long]$ffmpegManifest.archive.size -ne 195504127 -or
331331
$ffmpegManifest.archive.sha256 -ne
332-
'cd39114d50ad2d17d892571d896f67fbe8b25333958682430f095eeffbb58598' -or
333-
[long]$ffmpegManifest.archive.assetId -ne 472524907 -or
334-
$ffmpegManifest.archive.releaseTag -ne 'autobuild-2026-07-10-13-44' -or
335-
$ffmpegManifest.licenseFile.path -ne 'LICENSE.txt' -or
336-
[long]$ffmpegManifest.licenseFile.size -ne 7651 -or
332+
'd80010128975b46e1b2b74505c464250a3413e23681cc331c6943a9cf1046fda' -or
333+
$ffmpegManifest.archive.downloadUrl -ne
334+
'https://api.nuget.org/v3-flatcontainer/devenvy.ffmpeg.binaries.lgpl/8.0.1.4/devenvy.ffmpeg.binaries.lgpl.8.0.1.4.nupkg' -or
335+
$ffmpegManifest.archive.runtimePath -ne 'ffmpeg/win-x64' -or
336+
$ffmpegManifest.archive.noticePath -ne 'THIRD_PARTY_NOTICES.md' -or
337+
$ffmpegManifest.licenseFile.path -ne 'THIRD_PARTY_NOTICES.md' -or
338+
[long]$ffmpegManifest.licenseFile.size -ne 2174 -or
337339
$ffmpegManifest.licenseFile.sha256 -ne
338-
'da7eabb7bafdf7d3ae5e9f223aa5bdc1eece45ac569dc21b3b037520b4464768') {
340+
'39d65c5952106502f000d66c41c3bd23d2c0550a8c3270bb224c7642b3cccf9e') {
339341
Fail 'The published FFmpeg runtime identity or architecture changed.'
340342
}
341343
$reviewedFfmpegFilePaths = @(

VoxFlow.Windows/scripts/stage-ffmpeg-runtime.ps1

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ New-Item -ItemType Directory -Path $temporaryRoot -Force | Out-Null
4545
try {
4646
if ([string]::IsNullOrWhiteSpace($ArchivePath)) {
4747
$ArchivePath = Join-Path $temporaryRoot $manifest.archive.fileName
48-
$url = "https://github.com/BtbN/FFmpeg-Builds/releases/download/$($manifest.archive.releaseTag)/$($manifest.archive.fileName)"
49-
Invoke-WebRequest -Uri $url -OutFile $ArchivePath -UseBasicParsing -TimeoutSec 1800
48+
Invoke-WebRequest -Uri $manifest.archive.downloadUrl -OutFile $ArchivePath -UseBasicParsing -TimeoutSec 1800
5049
}
5150
$resolvedArchive = (Resolve-Path -LiteralPath $ArchivePath).Path
5251
$archiveInfo = Get-Item -LiteralPath $resolvedArchive
@@ -59,13 +58,11 @@ try {
5958
}
6059

6160
$expanded = Join-Path $temporaryRoot 'expanded'
62-
Expand-Archive -LiteralPath $resolvedArchive -DestinationPath $expanded
63-
$bin = Get-ChildItem -LiteralPath $expanded -Directory |
64-
Select-Object -First 1 |
65-
ForEach-Object { Join-Path $_.FullName 'bin' }
66-
$license = Get-ChildItem -LiteralPath $expanded -Directory |
67-
Select-Object -First 1 |
68-
ForEach-Object { Join-Path $_.FullName 'LICENSE.txt' }
61+
$expandableArchive = Join-Path $temporaryRoot 'ffmpeg-package.zip'
62+
Copy-Item -LiteralPath $resolvedArchive -Destination $expandableArchive -Force
63+
Expand-Archive -LiteralPath $expandableArchive -DestinationPath $expanded
64+
$bin = Join-Path $expanded $manifest.archive.runtimePath
65+
$license = Join-Path $expanded $manifest.archive.noticePath
6966
if (-not (Test-Path -LiteralPath $bin -PathType Container) -or
7067
-not (Test-Path -LiteralPath $license -PathType Leaf)) {
7168
throw 'The reviewed FFmpeg archive layout changed.'

VoxFlow.Windows/src/VoxFlow.Windows.Infrastructure/Media/FfmpegRuntimeVerifier.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public sealed class FfmpegRuntimeVerifier : IFfmpegRuntimeVerifier
4545
{
4646
public const string ManifestFileName = "FFMPEG_RUNTIME_MANIFEST.json";
4747
public const string ExpectedRuntimeId =
48-
"ffmpeg-n8.1.2-22-g94138f6973-20260710-win64-lgpl-shared";
48+
"devenvy-ffmpeg-lgpl-8.0.1.4-win-x64";
4949

5050
private static readonly JsonSerializerOptions SerializerOptions = new()
5151
{

VoxFlow.Windows/tests/packaging-contract.test.sh

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,10 @@ if grep -R -Fq --include='*.ps1' 'Start-Process' "${windows_root}/scripts"; then
202202
printf '%s\n' 'Release and governance scripts must not use unbounded Start-Process.' >&2
203203
exit 1
204204
fi
205-
grep -Fq 'cd39114d50ad2d17d892571d896f67fbe8b25333958682430f095eeffbb58598' \
205+
grep -Fq 'https://api.nuget.org/v3-flatcontainer/devenvy.ffmpeg.binaries.lgpl/' \
206206
"${windows_root}/runtime/ffmpeg/FFMPEG_RUNTIME_MANIFEST.json"
207-
ffmpeg_manifest_hash='957ee658b3acbc8683c40131db499147c48e4d11cff745b15e332443798e1038'
207+
grep -Fq '8.0.1.4' "${windows_root}/runtime/ffmpeg/FFMPEG_RUNTIME_MANIFEST.json"
208+
ffmpeg_manifest_hash='edcea9157fcb9789645879111299739d9da1bb1e4656bba1c0352740d84f5110'
208209
test "$(sha256sum "${windows_root}/runtime/ffmpeg/FFMPEG_RUNTIME_MANIFEST.json" | awk '{print $1}')" = \
209210
"${ffmpeg_manifest_hash}"
210211
grep -Fq "${ffmpeg_manifest_hash}" "${layout_check}"
@@ -218,7 +219,7 @@ for lf_path in \
218219
'scripts/patches/*.patch'; do
219220
grep -Fq "${lf_path} text eol=lf" "${windows_root}/.gitattributes"
220221
done
221-
grep -Fq 'da7eabb7bafdf7d3ae5e9f223aa5bdc1eece45ac569dc21b3b037520b4464768' \
222+
grep -Fq '39d65c5952106502f000d66c41c3bd23d2c0550a8c3270bb224c7642b3cccf9e' \
222223
"${windows_root}/runtime/ffmpeg/FFMPEG_RUNTIME_MANIFEST.json"
223224

224225
printf '%s\n' 'PASS: Windows packaging source contract is per-user, x64-only, self-contained, license-complete, and has explicit data deletion.'

0 commit comments

Comments
 (0)