So I'm trying to capture web audio from a tab and pass it into another script that works with DOM elements on the page.
EXTENSION SCRIPT
In the background.js
, I use the following script:
chrome.tabCapture.capture(constraints, function(stream) {
console.log("\ngot stream");
console.log(stream);
chrome.tabs.sendMessage(tabID, {
"message": "stream",
"stream": stream
});
});
The Developer Toolkit shows me that the created object is indeed a MediaStream object. (Which I want and appears to be working fine).
EXTENSION CONSOLE:
MediaStream {onremovetrack: null, onaddtrack: null, onended: null, ended: false, id: "c0jm4lYJus3XCwQgesUGT9lpyPQiWlGKHb7q"…}
CONTENT SCRIPT
I use a content script (injected), on the page itself to then pull the JSON serialized object back out:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.message === "stream") {
var thisStream = request.stream;
console.log(thisStream);
if (!thisStream) {
console.log("stream is null");
return;
}
loadStream(thisStream);
}
else if (request.message === "statusChanged") {
console.log("statusChanged");
}
});
PAGE CONSOLE
Unfortunately, because of JSON serialization, the object type is lost:
Object {onremovetrack: null, onaddtrack: null, onended: null, ended: false, id: "c0jm4lYJus3XCwQgesUGT9lpyPQiWlGKHb7q"…}
I need the object recast as a MediaStream object and have tried the following things which all failed:
Attempt 1: FAILED
var stream = new webkitMediaStream;
function loadStream(thisStream) {
stream = thisStream;
}
Attempt 2: FAILED
var stream;
function loadStream(thisStream) {
stream = new webkitMediaStream(thisStream);
}
Attempt 3: FAILED
var stream;
function loadStream(thisStream) {
stream = Object.create(webkitMediaStream, thisStream);
}
NOTE:
The constructor for the MediaStream
object IS webkitMediaStream
.
I need either a better method for passing the object from the extension script (the only place the chrome.tab.capture()
method works from) to the content script (the only place that has access to and can modify the DOM elements of the page),
OR
I need a way of recasting the JSON serialized object back into a fully functional MediaStream
object.
Thanks in advance!
JRad the Bad
Extension messages are always JSON-serialized, so it's indeed obvious that you cannot send a
MediaStream
from the background page to the web page. The question is, do you really need to send theMediaStream
from the background to the content script?URL.createObjectURL
to get ablob:
-URL for the stream and assign it tovideo.src
to see a video. The URL created byURL.createObjectURL
can only be used by a page at the same origin, so you need to create the<video>
tag in achrome-extension://
page; either in a tab, or in a frame. If you want to do this in a frame, make sure that the page is listed inweb_accessible_resources
.If you DO really need a
MediaStream
object of the tab in the tab, thenRTCPeerConnection
can be used to send the stream. This WebRTC API is normally used to exchange media streams between peers in a network, but it can also be used to send streams from one page to another page in another tab or browser.Here's a full example. Visit any web page, and click on the extension button. Then the extension will insert a video in the page showing the current tab.
background.js
contentscript.js
manifest.json