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

开发React Chrome扩展:如何实现无需额外标签页的会议音频录制?

核心实现思路:基于Chrome桌面捕获API+后台脚本/内嵌UI实现无新标签音频录制

一、关键Chrome API组合

  • chrome.tabCapture:专门针对标签页的媒体捕获接口,可直接获取指定活跃标签页的音频流,无需用户手动选择(若提前拿到标签ID),是实现特定会议页面录制的核心。
  • chrome.desktopCapture.chooseDesktopMedia:备选方案,允许用户弹窗选择要捕获的标签页/窗口音频,适合需要用户自主选择目标场景。
  • chrome.runtime.sendMessage/onMessage:用于React控制UI(弹窗/侧边栏)与后台脚本的通信,传递录制启停指令。
  • chrome.storage.local:临时存储录制状态、音频数据片段,避免页面刷新丢失进度。
  • chrome.sidePanel:实现内嵌侧边栏UI的核心API,让录制控制全程在当前浏览器窗口内完成,完全不干扰会议页面。

二、无新标签UI的两种实现方案(对应TacTiq的无缝体验)

  1. 浏览器动作Popup:点击扩展图标弹出React开发的小型控制UI,弹窗不会打开新标签,关闭后后台脚本仍可继续录制,适合轻量控制场景。
  2. 侧边栏(Side Panel):利用Chrome侧边栏API将录制UI嵌入浏览器右侧,全程与会议页面共存,操作更直观,适合需要持续显示录制状态的场景。

三、具体实现步骤(React + Chrome扩展)

1. 配置manifest.json

{
  "manifest_version": 3,
  "name": "会议音频录制工具",
  "version": "1.0",
  "permissions": ["tabCapture", "storage", "activeTab"],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html"
  },
  "side_panel": {
    "default_path": "sidepanel.html"
  }
}

2. 后台脚本(Service Worker)处理录制逻辑

// background.js
let mediaRecorder = null;
let audioChunks = [];

chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
  switch (message.action) {
    case 'start':
      try {
        const stream = await chrome.tabCapture.capture({ audio: true, video: false });
        mediaRecorder = new MediaRecorder(stream);
        audioChunks = [];

        mediaRecorder.ondataavailable = (e) => audioChunks.push(e.data);
        mediaRecorder.onstop = async () => {
          const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
          const audioBase64 = await blobToBase64(audioBlob);
          await chrome.storage.local.set({ recordedAudio: audioBase64 });
        };

        mediaRecorder.start();
        sendResponse({ status: 'success', msg: '录制已启动' });
      } catch (err) {
        sendResponse({ status: 'error', msg: err.message });
      }
      break;
    case 'stop':
      if (mediaRecorder && mediaRecorder.state === 'recording') {
        mediaRecorder.stop();
        // 停止后释放流
        mediaRecorder.stream.getTracks().forEach(track => track.stop());
        sendResponse({ status: 'success', msg: '录制已停止' });
      } else {
        sendResponse({ status: 'error', msg: '无正在进行的录制' });
      }
      break;
    default:
      sendResponse({ status: 'error', msg: '无效指令' });
  }
  return true; // 保持消息通道开放,支持异步响应
});

function blobToBase64(blob) {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.readAsDataURL(blob);
  });
}

3. React控制UI示例(Popup)

// Popup.jsx
import { useState } from 'react';

function RecordingPopup() {
  const [isRecording, setIsRecording] = useState(false);
  const [statusMsg, setStatusMsg] = useState('');

  const toggleRecording = async () => {
    const action = isRecording ? 'stop' : 'start';
    const response = await chrome.runtime.sendMessage({ action });
    
    setStatusMsg(response.msg);
    if (response.status === 'success') {
      setIsRecording(!isRecording);
    }
  };

  return (
    <div style={{ padding: '16px', width: '220px' }}>
      <button
        onClick={toggleRecording}
        style={{
          width: '100%',
          padding: '10px',
          border: 'none',
          borderRadius: '4px',
          backgroundColor: isRecording ? '#dc3545' : '#28a745',
          color: '#fff',
          fontSize: '14px',
          cursor: 'pointer'
        }}
      >
        {isRecording ? '停止录制' : '开始录制'}
      </button>
      {statusMsg && <p style={{ marginTop: '10px', textAlign: 'center', fontSize: '12px' }}>{statusMsg}</p>}
    </div>
  );
}

export default RecordingPopup;

四、会议转录集成思路

录制完成后,可通过以下方式实现转录:

  • 前端直接调用Web Speech API的SpeechRecognition接口(兼容性有限,适合轻量场景);
  • 将存储的Base64音频数据发送到后端,对接OpenAI Whisper、Google Speech-to-Text等专业语音转文字服务。

五、TacTiq无缝体验的核心逻辑推测

  1. 用后台Service Worker持久化处理录制任务,UI仅作为控制入口,不占用独立标签页;
  2. 提前通过权限申请流程获取用户授权,避免每次录制重复弹窗;
  3. 音频数据直接在后台内存/IndexedDB处理,无需渲染到页面,降低资源消耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:44:51