R-J*_*R-J 16 google-chrome google-chrome-extension web-mediarecorder
编辑:
随着年底和 Manifest V2 即将结束,我对此做了更多研究,并发现了以下解决方法:
这里使用 API 的示例desktopCapture:
https ://github.com/GoogleChrome/chrome-extensions-samples/issues/627
这种方法的问题在于,它要求用户通过某些 UI 选择捕获源,这可能会造成破坏。命令--auto-select-desktop-capture-source行开关显然可以用来绕过这个,但我还没有能够成功地使用它。
这里的示例扩展tabCapture通过创建自己的非活动选项卡来访问tabCaptureAPI 并记录当前
活动选项卡,从而解决了在 Service Worker 中无法工作的问题:
https://github.com/zhw2590582/chrome-audio-capture
到目前为止,这似乎是我在用户体验方面找到的最佳解决方案。Manifest V2 中提供的背景页面本质上被替换为虚拟选项卡。
第二个解决方案的迂回似乎也表明该tabCaptureAPI 本质上不适合在 Manifest V3 中使用,否则会有更直接的使用方式。我很失望的是,Manifest V3 正在强制执行,而实质上却留下了 Manifest V2 的功能,例如这一点。
原帖:
我正在尝试编写一个清单 v3 Chrome 扩展来捕获选项卡音频。但据我所知,清单 v3 中存在一些更改,这使得这有点困难:
chrome.tabCaptureAPI。尽管如此,我还是设法得到了一些几乎可以工作的东西,因为弹出脚本仍然可以访问chrome.tabCapture. 但是,有一个缺点 - 选项卡的音频被静音,并且似乎没有办法取消静音。这是我到目前为止所拥有的:
let tabId;
// Fetch tab immediately
chrome.runtime.sendMessage({command: 'query-active-tab'}, (response) => {
tabId = response.id;
});
Run Code Online (Sandbox Code Playgroud)
这是服务工作人员,它使用当前选项卡 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;
}
...
Run Code Online (Sandbox Code Playgroud)
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
})
});
});
Run Code Online (Sandbox Code Playgroud)
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
});
}
}
);
Run Code Online (Sandbox Code Playgroud)
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);
});
});
Run Code Online (Sandbox Code Playgroud)
这是实现上述内容的代码:https://github.com/killergerbah/-test-tab-capture-extension
这实际上确实会产生一个MediaStream,但缺点是选项卡的声音被静音。我尝试通过音频元素播放流,但这似乎没有任何作用。
有没有办法在清单 v3 扩展中获取选项卡音频流而不将选项卡中的音频静音?
我怀疑这种方法可能是完全错误的,因为它是如此迂回,但这是我在阅读文档和各种 StackOverflow 帖子后能想到的最好方法。我还了解到,tabCaptureAPI 将在某个时候迁移到清单 v3,所以也许这个问题根本没有意义——但是,如果有办法仍然可以正确使用它,我想知道。
小智 0
这可能不完全是您正在寻找的内容,但也许它可以提供一些见解。
我尝试通过音频元素播放流,但这似乎没有任何作用。
讽刺的是,这就是我设法解决这个问题的方法;通过在弹出窗口本身中创建一个对象。在弹出脚本中使用 tabCapture 时,它返回流,我将音频 srcObject 设置为该流。
HTML:
<audio id="audioObject" autoplay> No source detected </audio>
JS:
chrome.tabCapture.capture({audio: true, video: false}, function(stream) {
var audio = document.getElementById("audioObject");
audio.srcObject = stream
})
Run Code Online (Sandbox Code Playgroud)
根据Manifest V3 上的这篇文章,chrome.capture 将成为 tabCapture 等的新命名空间,但我还没有看到除此之外的任何内容。
| 归档时间: |
|
| 查看次数: |
7703 次 |
| 最近记录: |