Skip to content

Commit 2a0b3a5

Browse files
committed
fix(build): Fix FFmpeg cross-platform build on macOS for Windows targets (#145)
* fix(build): fix FFmpeg cross-platform build on macOS for Windows targets - Add cross-env dependency for cross-platform environment variables - Update Windows build scripts to set BUILD_TARGET_PLATFORM and BUILD_TARGET_ARCH - Modify download-ffmpeg.ts to prioritize environment variables over command arguments - Update vite plugin to avoid duplicate FFmpeg downloads - Fix release scripts to download all platform FFmpeg binaries before building - Ensure correct FFmpeg binaries are included for each target platform Resolves issue where building Windows packages on macOS would include macOS FFmpeg binaries instead of Windows ones. * fix(build): improve FFmpeg download in CI environments - Replace direct tsx command with npm run for better CI compatibility - Add CI-specific handling with proper environment variable passing - Convert hard failures to warnings to prevent CI build blocking - Improve error messages and debugging information Fixes Windows CI build failure: spawn tsx ENOENT * fix(build): ensure FFmpeg is properly downloaded in Windows CI - Use npm run ffmpeg:download on Windows for better compatibility - Pass environment variables to ensure correct platform detection - Throw errors on download failure to prevent incomplete builds - Keep direct tsx usage on Unix systems for performance This ensures CI builds never skip FFmpeg download and always include the correct FFmpeg binaries for the target platform.
1 parent 58fe719 commit 2a0b3a5

4 files changed

Lines changed: 92 additions & 21 deletions

File tree

electron.vite.config.ts

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,49 @@ function ffmpegDownloadPlugin() {
1818
// 只在生产构建时下载 FFmpeg
1919
if (!isProd) return
2020

21-
console.log('Downloading FFmpeg...')
21+
// 根据构建目标决定下载哪个平台
22+
const targetPlatform = process.env.BUILD_TARGET_PLATFORM || process.platform
23+
const targetArch = process.env.BUILD_TARGET_ARCH || process.arch
24+
25+
// 检查是否已存在,避免重复下载
26+
const ffmpegPath = path.resolve(
27+
'resources/ffmpeg',
28+
`${targetPlatform}-${targetArch}`,
29+
targetPlatform === 'win32' ? 'ffmpeg.exe' : 'ffmpeg'
30+
)
31+
32+
if (fs.existsSync(ffmpegPath)) {
33+
console.log(`FFmpeg already exists for ${targetPlatform}-${targetArch}`)
34+
return
35+
}
2236

23-
try {
24-
// 根据构建目标决定下载哪个平台
25-
const targetPlatform = process.env.BUILD_TARGET_PLATFORM || process.platform
26-
const targetArch = process.env.BUILD_TARGET_ARCH || process.arch
37+
console.log(`Downloading FFmpeg for ${targetPlatform}-${targetArch}...`)
2738

39+
try {
2840
await new Promise<void>((resolve, reject) => {
29-
const downloadScript = spawn(
30-
'tsx',
31-
['scripts/download-ffmpeg.ts', 'platform', targetPlatform, targetArch],
32-
{
33-
stdio: 'inherit'
41+
// 在不同环境中使用不同的命令来确保兼容性
42+
let command: string
43+
let args: string[]
44+
45+
if (process.platform === 'win32') {
46+
// Windows 环境:使用 npm run 调用脚本,更可靠
47+
command = 'npm'
48+
args = ['run', 'ffmpeg:download']
49+
} else {
50+
// Unix 环境:直接使用 tsx
51+
command = 'tsx'
52+
args = ['scripts/download-ffmpeg.ts', 'platform', targetPlatform, targetArch]
53+
}
54+
55+
const downloadScript = spawn(command, args, {
56+
stdio: 'inherit',
57+
shell: process.platform === 'win32',
58+
env: {
59+
...process.env,
60+
BUILD_TARGET_PLATFORM: targetPlatform,
61+
BUILD_TARGET_ARCH: targetArch
3462
}
35-
)
63+
})
3664

3765
downloadScript.on('close', (code) => {
3866
if (code === 0) {
@@ -48,7 +76,8 @@ function ffmpegDownloadPlugin() {
4876
})
4977
})
5078
} catch (error) {
51-
console.warn('FFmpeg Download failed', error)
79+
console.error('FFmpeg Download failed:', error)
80+
throw new Error(`Failed to download FFmpeg for ${targetPlatform}-${targetArch}: ${error}`)
5281
}
5382
}
5483
}

package.json

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@
2020
"start": "electron-vite preview",
2121
"dev": "electron-vite dev",
2222
"build": "npm run typecheck && electron-vite build",
23+
"build:release": "npm run typecheck && electron-vite build",
2324
"postinstall": "electron-builder install-app-deps",
2425
"build:unpack": "npm run build && electron-builder --dir --publish never",
25-
"build:win": "npm run build && electron-builder --win --publish never",
26-
"build:win:x64": "npm run build && electron-builder --win --x64 --publish never",
27-
"build:win:arm64": "npm run build && electron-builder --win --arm64 --publish never",
26+
"build:win": "cross-env BUILD_TARGET_PLATFORM=win32 npm run build && electron-builder --win --publish never",
27+
"build:win:x64": "cross-env BUILD_TARGET_PLATFORM=win32 BUILD_TARGET_ARCH=x64 npm run build && electron-builder --win --x64 --publish never",
28+
"build:win:arm64": "cross-env BUILD_TARGET_PLATFORM=win32 BUILD_TARGET_ARCH=arm64 npm run build && electron-builder --win --arm64 --publish never",
2829
"build:mac": "electron-vite build && electron-builder --mac --publish never",
2930
"build:mac:x64": "npm run build && electron-builder --mac --x64 --publish never",
3031
"build:mac:arm64": "npm run build && electron-builder --mac --arm64 --publish never",
@@ -47,10 +48,10 @@
4748
"version:prerelease": "tsx scripts/version-manager.ts prerelease",
4849
"version:beta": "tsx scripts/version-manager.ts minor beta",
4950
"version:beta-patch": "tsx scripts/version-manager.ts patch beta",
50-
"release": "npm run build && electron-builder --publish onTagOrDraft",
51-
"release:all": "npm run build && electron-builder --publish always",
52-
"release:never": "npm run build && electron-builder --publish never",
53-
"release:draft": "npm run build && electron-builder --publish onTagOrDraft",
51+
"release": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish onTagOrDraft",
52+
"release:all": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish always",
53+
"release:never": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish never",
54+
"release:draft": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish onTagOrDraft",
5455
"migrate": "tsx src/main/db/migration-cli.ts",
5556
"migrate:up": "npm run migrate up",
5657
"migrate:down": "npm run migrate down",
@@ -71,7 +72,8 @@
7172
"ffmpeg:download-all": "tsx scripts/download-ffmpeg.ts all",
7273
"ffmpeg:clean": "tsx scripts/download-ffmpeg.ts clean",
7374
"ffmpeg:test": "tsx scripts/test-ffmpeg-integration.ts",
74-
"prebuild": "npm run ffmpeg:download"
75+
"prebuild": "npm run ffmpeg:download",
76+
"prebuild:release": "echo 'FFmpeg already downloaded by release script'"
7577
},
7678
"dependencies": {
7779
"@ant-design/icons": "^6.0.1",
@@ -128,6 +130,7 @@
128130
"@welldone-software/why-did-you-render": "^10.0.1",
129131
"cli-progress": "^3.12.0",
130132
"code-inspector-plugin": "^1.2.7",
133+
"cross-env": "^10.0.0",
131134
"electron": "37.2.4",
132135
"electron-builder": "26.0.19",
133136
"electron-devtools-installer": "^4.0.0",

pnpm-lock.yaml

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/download-ffmpeg.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,28 @@ class FFmpegDownloader {
376376
// CLI 入口
377377
async function main() {
378378
const args = process.argv.slice(2)
379-
const command = args[0] || 'current'
379+
let command = args[0]
380380

381381
const downloader = new FFmpegDownloader()
382382

383383
try {
384+
// 优先检查环境变量,如果设置了构建目标则使用目标平台
385+
if (process.env.BUILD_TARGET_PLATFORM) {
386+
console.log(
387+
`检测到构建目标平台: ${process.env.BUILD_TARGET_PLATFORM}-${process.env.BUILD_TARGET_ARCH || process.arch}`
388+
)
389+
await downloader.downloadFFmpeg(
390+
process.env.BUILD_TARGET_PLATFORM,
391+
process.env.BUILD_TARGET_ARCH || process.arch
392+
)
393+
return
394+
}
395+
396+
// 如果没有环境变量,按原逻辑处理命令参数
397+
if (!command) {
398+
command = 'current'
399+
}
400+
384401
switch (command) {
385402
case 'all':
386403
await downloader.downloadAllPlatforms()
@@ -416,6 +433,10 @@ async function main() {
416433
win32: x64, arm64
417434
darwin: x64, arm64
418435
linux: x64, arm64
436+
437+
环境变量:
438+
BUILD_TARGET_PLATFORM - 构建目标平台 (win32, darwin, linux)
439+
BUILD_TARGET_ARCH - 构建目标架构 (x64, arm64)
419440
`)
420441
}
421442
} catch (error) {

0 commit comments

Comments
 (0)