谷歌浏览器 - 使用iframe时屏幕截图失败,相同的脚本无需iframe

7 javascript iframe google-chrome google-chrome-extension webrtc

当我使用以下脚本时,它适用于普通浏览器.但是当使用iframe时它会显示我的错误:

有谁知道造成这种情况的原因可以解决吗?

错误:

channel message Object {type: "getScreenPending", id: 24504, request: 6} content.js:4
channel message Object {type: "gotScreen", id: 24504, request: 6} content.js:4
>>> ShareScreen: if any err NavigatorUserMediaError {constraintName: "", message: "", name: "InvalidStateError"} test.js:1616
Run Code Online (Sandbox Code Playgroud)

manifest.json的:

{
  "name": "Screen sharing",
  "description": "Screensharing utility",
  "version": "0.0.2",
  "manifest_version": 2,
  "minimum_chrome_version": "34",
  "icons": {
    "48" : "icon.png"
  },
  "permissions": [
    "desktopCapture"
  ],
  "background": {
    "scripts": ["background.js"]
  },
  "content_scripts": [ {
    "js": [ "content.js" ],
    "all_frames": true,
    "run_at": "document_start",
    "matches": ["*://*.a.com/*", "*://*.b.com/*"]
  }],
  "web_accessible_resources": [
        "icon.png"
  ]
}
Run Code Online (Sandbox Code Playgroud)

background.js:

/* background page, responsible for actually choosing media */
chrome.runtime.onConnect.addListener(function (channel) {
    channel.onMessage.addListener(function (message) {
        switch(message.type) {
        case 'getScreen':
            var pending = chrome.desktopCapture.chooseDesktopMedia(message.options || ['screen', 'window'], 
                                                                   channel.sender.tab, function (streamid) {
                // communicate this string to the app so it can call getUserMedia with it
                message.type = 'gotScreen';
                message.sourceId = streamid;
                channel.postMessage(message);
            });
            // let the app know that it can cancel the timeout
            message.type = 'getScreenPending';
            message.request = pending;
            channel.postMessage(message);
            break;
        case 'cancelGetScreen':
            chrome.desktopCapture.cancelChooseDesktopMedia(message.request);
            message.type = 'canceledGetScreen';
            channel.postMessage(message);
            break;
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

content.js:

/* the chrome content script which can listen to the page dom events */
var channel = chrome.runtime.connect();
channel.onMessage.addListener(function (message) {
    console.log('channel message', message);
    window.postMessage(message, '*');
});

window.addEventListener('message', function (event) {
    if (event.source != window)
        return;
    if (!event.data && (event.data.type == 'getScreen' || event.data.type == 'cancelGetScreen'))
        return;
    channel.postMessage(event.data);
});
Run Code Online (Sandbox Code Playgroud)

Rob*_*b W 5

这是因为一个流只能由其URL匹配选项卡原点的帧使用.从Chrome 40开始,如果您设置tab.url为原点与框架匹配的网址(crbug.com/425344),则也可以在框架中使用流.

该流仅在十秒内有效,因此您必须遵循以下流程:

  1. 加载包含应处理流的页面的iframe.此页面必须通过安全方案提供,例如https:chrome-extension:.
  2. 将帧的原点(location.origin)发送到后台页面.
  3. 使用选项卡信息请求桌面流,并将其tab.url设置为框架的URL或源.
  4. 将streamId发送回帧并使用它(在十秒内).

示例(基于问题中的代码):

var tab = channel.sender.tab;
// NEW (Chrome 40+)
tab.url = message.url; // Your custom message, e.g. {url: location.origin}
chrome.desktopCapture.chooseDesktopMedia(['screen', 'window'], tab,
    function (streamid) {
        // ... see question for the rest of the code
    });
Run Code Online (Sandbox Code Playgroud)