我正在开发一个带有 React 前端的 Electron 应用程序,旨在执行一些视频任务。目前,我正在后端加载一个视频文件,将其转换为 base64 数据格式,然后将其发送到 React 前端以将其用作视频播放器的源。这按预期工作。
虽然这对于较小的视频文件非常有用,但发送的数据大小有限制。
我想知道是否有一种实际的方法可以让 React 通过传递本地 url 作为源来直接加载媒体文件?我知道出于网络安全原因这是不允许的,但我的应用程序封装在 Electron 内并且不连接到互联网。
如果这是不可能的,或者,加载大型媒体文件(4GB 等大小)以在播放器中查看的最佳方式是什么?
直接在 React 组件中导入视频文件不是一个选项,因为视频是由用户通过从本地系统选择来动态导入的。
任何帮助将不胜感激。
我终于找到了解决方案。大多数地方的表述都是错误的。所以我决定更新对其他正在寻找答案的人有用的内容。
不要禁用webSecurity
,正如许多地方建议的那样。保留此功能很重要。如果您必须这样做,那么您可以将其值设置为
webSecurity: app.isPackaged
。这样,在开发过程中它将被关闭,但在生产版本中它将被打开。由于该应用程序是从生产版本中的文件部署的,因此本地媒体可以按预期工作。但这里是
webSecurity
仍然启用的实际修复。解决方案
2024年更新
原始解决方案已被弃用。您现在可以执行以下操作来实现相同的目标。
const { app, protocol, net } = require('electron')
app.whenReady().then(() => {
protocol.handle('media-loader', (request) =>
net.fetch('file://' + request.url.slice('media-loader://'.length)))
})
您可以更新 file://
以匹配您需要的任何类型的 URL。
自定义协议来处理您的媒体。我之前已经尝试过很多次,但不幸的是,由于某种原因,官方文档上的代码没有返回值。所以直接复制是行不通的。
app.whenReady().then(() => {
// Create custom protocol for local media loading
protocol.registerFileProtocol("media-loader", (request, callback) => {
const url = request.url.replace("media-loader://", "");
try {
return callback(url);
} catch (err) {
console.error(error);
return callback(404);
}
});
// Create Window
createWindow();
});
一旦有了这个新的协议设置,只需使用其绝对路径直接加载媒体即可。
<video src={`media-loader://${path}`}></video>
通过此设置,您不再需要创建 ObjectURL 或通过 IPC 传递媒体文件,IPC 性能不高,并且对您可以加载的文件大小有限制。