首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在清单chrome.tabCapture扩展中正确使用v3

在清单chrome.tabCapture扩展中正确使用v3
EN

Stack Overflow用户
提问于 2021-02-16 02:16:31
回答 3查看 3.7K关注 0票数 9

编辑:

随着年底和Manifest V2的临近,我对此做了更多的研究,并找到了以下解决办法:

  • 这里使用desktopCapture API:https://github.com/GoogleChrome/chrome-extensions-samples/issues/627的示例 这种方法的问题在于,它要求用户通过一些UI选择捕获源,这可能会造成干扰。显然,可以使用--auto-select-desktop-capture-source命令行开关来绕过它,但我一直未能成功地使用它。
  • 这里的示例扩展可以通过创建自己的非活动选项卡来访问tabCapture API并记录当前活动的选项卡,从而绕过不工作于服务工作者的tabCapturehttps://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。然而,有一个缺点-选项卡的音频是静音的,似乎没有一种方法来解除它。到目前为止,这就是我所拥有的:

  1. 从弹出脚本中查询服务工作者当前选项卡。
代码语言:javascript
运行
复制
let tabId;

// Fetch tab immediately
chrome.runtime.sendMessage({command: 'query-active-tab'}, (response) => {
    tabId = response.id;
});

这是服务工作人员,它使用当前选项卡ID进行响应。

代码语言:javascript
运行
复制
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;
        }
        ...
  1. 同样,在弹出脚本中,通过键盘快捷命令,使用chrome.tabCapture.getMediaStreamId获取要由当前选项卡使用的媒体流ID,并将该流ID发送回服务工作人员。
代码语言:javascript
运行
复制
// 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
        })
    });
});
  1. 服务工作者将该流ID转发给内容脚本。
代码语言:javascript
运行
复制
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
            });
        }
    }
);
  1. 内容脚本使用navigator.mediaDevices.getUserMedia获取流。
代码语言:javascript
运行
复制
// 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,所以也许这个问题甚至没有意义--然而,如果有一种方法仍然正确地使用它,我想知道。

EN

回答 3

Stack Overflow用户

发布于 2022-01-20 08:59:39

我发现你的文章在推进我的音频选项卡记录器的实现过程中非常有用。

关于您遇到的特定静音问题,我在这里查看:使用chrome.tabCapture.capture()和MediaRecorder()时,选项卡的原始音频被静音解决了它

代码语言:javascript
运行
复制
// 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);
    });
});
票数 1
EN

Stack Overflow用户

发布于 2021-06-14 06:38:57

这可能不是你想要的,但也许它可以提供一些洞察力。

我试过通过音频元素播放流,但这似乎什么也做不了。

具有讽刺意味的是,我就是通过在弹出本身中创建一个对象来解决这个问题的。在弹出脚本中使用tabCapture时,它返回流,我将音频srcObject设置为该流。

HTML:<audio id="audioObject" autoplay> No source detected </audio>

联署材料:

代码语言:javascript
运行
复制
chrome.tabCapture.capture({audio: true, video: false}, function(stream) {
    var audio = document.getElementById("audioObject");
    audio.srcObject = stream
})

根据这个职位 on Manifest V3的说法,chrome.capture将成为tabCapture等的新名称空间,但除此之外,我还没有看到任何其他内容。

票数 0
EN

Stack Overflow用户

发布于 2022-03-08 14:28:34

我也有这个问题,我通过使用来解决它。只需创建一个新的上下文并使用捕获的MediaStream将其连接到媒体流源,这就是一个例子:

代码语言:javascript
运行
复制
avoidSilenceInTab: (desktopStream: MediaStream) => {
 var contextTab = new AudioContext();
 contextTab
   .createMediaStreamSource(desktopStream)
   .connect(contextTab.destination);

}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66217882

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档