10

I am trying to implement a screen sharing web application that will use the desktopCapture Chrome API to display the users screen on a web page. I have created the chrome extension and have an event listener running in the background. My problem is when I try to send a message from the web page to the extension (to get the userMedia id) I am not receiving anything on the extension side. I am also trying to return the getUserMedia id back to the webpage to display the feed. I have attached what I have. Thanks

Manifest

{
"name": "Class Mate Manifest",
"description": "Extension that allows for user to share their screen",
"version": "1",
"manifest_version": 2,

"background": {
  "scripts": ["background.js"]
},
"permissions": [
"desktopCapture",
"tabs"
],
"browser_action": {
  "default_icon": "icon.png",
"default_popup": "index.html"
    }
 }

background.js

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(request.greeting);
if(request.greeting == yes){
 chrome.desktopCapture.chooseDesktopMedia(["screen", "window"], sendResponse);
 return true;
 }
 });

webpage.js

function gotStream(stream) {
console.log("Received local stream");
var video = document.querySelector("video");
video.src = URL.createObjectURL(stream);
localstream = stream;
// stream.onended = function() { console.log("Ended"); };
}

function getUserMediaError() {
console.log("getUserMedia() failed.");
}

function onAccessApproved(id) {
console.log(id);
if (!id) {
console.log("Access rejected.");
return;
}


navigator.webkitGetUserMedia({
  audio:false,
  video: { mandatory: { chromeMediaSource: "desktop", chromeMediaSourceId: id } }
}, gotStream, getUserMediaError);

}


chrome.runtime.sendMessage({greeting: "yes"}, onAccessApproved);
bigC5012
  • 589
  • 1
  • 5
  • 19

1 Answers1

14

You cannot simply use messaging the same way you would use it in a content script from an arbitrary webpage's code.

There are two guides available in the documentation for communicating with webpages, which correspond to two approaches: (externally_connectable) (custom events with a content script)

Suppose you want to allow http://example.com to send a message to your extension.

  1. You need to specifically whitelist that site in the manifest:

      "externally_connectable" : {
        matches: [ "http://example.com" ]
      },
    
  2. You need to obtain a permanent extension ID. Suppose the resulting ID is abcdefghijklmnoabcdefhijklmnoabc

  3. Your webpage needs to check it's allowed to send a message, then send it using the pre-defined ID:

    // Website code
    // This will only be true if some extension allowed the page to connect
    if(chrome && chrome.runtime && chrome.runtime.sendMessage) {
      chrome.runtime.sendMessage(
        "abcdefghijklmnoabcdefhijklmnoabc",
        {greeting: "yes"},
        onAccessApproved
      );
    }
    
  4. Your extension needs to listen to external messages and probably also check their origin:

    // Extension's background code
    chrome.runtime.onMessageExternal.addListener(
      function(request, sender, sendResponse) {
        if(!validate(request.sender)) // Check the URL with a custom function
          return;
        /* do work */
      }
    );
    
Community
  • 1
  • 1
Xan
  • 74,770
  • 16
  • 179
  • 206
  • Yes you were correct. I was able to send a message from my web page using the externally connectable approach you mentioned. But now once I send the message, the extension receives the message properly but does not send anything back via the callback function. So my chrome extension is suppose to send back an id to use to share the screen. But on the web page side the callback method is not even being ran. Any thoughts? – bigC5012 Sep 30 '14 at 02:35
  • So I have fixed my error in my previous comment. Now the web page successfully sends a message to the extension. The extension receives the message and asks the user what screen they wish to capture. Then the background.js file sends the correct id to the webpage. Once my web page runs onAccessAproved, it fails to load the video stream and runs the getUserMediaError function. I printed out the error on the console and it says NavigateUserMediaError. I do not know what this error means or what is wrong in my code? – bigC5012 Sep 30 '14 at 21:37
  • I would make a new question about that. – Xan Sep 30 '14 at 21:39
  • What do you mean by? 1) Point 4: is this the code you usually put in manifest.json > background.js > here? 2) Point 3: is this the code you put in your `http://example.com/index.html` or `https://example.com/index.html` ? –  Feb 03 '16 at 10:24
  • 1
    @YumYumYum I hope I clarified it now. – Xan Feb 03 '16 at 10:38
  • How about the other way? Sending a message from-extension-to-webpage? – Kalnode Dec 28 '22 at 15:29