如何在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
相关产品推荐
相关产品推荐

