如何在 chrome 扩展清单 v3 的选项卡中播放音频流

问题描述 投票:0回答:2

为了从清单 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 中工作,是我试图找出的。

javascript google-chrome-extension getusermedia chrome-extension-manifest-v3 mediadevices
2个回答
0
投票

这是一个在扩展弹出窗口中捕获音频的解决方案,而不是服务工作者。

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>

© www.soinside.com 2019 - 2024. All rights reserved.