Use desktopCapturer in sandboxed renderer process


#1

I would like to use desktopCapturer (https://github.com/electron/electron/blob/master/docs/api/desktop-capturer.md) in a sandboxed renderer process. I don’t see availability as of electron 1.6.5.

According to documentation here: https://github.com/electron/electron/blob/master/docs/api/sandbox-option.md … can use electron (crashReporter, remote and ipcRenderer) but no desktopCapturer :frowning:

Any ideas how this might be possible? Or would I need to request electron add desktopCapturer API in the sandbox?

Basically, I am trying to build a desktop picker dialog for media sources in a screen sharing app, similar to describe here: https://github.com/electron/electron/issues/4432

Thanks.


#2

To answer my own question… one not so entirely kosher/stable way to accomplish this feat is utilized ipc message available in renderer process: ‘ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES’. This is available even in sandboxed renderer. Found this when digging through electron.asar file that comes with prebuilt electron node module. Of course, since this is essentially a private messaging interface, it is subject to change without notice. Below is sample code modified from electron.asar that works in sandboxed renderer…

var nextId = 0
var includes = [].includes

function getNextId() {
  return ++nextId
}

// |options.type| can not be empty and has to include 'window' or 'screen'.
function isValid(options) {
  return ((options != null ? options.types : void 0) != null) && Array.isArray(options.types)
}

function getSources(options, callback) {
  var captureScreen, captureWindow, id
  if (!isValid(options)) {
    return callback(new Error('Invalid options'))
  }
  captureWindow = includes.call(options.types, 'window')
  captureScreen = includes.call(options.types, 'screen')
  if (options.thumbnailSize == null) {
    options.thumbnailSize = {
      width: 150,
      height: 150
    }
  }
  id = getNextId()
  local.ipcRenderer.send('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', captureWindow, captureScreen, options.thumbnailSize, id)
  return local.ipcRenderer.once('ELECTRON_RENDERER_DESKTOP_CAPTURER_RESULT_' + id, function (event, sources) {
    var source
    callback(null, (function () {
      var i, len, results
      results = [];
      for (i = 0, len = sources.length; i < len; i++) {
        source = sources[i]
        results.push({
          id: source.id,
          name: source.name,
          thumbnail: source.thumbnail
        })
      }
      return results
    })())
  })
}