我正在尝试开发一个小应用程序,我首先通过aperture
包捕获屏幕,然后尝试使用video
标记在屏幕上显示它。
我通过以下方式捕获屏幕:
import apertureConstructor from 'aperture';
const aperture = apertureConstructor();
const options = {
fps: 30
};
(async () => {
await aperture.startRecording(options);
setTimeout(async () => {
this.captureUrl = await aperture.stopRecording();
}, 3000)
})();
请忽略这一切。 Aperture
包将捕获的视频写入磁盘,最终,我在captureUrl
中找到了此文件的路径。它是这样的:
/var/folders/29/08gshk3n4mlbbcjnm1m5xyy40000gp/T/tmp-79999m0uOszQK0zaC.mp4
如果我输入:file:///var/folders/29/08gshk3n4mlbbcjnm1m5xyy40000gp/T/tmp-79999m0uOszQK0zaC.mp4
到Google Chrome地址栏,我可以验证此文件是否存在且播放正常。
因此,我尝试将此地址用作video
标记的来源,如下所示:
<video control autoplay>
<source src="/var/folders/29/08gshk3n4mlbbcjnm1m5xyy40000gp/T/tmp-8004145a2o4gugbVV.mp4" type="video/mp4">
</video>
抱怨该文件不存在(404):
GET http://localhost:9080/var/folders/29/08gshk3n4mlbbcjnm1m5xyy40000gp/T/tmp-8004145a2o4gugbVV.mp4 404 (Not Found)
是的,它确实试图转到localhost:9080
,因为在这种情况下它是我的开发服务器主机,并且没有这样的文件。
所以我决定添加file://
...
<video controls autoplay>
<source src="file:///var/folders/29/08gshk3n4mlbbcjnm1m5xyy40000gp/T/tmp-8004145a2o4gugbVV.mp4" type="video/mp4">
</video>
这次它说:
Not allowed to load local resource: file:///var/folders/29/08gshk3n4mlbbcjnm1m5xyy40000gp/T/tmp-80041e3SlBZUNphLM.mp4
:/
我想知道我是否错过了一些让#34; file://&#34;安全或其他。
我还想过通过&#34; fs&#34;来阅读整个文件。和base64提供视频data:
,但由于这个视频文件可能很大,我觉得我不应该这样做。
因为我是electron
的新手,我希望我会错过一些基本的东西。任何帮助表示赞赏。谢谢!
答案 0 :(得分:1)
很高兴看到熟悉此处的人提出的问题。 :)
我建议您在BrowserWindow中禁用网络安全首选项。还有一个issue与此主题相关。
答案 1 :(得分:0)
我最近遇到了同样的问题。您可以设置(在主过程中):
webPreferences: {
webSecurity: false
}
这将允许您从用户的HDD加载file://
网址。但是,这确实是不好的做法,因为它会提高安全性。
可接受的方式是:
webPreferences: {
webSecurity: true
}
然后,从您的主流程中创建一个Web服务器,该服务器提供所需的文件。
在您的主要过程中:
const http = require('http')
const express = require('express')
const expressApp = express()
const cors = require('cors')
const router = express.Router()
然后执行以下代码:
expressApp.use(cors())
router.get('/file/:name', function (req, res) {
let filename = req.params.name
res.sendFile(filename)
})
expressApp.use('/', router)
http.createServer(expressApp).listen(8000)
现在,在渲染器代码的js / html中,您可以将视频代码中的src
设置为:
'http://localhost:8000/file/' + filename
答案 2 :(得分:0)
既然已经有一个公认的答案,我就告诉你我是如何为可能遇到同样问题的人解决这个问题的。
此时有一种方法可以通过使用 protocol 来做到这一点,即使您指定
webPreferences: {
webSecurity: true,
}
通常显示图像或播放文件中的视频
<video controls autoplay>
<source src="file:///path-to-video.mp4">
</video>
但这不适用于 webpack,因为 webpack 会生成一个服务器,并且默认情况下,出于安全原因,不会加载以 file://
开头的所有内容。如果电子加载了 file://index.html
,那么它可能会工作,但 protocol 方式非常酷,您可以保护您的资源。
要解决您的问题,您可以执行以下操作:
const { protocol } = require('electron');
function fileHandler(req, callback){
let requestedPath = req.url
// Write some code to resolve path, calculate absolute path etc
let check = // Write some code here to check if you should return the file to renderer process
if (!check){
callback({
// -6 is FILE_NOT_FOUND
// https://source.chromium.org/chromium/chromium/src/+/master:net/base/net_error_list.h
error: -6
});
return;
}
callback({
path: requestedPath
});
}
// Then in electron main.js
app.on("ready", () => {
protocol.registerFileProtocol(
'your-custom-protocol',
fileHandler,
);
// Create some window you can even use webPreferences: true
});
然后你可以像这样在你的html代码中使用它
<video controls autoplay>
<source src="your-custom-protocol:///path-to-video.mp4">
</video>
通过这样做,您可以确保您的应用是安全的,并且它不会从文件系统中请求随机文件,并且它也能很好地与 webpack 配合使用。
有关这方面的更多信息,有一个 github 存储库来展示电子中的安全模式。 看看它here