Reputation: 491
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:
var video = document.getElementById("video");
var objectUrl = URL.createObjectURL(stream);
video.src = objectUrl;
//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
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
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