【问题标题】:Playing local mp4 file in electron在电子中播放本地 mp4 文件
【发布时间】:2018-01-15 04:37:58
【问题描述】:

我正在尝试开发一个小型应用程序,我首先通过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

如果我在 Google Chrome 地址栏输入:file:///var/folders/29/08gshk3n4mlbbcjnm1m5xyy40000gp/T/tmp-79999m0uOszQK0zaC.mp4,我可以验证该文件是否存在并且可以正常播放。

所以我尝试使用这个地址作为我的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

:/

我想知道我是否错过了使“file://”安全的东西或其他东西。

我还考虑过通过“fs”读取整个文件并通过 base64 将其提供为 data: 的视频,但由于此视频文件可能很大,我觉得我不应该那样做。

由于我是electron 的新手,我希望我错过了一些基本的东西。任何帮助表示赞赏。谢谢!

【问题讨论】:

    标签: macos html5-video electron


    【解决方案1】:

    很高兴在这里看到熟悉的人提出的问题。 :)

    我建议您禁用 BrowserWindow 中的网络安全首选项。还有一个与此主题相关的issue。

    【讨论】:

      【解决方案2】:

      我最近遇到了同样的问题。您可以设置(在主进程中):

      webPreferences: {
        webSecurity: false
      }
      

      这将允许您从用户的 HDD 加载 file:// url。但是,这确实是一种不好的做法,因为它会打开安全性。

      接受的方式是:

      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
      

      【讨论】:

      • 如果我们不只是创建一个服务器,它可以真正为文件系统上任何客户端可能要求的任何文件提供服务,我会认为这更安全......
      【解决方案3】:

      既然已经有一个公认的答案,我就告诉你我是如何为可能遇到同样问题的人解决这个问题的。

      此时有一种方法可以使用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 repo 来展示电子中的安全模式。 看看吧here

      【讨论】:

        猜你喜欢
        • 2016-06-11
        • 1970-01-01
        • 2019-01-12
        • 1970-01-01
        • 2022-06-14
        • 2014-10-21
        • 1970-01-01
        • 2019-11-22
        • 2014-01-03
        相关资源
        最近更新 更多