electron访问本机摄像头

前言:chrome访问windows摄像头只有两种情况下符合(1、https协议下  2、谷歌浏览器白名单),由于项目问题,需要在http协议环境下访问摄像头。于是百度了很多方法,大部分都没有生效,也可能是我配置有问题

一、环境介绍

1、https下浏览器中音视频权限都是可访问的
 2、http下浏览器是禁止访问的权限

 于是我需要在electron中给应用程序能够访问音视频的权限,在electron中http能够访问音视频权限的我找到了三种方法

1、使用内置模块protocol的registerSchemesAsPrivileged方法

2、指定网址当成安全协议

3、设置自定义权限的检查和处理权限请求,来管理 electron 中 web 页面的权限请求

二、解决方案

1、官网描述:protocol.registerSchemesAsPrivileged内置方法

具体使用方法如下:

const { protocol } = require('electron')

protocol.registerSchemesAsPrivileged([
  {
    scheme: 'http',
    privileges:
    {
      standard: true,
      secure: true,
      bypassCSP: true,
      allowServiceWorkers: true,
      supportFetchAPI: true,
      corsEnabled: true,
      stream: true
    }
  }
])

把指定的协议当成安全的协议,从而去调用本机摄像头等设备,开启后该协议所有网址都会被视为安全网址,安全性会降低。此方法我本地调试后依旧无法获取到流视频

2、指定网址当成安全协议

第二个参数为数组,可以设置多个指定网址为安全协议

const { app } = require('electron')

app.commandLine.appendSwitch('unsafely-treat-insecure-origin-as-secure', ['http://172.16.30.151:8086', 'http://localhost:8086'])

此方法设置后依旧行不通,chrome中设置了白名单后也不行

3、自定义请求权限可以响应权限

session.setPermissionCheckHandler(handler):设置回调函数来自定义权限的检查,

每当 electron 中的 web 页面请求权限时,这个回调函数会被调用。你可以在这个回调函数中决定是否允许或拒绝该权限。回调函数的签名为:handler(webContents, permission, callback)

  • webContents:表示请求权限的 Web 页面的 WebContents 对象。
  • permission:表示请求的权限类型,例如 'media'(访问摄像头和麦克风)、'geolocation'(地理位置)、'notifications'(通知)等。
  • callback:一个回调函数,你可以调用它来传递是否允许该权限的决定,形如 callback(true)(允许)或 callback(false)(拒绝)。

session.setPermissionRequestHandler(handler):允许设置回调函数来处理权限请求的用户界面。当 electron 中的 web 页面请求权限并且 session.setPermissionCheckHandler 未决定是否允许该权限时,该回调函数会被调用。

回调函数的签名为:handler(webContents, permission, callback),参数和返回值与 session.setPermissionCheckHandler 的回调函数相同。

这两个都是用于管理 electron 中 web 页面的权限请求的 api

const { BrowserWindow } = require('electron')
const webBrowserWindow = new BrowserWindow({
  width: 1600,
  height: 1200,
  webPreferences: {
    contextIsolation: false, // 沙箱 上下文隔离
    nodeIntegration: true, // 允许html页面上的 javascipt 代码访问 nodejs 环境 api
    // preload: path.join(__dirname, 'preload.js'),
    // 允许访问摄像头和麦克风
    allowMediaDevices: true,
    // backgroundThrottling: false,   // 设置应用在后台正常运行
  }
})
// 获取当前窗口的会话对象
const session = webBrowserWindow.webContents.session
// 响应 session 的权限请求
session.setPermissionRequestHandler((_, permission, callback) => {
  // if (webBrowserWindow.webContents.getURL() === 'http://hostlocal:8086/') {
  //   return callback(true)
  // }
  // 默认响应全部请求
  callback(true)
})
session.setPermissionCheckHandler(() => true)
// 初始化摄像头
initCamera () {
  try {
    // 获取 windows 可用媒体设备信息
    navigator.mediaDevices.enumerateDevices().then(devices => {
      // console.log('devices', devices)
      // 根据设备id判断具体使用哪个摄像头
      for (const key in devices) {
        if (devices[key].kind === this.deviceKind) {
          this.device = devices[key]
          break
        }
      }
    })
  } catch (error) {
    this.errorCamera(error)
  }
}

// 打开摄像头
async openCamera () {
  // 如摄像头已打开,则直接返回
  if (this.isCameraOpen) return false
  // 约束条件 
  const constraints = {
    video: {
      frameRate: {
        ideal: 20
      },
      device: this.device.deviceId
    }
  }
  try {
    // 获取流视频
    const stream = await navigator.mediaDevices.getUserMedia(constraints)
    if (stream) {
      this.showStream(stream)
    } else {
      $message('未获取到摄像头')
    }
  } catch (error) {
    this.errorCamera(error)
  }
}

最终可以通过navigator.mediaDevices.getUserMedia()获取到流视频,是否授权音视频可在上述回调函数中自行根据业务逻辑控制。

注意:该方法是在electron社区论坛中找到。这个目前我只用于本地调试使用。具体风险暂未可知

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值