为了从清单 v2 中的选项卡捕获输出音频流,可以在后台脚本中使用
chrome.tabCapture.capture
API 来获取流。但是,在清单 v3 中,tabCapture 已移至前台,并且在后台脚本中不可用。它在内容脚本中都不可用。
尝试了一些方法后,我终于可以让
tabCapture
在弹出脚本中工作。但是,在我的用例中,弹出窗口无法长时间保持打开状态以捕获流。相反,我偶然发现了 getMediaStreamId
的 tabCapture
方法,它给了我一个streamId。所以,我想出了这个:
chrome.tabs.query({
active: true,
currentWindow: true
}, (tabs) => {
var tab = tabs[0];
chrome.tabCapture.getMediaStreamId({consumerTabId: tab.id}, (streamId) => {
chrome.tabs.sendMessage(tab.id, { action: 'streamId', streamId: streamId });
});
});
在
popup.js
文件中存在的上述脚本中,获取streamId后,我将其发送到内容脚本。我一直专注于如何从该streamId 创建流,以便可以捕获/记录该流。 文档提到使用getUserMedia()
,但我在那里并不幸运。这是我可以通过其他问题的一些帮助想出的(但它不起作用,我得到这个错误DOMException: Error starting tab capture
):
navigator.mediaDevices.getUserMedia({
audio: {
mandatory: {
chromeMediaSource: 'tab',
chromeMediaSourceId: streamId
}
}
})
如何使 tabCapture 在清单 v3 中工作,是我试图找出的。
这是一个在扩展弹出窗口中捕获音频的解决方案,而不是服务工作者。
manifest.json
{
"name": "Audio Share",
"version": "0.1",
"manifest_version": 3,
"permissions": [
"tabs",
"activeTab",
"tabCapture"
],
"host_permissions": [
"https://*/"
],
"action": {
"default_popup": "home.html",
"default_action": "home.js"
}
}
home.js
function saveToFile(blob, name) {
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = name;
a.click();
URL.revokeObjectURL(url);
a.remove();
}
function captureTabAudio() {
chrome.tabCapture.capture({audio: true, video: false}, (stream) => {
// these lines enable the audio to continue playing while capturing
context = new AudioContext();
var newStream = context.createMediaStreamSource(stream);
newStream.connect(context.destination);
const recorder = new MediaRecorder(stream);
const chunks = [];
recorder.ondataavailable = (e) => {
chunks.push(e.data);
};
recorder.onstop = (e) => saveToFile(new Blob(chunks), "test.wav");
recorder.start();
setTimeout(() => recorder.stop(), 5000);
})
}
document.addEventListener('DOMContentLoaded', function () {
document.getElementById("share-audio-button").addEventListener("click", function ()
captureTabAudio();
})
});
home.html
<html>
<head>
<script src="home.js"></script>
</head>
<body>
<h1>Audio Share</h1>
<button id="share-audio-button">Share Audio</button>
</body>
</html>