user1710407
user1710407

Reputation: 491

Show video from chrome.desktopCapture.chooseDesktopMedia in a tab?

I am trying out chrome.desktopCapture.chooseDesktopMedia in a chrome extension and I can get a desktop stream just fine.

I am using the following to turn the stream into an blob:-URL in the background script as follows:

var objectUrl = URL.createObjectURL(stream);

What I can't seem to work out is how to set this as the src attribute of a video element on the injected page.

I have tried the following, each of which do not work:

In Background.js:

var video     = document.getElementById("video");
var objectUrl = URL.createObjectURL(stream);
video.src     = objectUrl;

In Content.js

//objectUrl is a string received in a message from the background page by the content page
var video     = document.getElementById("video");
video.src     = objectUrl;

I get the following in the javascript console:

Not allowed to load local resource: blob:chrome-extension://panahgiakgfjeioddhenaabbacfmkclm/48ff3e53-ff6a-4bee-a1dd-1b8844591a91

I also get the same if I post the URL in a message all the way to the injected page. Should this work? I'd really appreciate any advice here.

In my manifest I also have "web_accessible_resources": [ "*" ] but that was only to see if it resolved this issue (it did not).

Upvotes: 2

Views: 3513

Answers (2)

Rob W
Rob W

Reputation: 349122

In a content script, the DOM is shared with the page, so any DOM operations (such as setting the video src) is subject to the same-origin policy of the page, not the extension.

If you want to show the content of a tab, then you MUST pass a tab.Tab object to chrome.desktopCapture.chooseDesktopMedia. This object can be obtained in many ways, including the message passing and tabs APIs. Here is an example using the extension button:

background.js

chrome.browserAction.onClicked.addListener(function(tab) {
    // NOTE: If you want to use the media stream in an iframe on an origin
    // different from the top-level frame (e.g. http://example.com), set
    //  tab.url = 'http://example.com'; before calling chooseDesktopMedia!
    //  (setting tab.url only works in Chrome 40+)
    chrome.desktopCapture.chooseDesktopMedia([
        'screen', 'window'//, 'tab'
    ], tab, function(streamId) {
        if (chrome.runtime.lastError) {
            alert('Failed to get desktop media: ' +
                chrome.runtime.lastError.message);
            return;
        }   

        // I am using inline code just to have a self-contained example.
        // You can put the following code in a separate file and pass
        // the stream ID to the extension via message passing if wanted.
        var code = '(' + function(streamId) {
            navigator.webkitGetUserMedia({
                audio: false,
                video: {
                    mandatory: {
                        chromeMediaSource: 'desktop',
                        chromeMediaSourceId: streamId
                    }   
                }   
            }, function onSuccess(stream) {
                var url = URL.createObjectURL(stream);
                var vid = document.createElement('video');
                vid.src = url;
                document.body.appendChild(vid);
            }, function onError() {
                alert('Failed to get user media.');
            }); 
        } + ')(' + JSON.stringify(streamId) + ')';

        chrome.tabs.executeScript(tab.id, {
            code: code
        }, function() {
            if (chrome.runtime.lastError) {
                alert('Failed to execute script: ' +
                    chrome.runtime.lastError.message);
            }   
        }); 
    }); 
});

manifest.json

{
    "name": "desktopCapture.chooseDesktopMedia for a tab",
    "version": "1",
    "manifest_version": 2,
    "background": {
        "scripts": ["background.js"]
    },
    "browser_action": {
        "default_title": "Show desktop capture request"
    },
    "permissions": [
        "desktopCapture",
        "activeTab"
    ]
}

Upvotes: 5

Scott
Scott

Reputation: 614

ObjectURLs can't be shared cross-origin. A Data URL can be shared cross-origin if it works with your video stream (I'm not sure).

Upvotes: 0

Related Questions