【发布时间】:2021-02-16 02:16:31
【问题描述】:
我正在尝试编写一个用于捕获标签音频的清单 v3 Chrome 扩展程序。但是据我所知,对于 manifest v3,有一些变化使这有点困难:
- 后台脚本被服务工作者替换。
- Service Worker 无权访问
chrome.tabCaptureAPI。
尽管如此,我还是设法得到了一些几乎可以作为弹出脚本仍然可以访问chrome.tabCapture 的东西。但是,有一个缺点 - 选项卡的音频已静音,似乎没有办法取消静音。这是我目前所拥有的:
- 从弹出脚本中查询 service worker 当前选项卡。
let tabId;
// Fetch tab immediately
chrome.runtime.sendMessage({command: 'query-active-tab'}, (response) => {
tabId = response.id;
});
这是服务工作者,它使用当前选项卡 ID 进行响应。
chrome.runtime.onMessage.addListener(
(request, sender, sendResponse) => {
// Popup asks for current tab
if (request.command === 'query-active-tab') {
chrome.tabs.query({active: true}, (tabs) => {
if (tabs.length > 0) {
sendResponse({id: tabs[0].id});
}
});
return true;
}
...
- 再次在弹出脚本中,通过键盘快捷键命令,使用
chrome.tabCapture.getMediaStreamId获取当前选项卡使用的媒体流 ID,并将该流 ID 发送回服务工作者。
// On command, get the stream ID and forward it back to the service worker
chrome.commands.onCommand.addListener((command) => {
chrome.tabCapture.getMediaStreamId({consumerTabId: tabId}, (streamId) => {
chrome.runtime.sendMessage({
command: 'tab-media-stream',
tabId: tabId,
streamId: streamId
})
});
});
- Service Worker 将该流 ID 转发到内容脚本。
chrome.runtime.onMessage.addListener(
(request, sender, sendResponse) => {
...
// Popup sent back media stream ID, forward it to the content script
if (request.command === 'tab-media-stream') {
chrome.tabs.sendMessage(request.tabId, {
command: 'tab-media-stream',
streamId: request.streamId
});
}
}
);
- 内容脚本使用
navigator.mediaDevices.getUserMedia获取流。
// Service worker sent us the stream ID, use it to get the stream
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
navigator.mediaDevices.getUserMedia({
video: false,
audio: true,
audio: {
mandatory: {
chromeMediaSource: 'tab',
chromeMediaSourceId: request.streamId
}
}
})
.then((stream) => {
// Once we're here, the audio in the tab is muted
// However, recording the audio works!
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);
});
});
以下是实现上述内容的代码:https://github.com/killergerbah/-test-tab-capture-extension
这确实会产生MediaStream,但缺点是标签的声音被静音了。我尝试通过音频元素播放流,但这似乎无济于事。
有没有一种方法可以在清单 v3 扩展中获取标签音频流而不使标签中的音频静音?
我怀疑这种方法可能完全错误,因为它是如此迂回,但这是我在阅读文档和各种 StackOverflow 帖子后能想到的最好方法。
我还读到 tabCapture API 将在某个时候为 manifest v3 移动,所以也许这个问题甚至没有意义问 - 但是如果有办法仍然正确使用它我想知道。
【问题讨论】:
-
这里有任何进度更新吗?我也在努力在 v3 扩展中使用 chrome.tabCapture @R-J
-
@lsimmons 我在 manifest v3 中使用 tapCapture 没有任何进展——我最终降级到 manifest v2。不过,我仍然需要探索下面的答案。
-
在四处寻找之后,我发现了这个仍然存在的错误:bugs.chromium.org/p/chromium/issues/detail?id=1214847
标签: google-chrome google-chrome-extension web-mediarecorder