dani_l_n
dani_l_n

Reputation: 406

interaction of a chrome extension based on React TSX UI chrome API

I'm attempting to build some extension which contains a form and an option to capture screen with desktopCapture, which looks like this:

enter image description here

The form is written in React TypeScript and the code for capturing the screen (taken from here) is the following:

chrome.runtime.onMessage.addListener(
  (message, sender, senderResponse) => {
    if (message.name === "stream" && message.streamId) {
      let track, canvas;
      navigator.mediaDevices
        .getUserMedia({
          video: {
            mandatory: {
              chromeMediaSource: "desktop",
              chromeMediaSourceId: message.streamId,
            },
          },
        })
        .then((stream) => {
          track = stream.getVideoTracks()[0];
          const imageCapture = new ImageCapture(track);
          return imageCapture.grabFrame();
        })
        .then((bitmap) => {
          track.stop();
          canvas = document.createElement("canvas");
          canvas.width = bitmap.width;
          canvas.height = bitmap.height;
          let context = canvas.getContext("2d");
          context.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height);
          return canvas
            .toDataURL()
            .then((url) => {
              //TODO download the image from the URL
              chrome.runtime.sendMessage(
                { name: "download", url },
                (response) => {
                  if (response.success) {
                    alert("Screenshot saved");
                  } else {
                    alert("Could not save screenshot");
                  }
                  canvas.remove();
                  senderResponse({ success: true });
                }
              );
            })
            .catch((err) => {
              alert("Could not take screenshot");
              senderResponse({ success: false, message: err });
            });
        });
    }
    return true;
  }
);

My intention is that when the user will click on "take screen shot", the code above will run, and then, on save, the image will be presented in that box.

I was able to 'grab' the two elements, both the box where I wish the image to appear after screenshooting, and the "TAKE SCREEN SHOT" button.

as far as I'm aware of, content_script only injects into web-pages (browser), and has no access to extension, therefor, that's not the way to add the code inside..

What am I missing? How could I add an eventListener, that if the button is clicked, the screenCapturing code will run, and I'll be able to set the box to be the captured image?

Best regards!

Upvotes: 0

Views: 357

Answers (1)

Anil kumar
Anil kumar

Reputation: 1628

As i understand, you want to take screenshot of tab's page content. (I assume you don't need to grab playing video or audio content)

Fix 1: Use chrome.tabs.captureVisibleTab api for capture screenshot. API link chrome.tabs

Add this in background.js

const takeShot = async (windowId) => {
try {
    let imgUrl64 = await chrome.tabs.captureVisibleTab(windowId, { format: "jpeg", quality: 80 });
    console.log(imgUrl64);
    chrome.runtime.sendMessage({ msg: "update_screenshot",imgUrl64:imgUrl64});
} catch (error) {
    console.error(error);
}
};

chrome.runtime.onMessage.addListener(async (req, sender, sendResponse) => {
    if(req.msg === "take_screenshot") takeShot(sender.tab.windowId)
}

Fix 2: Content_script has limited api access.

Check this page. Understand content script capabilities

Solution: Send message from content_script to background and ask them to capture screenshot. Background capture screenshot

content.js

chrome.runtime.sendMessage({ msg: "take_screenshot"});

popup.js

chrome.runtime.onMessage.addListener(async (req, sender, sendResponse) => {
        if(req.msg === "update_screenshot") console.log(req.imgUrl64)
    }

Upvotes: 1

Related Questions