Electron将视频文件单独打包成asar并调用

要将视频文件放到单独的 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目录下。

相关推荐
Mr.Jessy6 小时前
JavaScript高级:构造函数与原型
开发语言·前端·javascript·学习·ecmascript
白兰地空瓶8 小时前
🚀你以为你在写 React?其实你在“搭一套前端操作系统”
前端·react.js
爱上妖精的尾巴9 小时前
6-4 WPS JS宏 不重复随机取值应用
开发语言·前端·javascript
似水流年QC9 小时前
深入探索 WebHID:Web 标准下的硬件交互实现
前端·交互·webhid
陪我去看海9 小时前
测试 mcp
前端
speedoooo10 小时前
在现有App里嵌入一个AI协作者
前端·ui·小程序·前端框架·web app
全栈胖叔叔-瓜州10 小时前
关于llamasharp 大模型多轮对话,模型对话无法终止,或者输出角色标识User:,或者System等角色标识问题。
前端·人工智能
三七吃山漆10 小时前
攻防世界——wife_wife
前端·javascript·web安全·网络安全·ctf
用户479492835691510 小时前
面试官问"try-catch影响性能吗",我用数据打脸
前端·javascript·面试
GISer_Jing11 小时前
前端营销技术实战:数据+AI实战指南
前端·javascript·人工智能