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

如何在Chrome扩展JS中从chrome.scripting.executeScript获取Blob对象?

音频录制与结果返回优化方案

我希望通过chrome.scripting.executeScript返回页面中录制的音频,将其存储到主程序变量中。当前通过startRecording函数注入脚本,需要录制10秒后获取音频,但现有代码使用Promise时遇到问题,现有代码如下:

主程序原代码

function startRecording(tab) {
    console.log("startRecording : " + tab.id)
    chrome.scripting.executeScript({
        target: { tabId: tab.id },
        function: captureAudio,
    },(res) => { 
        console.log(res)
        recordedAudio = res.result
    },
    ).then(()=>{console.log("Record launched !")});
}

注入页面的原函数

async function captureAudio() {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      const mediaRecorder = new MediaRecorder(stream);
      const audioChunks = [];
  
      mediaRecorder.ondataavailable = (event) => {
        audioChunks.push(event.data);
      };
  
      mediaRecorder.start();
  
      setTimeout(() => {
        mediaRecorder.stop();
      }, 10000);
  
      mediaRecorder.onstop = () => {
        const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
        return audioBlob
      };
    } catch (error) {
      console.error("Erreur lors de la capture audio :", error);
    }
  }

问题分析

原代码核心问题是:captureAudio虽标记为async,但未返回能解析为音频Blob的Promise。onstop回调中的return audioBlob无法传递到外层async函数,导致chrome.scripting.executeScript无法获取到预期的音频结果。


优化后的代码

注入页面的captureAudio函数

function captureAudio() {
  return new Promise(async (resolve, reject) => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      const mediaRecorder = new MediaRecorder(stream);
      const audioChunks = [];

      mediaRecorder.ondataavailable = (event) => {
        audioChunks.push(event.data);
      };

      // 录制停止时返回音频Blob
      mediaRecorder.onstop = () => {
        stream.getTracks().forEach(track => track.stop()); // 释放媒体资源
        const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
        resolve(audioBlob);
      };

      // 捕获录制错误
      mediaRecorder.onerror = (error) => {
        stream.getTracks().forEach(track => track.stop());
        reject(error);
      };

      mediaRecorder.start();

      // 10秒后自动停止录制
      setTimeout(() => {
        mediaRecorder.stop();
      }, 10000);
    } catch (error) {
      reject(error);
    }
  });
}

主程序的startRecording函数

async function startRecording(tab) {
  console.log("startRecording : " + tab.id);
  try {
    const [result] = await chrome.scripting.executeScript({
      target: { tabId: tab.id },
      function: captureAudio,
    });
    recordedAudio = result.result; // 存储获取到的音频Blob
    console.log("录制完成,已获取音频Blob");
  } catch (error) {
    console.error("录制或获取音频失败:", error);
  }
}

优化说明

  • 让captureAudio返回Promise,通过resolve传递最终音频Blob,reject传递错误信息,确保结果能被主程序接收
  • 在录制结束或出错时主动释放媒体流资源,避免内存泄漏
  • 主程序使用async/await简化异步逻辑,直接获取executeScript返回的结果数组,错误处理更统一

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:35:25