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

如何开发带Popup弹窗与点击触发侧边栏的Chrome录屏扩展

Chrome录屏扩展实现方案(含侧边栏注入)

核心文件分工

  • popup.html:提供扩展的点击入口(开始录制按钮),仅在点击扩展图标时显示。
  • content-script.js:负责向当前页面DOM注入侧边栏UI,处理侧边栏的交互逻辑。
  • background.js:管理录屏的核心逻辑(启动、暂停、停止录制),作为popup和content script的通信中转。
  • manifest.json:扩展的配置文件,声明权限、文件引用等。

1. manifest.json 配置

需要声明必要权限,同时指定各个文件的作用范围:

{
  "manifest_version": 3,
  "name": "屏幕录制侧边栏",
  "version": "1.0",
  "permissions": ["activeTab", "scripting", "storage", "desktopCapture"],
  "action": {
    "default_popup": "popup.html"
  },
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content-script.js"]
    }
  ]
}

2. popup.html 实现

仅保留开始录制按钮,点击后触发后台指令:

<!DOCTYPE html>
<html>
<head>
  <style>
    body { width: 150px; padding: 10px; }
    button { width: 100%; padding: 8px; cursor: pointer; }
  </style>
</head>
<body>
  <button id="startRecord">开始录制</button>
  <script src="popup.js"></script>
</body>
</html>

配套的popup.js:

document.getElementById('startRecord').addEventListener('click', async () => {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  chrome.runtime.sendMessage({ type: 'START_RECORD', tabId: tab.id });
  window.close();
});

3. content-script.js 实现

负责注入侧边栏DOM,处理计时器、暂停/停止按钮交互:

const sidebarHTML = `
  <div id="record-sidebar" style="position: fixed; right: 0; top: 0; width: 250px; height: 100vh; background: #fff; box-shadow: -2px 0 5px rgba(0,0,0,0.2); z-index: 999999; padding: 20px; box-sizing: border-box;">
    <h3>正在录制</h3>
    <div id="timer" style="font-size: 24px; margin: 20px 0; text-align: center;">00:00:00</div>
    <button id="pauseBtn" style="width: 100%; padding: 10px; margin-bottom: 10px; background: #f39c12; color: white; border: none; border-radius: 4px; cursor: pointer;">暂停</button>
    <button id="stopBtn" style="width: 100%; padding: 10px; background: #e74c3c; color: white; border: none; border-radius: 4px; cursor: pointer;">停止</button>
  </div>
`;

let timerInterval;
let seconds = 0;

chrome.runtime.onMessage.addListener((message) => {
  switch(message.type) {
    case 'SHOW_SIDEBAR':
      injectSidebar();
      startTimer();
      break;
    case 'PAUSE_RECORD':
      togglePause();
      break;
    case 'STOP_RECORD':
      stopRecording();
      break;
  }
});

function injectSidebar() {
  if (!document.getElementById('record-sidebar')) {
    document.body.insertAdjacentHTML('beforeend', sidebarHTML);
    document.getElementById('pauseBtn').addEventListener('click', () => {
      chrome.runtime.sendMessage({ type: 'PAUSE_RECORD' });
    });
    document.getElementById('stopBtn').addEventListener('click', () => {
      chrome.runtime.sendMessage({ type: 'STOP_RECORD' });
    });
  }
}

function startTimer() {
  timerInterval = setInterval(() => {
    seconds++;
    const hours = Math.floor(seconds / 3600).toString().padStart(2, '0');
    const minutes = Math.floor((seconds % 3600) / 60).toString().padStart(2, '0');
    const secs = (seconds % 60).toString().padStart(2, '0');
    document.getElementById('timer').textContent = `${hours}:${minutes}:${secs}`;
  }, 1000);
}

function togglePause() {
  const pauseBtn = document.getElementById('pauseBtn');
  if (timerInterval) {
    clearInterval(timerInterval);
    timerInterval = null;
    pauseBtn.textContent = '继续';
  } else {
    startTimer();
    pauseBtn.textContent = '暂停';
  }
}

function stopRecording() {
  if (timerInterval) clearInterval(timerInterval);
  const sidebar = document.getElementById('record-sidebar');
  if (sidebar) sidebar.remove();
  seconds = 0;
}

4. background.js 实现

处理录屏核心逻辑,以及消息中转:

let mediaRecorder;
let recordedChunks = [];
let currentTabId;

chrome.runtime.onMessage.addListener(async (message) => {
  switch(message.type) {
    case 'START_RECORD':
      currentTabId = message.tabId;
      const streamId = await chrome.desktopCapture.chooseDesktopMedia(['screen', 'window'], null);
      if (streamId) {
        const stream = await navigator.mediaDevices.getUserMedia({
          audio: true,
          video: {
            mandatory: {
              chromeMediaSource: 'desktop',
              chromeMediaSourceId: streamId
            }
          }
        });
        mediaRecorder = new MediaRecorder(stream);
        mediaRecorder.ondataavailable = (e) => {
          if (e.data.size > 0) recordedChunks.push(e.data);
        };
        mediaRecorder.onstop = () => {
          const blob = new Blob(recordedChunks, { type: 'video/webm' });
          const url = URL.createObjectURL(blob);
          chrome.downloads.download({ url: url, filename: '录制视频.webm' });
          recordedChunks = [];
        };
        mediaRecorder.start();
        chrome.tabs.sendMessage(currentTabId, { type: 'SHOW_SIDEBAR' });
      }
      break;
    case 'PAUSE_RECORD':
      if (mediaRecorder) {
        mediaRecorder.state === 'recording' ? mediaRecorder.pause() : mediaRecorder.resume();
      }
      break;
    case 'STOP_RECORD':
      if (mediaRecorder && mediaRecorder.state !== 'inactive') {
        mediaRecorder.stop();
        mediaRecorder.stream.getTracks().forEach(track => track.stop());
      }
      chrome.tabs.sendMessage(currentTabId, { type: 'STOP_RECORD' });
      break;
  }
});

关键逻辑说明

  1. 通信机制:通过chrome.runtime.sendMessage和chrome.tabs.sendMessage实现三者间消息传递。
  2. 侧边栏注入:content script直接操作页面DOM,插入固定定位的侧边栏,确保层级最高不被遮挡。
  3. 录屏核心:用desktopCapture API获取屏幕权限,通过MediaRecorder处理视频录制与文件生成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:33:13