编辑:
随着年底和Manifest V2的临近,我对此做了更多的研究,并找到了以下解决办法:
desktopCapture
API:https://github.com/GoogleChrome/chrome-extensions-samples/issues/627的示例
这种方法的问题在于,它要求用户通过一些UI选择捕获源,这可能会造成干扰。显然,可以使用--auto-select-desktop-capture-source
命令行开关来绕过它,但我一直未能成功地使用它。tabCapture
API并记录当前活动的选项卡,从而绕过不工作于服务工作者的tabCapture
:
https://github.com/zhw2590582/chrome-audio-capture
到目前为止,这似乎是我在UX方面找到的最好的解决方案。Manifest V2中提供的背景页面实际上被一个幻影选项卡所取代。第二种解决方案的广泛性似乎也表明,tabCapture
API本质上并不适合在Manifest V3中使用,否则就会有更直接的方法来使用它。我感到失望的是,Manifest V3正在被强制执行,而实际上却留下了Manifest V2这样的特性。
原文:
我试图编写一个清单v3 Chrome扩展,捕捉选项卡音频。然而,据我所知,对于清单v3,有一些更改使得这有点困难:
chrome.tabCapture
API。尽管如此,我还是设法获得了一些几乎可以工作的东西,因为弹出脚本仍然可以访问chrome.tabCapture
。然而,有一个缺点-选项卡的音频是静音的,似乎没有一种方法来解除它。到目前为止,这就是我所拥有的:
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
})
});
});
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将被移动到清单v3,所以也许这个问题甚至没有意义--然而,如果有一种方法仍然正确地使用它,我想知道。
发布于 2022-01-20 08:59:39
我发现你的文章在推进我的音频选项卡记录器的实现过程中非常有用。
关于您遇到的特定静音问题,我在这里查看:使用chrome.tabCapture.capture()和MediaRecorder()时,选项卡的原始音频被静音解决了它
// 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) => {
// To resolve original audio muting
context = new AudioContext();
var audio = context.createMediaStreamSource(stream);
audio.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);
});
});
发布于 2021-06-14 06:38:57
这可能不是你想要的,但也许它可以提供一些洞察力。
我试过通过音频元素播放流,但这似乎什么也做不了。
具有讽刺意味的是,我就是通过在弹出本身中创建一个对象来解决这个问题的。在弹出脚本中使用tabCapture时,它返回流,我将音频srcObject设置为该流。
HTML:<audio id="audioObject" autoplay> No source detected </audio>
联署材料:
chrome.tabCapture.capture({audio: true, video: false}, function(stream) {
var audio = document.getElementById("audioObject");
audio.srcObject = stream
})
根据这个职位 on Manifest V3的说法,chrome.capture将成为tabCapture等的新名称空间,但除此之外,我还没有看到任何其他内容。
发布于 2022-03-08 14:28:34
我也有这个问题,我通过使用来解决它。只需创建一个新的上下文并使用捕获的MediaStream将其连接到媒体流源,这就是一个例子:
avoidSilenceInTab: (desktopStream: MediaStream) => {
var contextTab = new AudioContext();
contextTab
.createMediaStreamSource(desktopStream)
.connect(contextTab.destination);
}
https://stackoverflow.com/questions/66217882
复制相似问题