diff --git a/electron.vite.config.ts b/electron.vite.config.ts index da28b75f..7b77040e 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -18,21 +18,49 @@ function ffmpegDownloadPlugin() { // 只在生产构建时下载 FFmpeg if (!isProd) return - console.log('Downloading FFmpeg...') + // 根据构建目标决定下载哪个平台 + const targetPlatform = process.env.BUILD_TARGET_PLATFORM || process.platform + const targetArch = process.env.BUILD_TARGET_ARCH || process.arch + + // 检查是否已存在,避免重复下载 + const ffmpegPath = path.resolve( + 'resources/ffmpeg', + `${targetPlatform}-${targetArch}`, + targetPlatform === 'win32' ? 'ffmpeg.exe' : 'ffmpeg' + ) + + if (fs.existsSync(ffmpegPath)) { + console.log(`FFmpeg already exists for ${targetPlatform}-${targetArch}`) + return + } - try { - // 根据构建目标决定下载哪个平台 - const targetPlatform = process.env.BUILD_TARGET_PLATFORM || process.platform - const targetArch = process.env.BUILD_TARGET_ARCH || process.arch + console.log(`Downloading FFmpeg for ${targetPlatform}-${targetArch}...`) + try { await new Promise((resolve, reject) => { - const downloadScript = spawn( - 'tsx', - ['scripts/download-ffmpeg.ts', 'platform', targetPlatform, targetArch], - { - stdio: 'inherit' + // 在不同环境中使用不同的命令来确保兼容性 + let command: string + let args: string[] + + if (process.platform === 'win32') { + // Windows 环境:使用 npm run 调用脚本,更可靠 + command = 'npm' + args = ['run', 'ffmpeg:download'] + } else { + // Unix 环境:直接使用 tsx + command = 'tsx' + args = ['scripts/download-ffmpeg.ts', 'platform', targetPlatform, targetArch] + } + + const downloadScript = spawn(command, args, { + stdio: 'inherit', + shell: process.platform === 'win32', + env: { + ...process.env, + BUILD_TARGET_PLATFORM: targetPlatform, + BUILD_TARGET_ARCH: targetArch } - ) + }) downloadScript.on('close', (code) => { if (code === 0) { @@ -48,7 +76,8 @@ function ffmpegDownloadPlugin() { }) }) } catch (error) { - console.warn('FFmpeg Download failed', error) + console.error('FFmpeg Download failed:', error) + throw new Error(`Failed to download FFmpeg for ${targetPlatform}-${targetArch}: ${error}`) } } } diff --git a/package.json b/package.json index 92a27f60..ff4da17c 100644 --- a/package.json +++ b/package.json @@ -20,11 +20,12 @@ "start": "electron-vite preview", "dev": "electron-vite dev", "build": "npm run typecheck && electron-vite build", + "build:release": "npm run typecheck && electron-vite build", "postinstall": "electron-builder install-app-deps", "build:unpack": "npm run build && electron-builder --dir --publish never", - "build:win": "npm run build && electron-builder --win --publish never", - "build:win:x64": "npm run build && electron-builder --win --x64 --publish never", - "build:win:arm64": "npm run build && electron-builder --win --arm64 --publish never", + "build:win": "cross-env BUILD_TARGET_PLATFORM=win32 npm run build && electron-builder --win --publish never", + "build:win:x64": "cross-env BUILD_TARGET_PLATFORM=win32 BUILD_TARGET_ARCH=x64 npm run build && electron-builder --win --x64 --publish never", + "build:win:arm64": "cross-env BUILD_TARGET_PLATFORM=win32 BUILD_TARGET_ARCH=arm64 npm run build && electron-builder --win --arm64 --publish never", "build:mac": "electron-vite build && electron-builder --mac --publish never", "build:mac:x64": "npm run build && electron-builder --mac --x64 --publish never", "build:mac:arm64": "npm run build && electron-builder --mac --arm64 --publish never", @@ -47,10 +48,10 @@ "version:prerelease": "tsx scripts/version-manager.ts prerelease", "version:beta": "tsx scripts/version-manager.ts minor beta", "version:beta-patch": "tsx scripts/version-manager.ts patch beta", - "release": "npm run build && electron-builder --publish onTagOrDraft", - "release:all": "npm run build && electron-builder --publish always", - "release:never": "npm run build && electron-builder --publish never", - "release:draft": "npm run build && electron-builder --publish onTagOrDraft", + "release": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish onTagOrDraft", + "release:all": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish always", + "release:never": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish never", + "release:draft": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish onTagOrDraft", "migrate": "tsx src/main/db/migration-cli.ts", "migrate:up": "npm run migrate up", "migrate:down": "npm run migrate down", @@ -71,7 +72,8 @@ "ffmpeg:download-all": "tsx scripts/download-ffmpeg.ts all", "ffmpeg:clean": "tsx scripts/download-ffmpeg.ts clean", "ffmpeg:test": "tsx scripts/test-ffmpeg-integration.ts", - "prebuild": "npm run ffmpeg:download" + "prebuild": "npm run ffmpeg:download", + "prebuild:release": "echo 'FFmpeg already downloaded by release script'" }, "dependencies": { "@ant-design/icons": "^6.0.1", @@ -128,6 +130,7 @@ "@welldone-software/why-did-you-render": "^10.0.1", "cli-progress": "^3.12.0", "code-inspector-plugin": "^1.2.7", + "cross-env": "^10.0.0", "electron": "37.2.4", "electron-builder": "26.0.19", "electron-devtools-installer": "^4.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eac64848..bed42240 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -171,6 +171,9 @@ importers: code-inspector-plugin: specifier: ^1.2.7 version: 1.2.7 + cross-env: + specifier: ^10.0.0 + version: 10.0.0 electron: specifier: 37.2.4 version: 37.2.4 @@ -685,6 +688,9 @@ packages: '@emotion/unitless@0.8.1': resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} + '@epic-web/invariant@1.0.0': + resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} + '@esbuild/aix-ppc64@0.25.8': resolution: {integrity: sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==} engines: {node: '>=18'} @@ -2584,6 +2590,11 @@ packages: cross-dirname@0.1.0: resolution: {integrity: sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==} + cross-env@10.0.0: + resolution: {integrity: sha512-aU8qlEK/nHYtVuN4p7UQgAwVljzMg8hB4YK5ThRqD2l/ziSnryncPNn7bMLt5cFYsKVKBh8HqLqyCoTupEUu7Q==} + engines: {node: '>=20'} + hasBin: true + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -7433,6 +7444,8 @@ snapshots: '@emotion/unitless@0.8.1': {} + '@epic-web/invariant@1.0.0': {} + '@esbuild/aix-ppc64@0.25.8': optional: true @@ -9622,6 +9635,11 @@ snapshots: cross-dirname@0.1.0: optional: true + cross-env@10.0.0: + dependencies: + '@epic-web/invariant': 1.0.0 + cross-spawn: 7.0.6 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 diff --git a/scripts/download-ffmpeg.ts b/scripts/download-ffmpeg.ts index f4017661..442d5034 100644 --- a/scripts/download-ffmpeg.ts +++ b/scripts/download-ffmpeg.ts @@ -376,11 +376,28 @@ class FFmpegDownloader { // CLI 入口 async function main() { const args = process.argv.slice(2) - const command = args[0] || 'current' + let command = args[0] const downloader = new FFmpegDownloader() try { + // 优先检查环境变量,如果设置了构建目标则使用目标平台 + if (process.env.BUILD_TARGET_PLATFORM) { + console.log( + `检测到构建目标平台: ${process.env.BUILD_TARGET_PLATFORM}-${process.env.BUILD_TARGET_ARCH || process.arch}` + ) + await downloader.downloadFFmpeg( + process.env.BUILD_TARGET_PLATFORM, + process.env.BUILD_TARGET_ARCH || process.arch + ) + return + } + + // 如果没有环境变量,按原逻辑处理命令参数 + if (!command) { + command = 'current' + } + switch (command) { case 'all': await downloader.downloadAllPlatforms() @@ -416,6 +433,10 @@ async function main() { win32: x64, arm64 darwin: x64, arm64 linux: x64, arm64 + +环境变量: + BUILD_TARGET_PLATFORM - 构建目标平台 (win32, darwin, linux) + BUILD_TARGET_ARCH - 构建目标架构 (x64, arm64) `) } } catch (error) {