检测浏览器中是否正在播放音频的Javascript代码

20

有没有全局的方法可以检测浏览器中音频何时正在播放或开始播放。

类似于以下思路:if(window.mediaPlaying()){...

而不需要将代码绑定到特定元素?

编辑:重要的是要能够检测任何音频,无论音频来自哪里。无论它来自iframe、视频、Web Audio API等。

4个回答

14

这个并不推荐使用,但它可以正常工作。

基本上我发现访问整个窗口音频的唯一方法是使用MediaDevices.getDisplayMedia()

从那里可以将一个MediaStream输入到AnalyserNode中,然后可用于检查音频音量是否大于零。

仅适用于 Chrome 和可能的 Edge (仅在 Linux 上的 Chrome 80 中测试过)

JSFiddle上有包括<video><audio>和 YouTube等内容!

重要的代码片段(无法在工作片段中发布,因为片段 iframe 上有功能策略):

var audioCtx = new AudioContext();
var analyser = audioCtx.createAnalyser();

var bufferLength = analyser.fftSize;
var dataArray = new Float32Array(bufferLength);

window.isAudioPlaying = () => {
  analyser.getFloatTimeDomainData(dataArray);
  for (var i = 0; i < bufferLength; i++) {
    if (dataArray[i] != 0) return true;

  }
  return false;
}

navigator.mediaDevices.getDisplayMedia({
     video: true,
     audio: true
   })
   .then(stream => {
      if (stream.getAudioTracks().length > 0) {
        var source = audioCtx.createMediaStreamSource(stream);
        source.connect(analyser);

        document.body.classList.add('ready');
      } else {
        console.log('Failed to get stream. Audio not shared or browser not supported');
      }

   }).catch(err => console.log("Unable to open capture: ", err));

好的解决方案,但不幸的是,这并不总是有效。我已经在Google Meet上尝试过它来检测是否有人在说话,但消息显示即使没有人说话,音频也在播放。 - Aurasphere
2
似乎从选项卡中传来了一点静音声,即使每个人都已经静音。我制作了一个更新的小提琴,显示了音频的图形。[jsfiddle](https://jsfiddle.net/Thornton_Fernbacher/u78pce9g/62/) - Trobol

3

我阅读了所有关于Web Audio APIMDN文档,但是我没有找到任何显示音频播放的window全局标志。但我找到了一个巧妙的方法,可以显示任何正在播放的音频,无论是iframe还是video,但是它与Web Audio API有关:

const allAudio = Array.from( document.querySelectorAll('audio') );
const allVideo = Array.from( document.querySelectorAll('video') );
const isPlaying = [...allAudio, ...allVideo].some(item => !item.paused);

现在,我们可以通过isPlaying标志检测浏览器中是否正在播放音频或视频。


1
几乎可以确定这取决于音频/视频元素是否是DOM的一部分。我非常确定您可以使用JS创建一个音频元素并轻松播放它,而无需将其添加到DOM中;因此,对于该场景,这种方法不起作用。 - Lovethenakedgun
@Lovethenakedgun,你是如何解决“trustedTypes”错误的?我猜测该元素没有被注入到DOM中?这是在云端还是在带有声卡+麦克风的物理机器上?你是使用Python还是JS来实现的? - Gary Vaughan Jr
1
@GaryVaughanJr 在 https://file-examples.com 上,我得到了一个链接到他们最小的 MP3 示例,并在他们网站上的另一个页面的控制台中运行了以下代码:var aud = new Audio("https://file-examples.com/<path>/file_example_MP3_700KB.mp3"); aud.play(); 然后 MP3 音轨开始播放。new Audio 创建了一个 <audio> 元素,但是运行 document.querySelectorAll('audio') 不会返回它,除非你也将其附加到 document 中的某个位置。但是,你可以在不这样做的情况下操作和播放它。如果我在之前的评论中使用了错误的术语,请原谅我。我还没有遇到过 "trustedTypes" 错误。 - Lovethenakedgun

2

1
“不将代码绑定到特定元素”是这个问题的一个至关重要的方面(至少对我来说是这样)。 - brillout
在这种情况下,应首先为元素设置“playbackState”(默认值为“none”),但它可以针对任何媒体源进行设置。 - NinaW
如果您无法控制源元素,则可以按照Ed的逻辑,在文档中查找媒体元素(音频、视频、iframe),并检查它们是否正在播放音频。 - NinaW
我需要花些时间研究这个问题。有一些选项可以访问iframe的文档及其内部DOM,例如contentWindow(https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/contentWindow)和`frames`(https://developer.mozilla.org/en-US/docs/Web/API/Window/frames)。我还在https://stackoverflow.com/questions/43745161/stop-all-audio-inside-iframes-from-parent找到了一个相关的问题,可能会有所帮助。 - NinaW

0
我在谷歌上寻找解决方案,但目前还没有找到任何东西。 也许你可以检查一些只有在播放音频时才具有X值的数据。如果你有一些按钮开始播放音频文件,也许你可以通过在rep.按钮上添加一些事件监听器来确保音频正在播放...
也许像给"audio"标签添加一个事件监听器这样的事情?如果我没记错的话,音频标签有一个"paused"属性... 现在我只记得音频有"paused"属性了...
此外,您可能想要查看这个主题HTML5 check if audio is playing? 我刚刚五秒钟前发现它哈哈

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接