要将视频文件放到单独的 asar 包中,并让 Electron 应用正常调用,可按以下步骤操作:
项目结构调整
首先调整项目结构,将视频文件单独放在一个目录:
your-app/
├── main.js
├── forge.config.js
├── package.json
├── src/
├── index.html
└── assets/
└── videos/
├── video1.mp4
└── video2.mp4
将视频文件打包到单独的asar
若未安装 asar,可通过以下命令进行安装
bash
npm install -g asar
使用asar命令打包
bash
asar pack src/assets/videos out/videos.asar
修改 forge.config.js 配置
javascript
const { FusesPlugin } = require('@electron-forge/plugin-fuses');
const { FuseV1Options, FuseVersion } = require('@electron/fuses');
const path = require('path');
module.exports = {
packagerConfig: {
asar: true,
icon: path.join(__dirname, 'app-icon.ico'), // 图标文件路径
ignore: [
"./assets/videos", // 忽略视频目录
"py",
]
},
rebuildConfig: {},
makers: [
{
name: '@electron-forge/maker-squirrel',
config: {},
},
{
name: '@electron-forge/maker-zip',
platforms: ['darwin'],
},
{
name: '@electron-forge/maker-deb',
config: {},
},
{
name: '@electron-forge/maker-rpm',
config: {},
},
],
plugins: [
{
name: '@electron-forge/plugin-auto-unpack-natives',
config: {},
},
// Fuses are used to enable/disable various Electron functionality
// at package time, before code signing the application
new FusesPlugin({
version: FuseVersion.V1,
[FuseV1Options.RunAsNode]: false,
[FuseV1Options.EnableCookieEncryption]: true,
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
[FuseV1Options.EnableNodeCliInspectArguments]: false,
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: false, // 是否验证 ASAR 归档文件的完整性
[FuseV1Options.OnlyLoadAppFromAsar]: false, // 将 Electron 查找应用代码的路径限制为仅 app.asar
}),
],
};
EnableEmbeddedAsarIntegrityValidation 是一个构建时启用的安全开关,用于确保 Electron 应用在运行时加载的 ASAR 文件未被篡改,建议与 onlyLoadAppFromAsar 一起使用,并由 Electron Forge 或 Packager 自动完成配置。
主进程中注册协议
在主进程代码(通常是main.js)中注册一个自定义协议来处理 asar 文件中的资源:
javascript
const { protocol } = require('electron');
app.whenReady().then(() => {
createWindow()
// 注册自定义协议处理videos.asar中的文件
protocol.registerFileProtocol('app', (request, callback) => {
const url = request.url.replace('app://', '');
const decodedUrl = decodeURIComponent(url);
try {
const filePath = path.join(app.getAppPath(), '..', decodedUrl);
console.log(filePath)
// 检查文件是否存在
fs.accessSync(filePath, fs.constants.R_OK);
callback(filePath);
} catch (error) {
console.error('Error accessing video file:', error);
callback({ error: 404 });
}
});
}
在渲染进程中使用视频
在 index.html(或任何渲染进程的 HTML 文件)里放宽 CSP,把 app:// 协议加入白名单。
html
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' app://*;
media-src 'self' app://*;
script-src 'self' 'unsafe-eval';
style-src 'self' 'unsafe-inline'">
-
app://* 表示允许任意 app:// 开头的资源。
-
如果只想放行媒体,可只保留 media-src 'self' app://*。
在 HTML 中使用注册的 app:// 协议引用视频文件:
html
<video src="app://videos.asar/video1.mp4" autoplay loop muted></video>
确保 videos.asar 文件夹放在打包后的resources目录下。