You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome MV3扩展注入脚本中navigator.MediaDevices返回undefined的问题

Chrome MV3扩展获取navigator.MediaDevices返回undefined的问题

我正在开发一款Chrome扩展,用来录制当前标签页的视频。脚本注入器运行正常,但尝试获取navigator.MediaDevices时返回undefined。按文档说明,这种情况一般出现在不安全上下文,但我在HTTPS标签页和localhost环境测试都是同样的结果。推测是Chrome MV3扩展的特有问题,调整manifest权限后也没解决。

注入脚本代码

async function contScript(){
    const res = await execOnCurrTab(() => {
        const nav = navigator;
        const MD  = nav.MediaDevices;
        const MS  = MD.getDisplayMedia();
    });
}

function execOnCurrTab(callback){
    return new Promise(function(resolve){
        chrome.tabs.query({ active: true }, function (tabs) {
            let tab = tabs[0];
            chrome.scripting.executeScript(
                {
                    target: { tabId: tab.id },
                    function: callback,
                    args: [tab.title],
                },
                (injectionResults) => {
                    const injRes = injectionResults[0].result;
                    console.log(injRes)
                    testObj = {
                        'res' : injRes
                    }
                    resolve(injRes);
                }
            );
        });
    });
}

Manifest权限配置

"permissions": [
  "desktopCapture",
  "activeTab",
  "storage",
  "notifications",
  "alarms",
  "scripting"
],

问题原因及解决办法

  • 上下文限制:Chrome MV3中,内容脚本无法直接调用navigator.MediaDevices.getDisplayMedia,这类需要用户授权的媒体捕获API必须通过扩展后台发起请求。
  • 正确实现流程:
    1. 在后台服务工作者中调用chrome.desktopCapture.chooseDesktopMedia获取媒体流ID:
      // service-worker.js
      chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
          if (message.type === 'startCapture') {
              chrome.desktopCapture.chooseDesktopMedia(
                  ['tab'],
                  sender.tab,
                  (streamId) => {
                      sendResponse(streamId ? {streamId} : {error: '用户取消捕获'});
                  }
              );
              return true; // 保持消息通道开放以处理异步响应
          }
      });
      
    2. 修改内容脚本,改为向后台请求流ID后再获取媒体流:
      async function contScript(){
          const response = await chrome.runtime.sendMessage({type: 'startCapture'});
          if (response.streamId) {
              const mediaStream = await navigator.mediaDevices.getUserMedia({
                  video: {
                      mandatory: {
                          chromeMediaSource: 'desktop',
                          chromeMediaSourceId: response.streamId,
                          maxWidth: screen.width,
                          maxHeight: screen.height
                      }
                  }
              });
              // 这里可以添加录制逻辑,比如使用MediaRecorder
          }
      }
      
    3. 在manifest中注册后台服务工作者:
      "background": {
          "service_worker": "service-worker.js"
      },
      
  • 权限说明:现有desktopCapture和activeTab权限足够,无需额外添加,但要确保扩展安装时权限申请正常。

内容的提问来源于stack exchange,提问作者Corvus Corax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 06:15:12