user285594
user285594

Reputation:

Google Chrome - Screen capture failing when iframe is used, same script works without iframe

When i use this following script it works with normal browser. But when iframe is used then its showing me this error:

Does anyone know what is causing this and can be resolved?

ERROR:

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

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"
  ]
}

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;
        }
    });
});

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);
});

Upvotes: 7

Views: 3643

Answers (2)

Rob W
Rob W

Reputation: 348962

This is caused by the fact that the a stream can only be used by frames whose URL match the origin of the tab. Starting with Chrome 40, you can use the stream in frames as well if you set tab.url to a URL whose origin matches the frame (crbug.com/425344).

The stream is only valid for ten seconds, so you have to follow the following flow:

  1. Load the iframe that contains the page that should handle the stream. This page must be served from a secure scheme, e.g. https: or chrome-extension:.
  2. Send the frame's origin (location.origin) to the background page.
  3. Request the desktop stream using the tab info, with tab.url set to the frame's URL or origin.
  4. Send the streamId back to the frame and use it (within ten seconds).

Example (based on the code in the question):

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
    });

Upvotes: 5

user285594
user285594

Reputation:

1 - this is not a code problem, browser problem

2 - this is not working because i am launching the extension from HTTP (http://www.maindomain.com) using iframe a HTTPS (https://subdomain.maindomain.com) link which is using the browser extension

So to fix it. I needed to use HTTPS (https://www.maindomain.com) opening HTTPS iframe links (https://subdomain.maindomain.com) . Since then it works now.

Hope this help others.

NOTE: problem occurred: when i run the iframe from same subdomain subdomain.maindomain.com/test.php (iframe src=subdomain.maindomain.com/core.php) then it works. But when i am running it as maindomain.com/otherpages (iframe src=subdomain.maindomain.com/core.php) then this is not working. Was very confusing.

EDIT: This still did not resolved the problem. screen share dialog box opens but when i press share screen then it gives same error and fails.

Upvotes: 0

Related Questions