Electron支持WebRTC 屏幕分享的关键

Electron 可以很方便的创建一个窗口,然后加载指定的网页来呈现。但如果网页中包含了WebRTC 屏幕分享相关的逻辑,则会发现Electron会和Chrome浏览器表现不同。

问题在于Electron未能实现Chrome所支持的Web RTC的getDisplayMedia接口,导致本应该跳出视频流选择的界面未能显示出来。

解决方法:

Electron提供了desktopCapturer.getSources用来实现类似getDisplayMedia的功能,因为我们可以在BrowserWindow的preload中重写navigator.mediaDevices.getDisplayMedia方法

类似于:

window.navigator.mediaDevices.getDisplayMedia = () => {  
    return new Promise(async (resolve, reject) => {
      try {
        const sources = await desktopCapturer.getSources({ types: ['screen'] })
        const stream = await window.navigator.mediaDevices.getUserMedia({
            audio: false,
            video: {
              mandatory: {
                chromeMediaSource: 'desktop',
                chromeMediaSourceId: sources[0].id
              }
            }
          })
          resolve(stream)
        }catch(err){
            reject(err)
        }       
    })
  }

  我这里只默认获取了第一个source,也就是主屏幕。

 关键的地方:

Electron新版本,默认在preload中的js和网页中的js是隔离的,也就是contextisolation的设置为true,这会导致,在preload中设置的上述方法在网页中不起作用,因此需要将contextisolation设置为false

带来的额外的问题就是contextBridge就没法使用了,后者通过contextBridge.exposeInMainWorld()的方式,可以向网页注入属性或者方法

我自己的设置(测试可行):

    mainwindow = new BrowserWindow({
        show: false,
        title: appName,
        icon: 'app/assets/examclient_128.ico',
        webPreferences: {
            preload: path.join(__dirname, 'preload.js'),
            nodeIntegration: false,
            devTools: true,
            webSecurity:false,
            experimentalFeatures:true,
            contextIsolation:false
        }
    });    
posted @ 2021-08-26 12:12  chyshx  阅读(3141)  评论(0编辑  收藏  举报