Javascript onDeviceChange()仅在macOS Chrome中正常工作

Javascript onDeviceChange()仅在macOS Chrome中正常工作,javascript,Javascript,我想检测音频输入或输出设备何时发生变化,图中所示的onDeviceChange()就可以做到这一点。这是小提琴。当我将耳机(带有麦克风)插入耳机插孔时-无论是否具有getUserMedia权限,这都不是必需的-这在macOS Chrome中通过显示device change(设备更改)每次。但是,它在其他任何地方都不起作用 macOS Chrome:有效。无论权限如何(提示,授予,拒绝),也一文不值 macOS Firefox(具有权限):只触发一次,尽管多次插拔 Windows10Chrom

我想检测音频输入或输出设备何时发生变化,图中所示的
onDeviceChange()
就可以做到这一点。这是小提琴。当我将耳机(带有麦克风)插入耳机插孔时-无论是否具有
getUserMedia
权限,这都不是必需的-这在macOS Chrome中通过显示
device change(设备更改)每次。但是,它在其他任何地方都不起作用

  • macOS Chrome:有效。无论权限如何(
    提示
    授予
    拒绝
    ),也一文不值
  • macOS Firefox(具有权限):只触发一次,尽管多次插拔
  • Windows10Chrome:这看起来特别奇怪!根本不起作用,即使得到允许
  • Windows 10 Firefox:无法测试,但假设它将启动一次
我已经在谷歌上搜索了一段时间,据我所知,这应该适用于所有这些情况。支持:

  • Firefox错误:
  • Firefox错误:
前两个版本中有一个脚注说“MediaDevices.ondevicechange仅在macOS上受支持”,但这是指2017年推出的Firefox 51。无论如何,这并不能解释为什么它不能在当前的macOS Firefox或Windows Chrome上运行

再深入一点,我查看了我从
enumerateDevices()
获得的
audioinput
设备。未插入任何电源:

Default - Internal Microphone (Built-in)
Internal Microphone (Built-in)
ZoomAudioDevice (Virtual)
使用麦克风插入耳机后:

Default - External Microphone (Built-in)
External Microphone (Built-in)
ZoomAudioDevice (Virtual)
这里有一个有趣的部分:
deviceId
没有改变,尽管它显然是一个不同的设备。我认为这可能与此有关,所以我尝试连接和断开蓝牙扬声器(它确实显示为不同的设备),但我得到了同样的结果:每次在macOS Chrome上工作,但只有一次在macOS Firefox上工作

还有其他人经历过吗?我只能偶尔访问一台物理Windows计算机。我是否遗漏了什么,或者这仅在macOS Chrome中得到正确支持?为什么会这样,为什么它在Windows中不起同样的作用?也许这与耳机插孔有关

更新1 根据Kaido的说法,这里是音频MIDI设置前后的屏幕截图

无输入:

插入耳机后:

更新2 这似乎与我的耳机有关。我试着用其他耳机,在macOS Chrome/Firefox和Windows Chrome上,效果如预期。无法在Windows Firefox上进行测试,但这可能也有效。真是浪费时间

有或没有
getUserMedia
权限,这不是必需的

这可能就是你困惑的地方

如果此设备不是同类设备中唯一的设备,则需要此权限才能侦听devicechange事件。 从

MediaDeviceKind
的新媒体输入和/或输出设备可用时,该
MediaDeviceKind
的零设备以前可用,或者
MediaDeviceKind
的单独输入和/或输出设备变为不可用,对于
true
false
,用户代理必须在浏览上下文中运行以下步骤,但不能在其他上下文中运行:

换句话说,这意味着如果添加或删除的设备是或曾经是同类设备中唯一的设备,则只有在上下文是安全的(https://)并且权限是未授予的情况下,才应立即触发此事件

我猜您插入和拔出的设备并不是同类设备中唯一的一个,在这种情况下,您将进入下一段:

此外,当新的媒体输入和/或输出设备可用时,或任何可用的输入和/或输出设备不可用时,或摄像头或麦克风的系统默认设置更改时,用户代理必须在浏览上下文中运行,该上下文为
true
且为
true
,但不得在其他上下文中运行

这意味着,如果授予了权限(并且上下文是安全的),事件无论如何都会触发

请注意,最后一段规定,即使之前已阻止的事件在最终授予许可时也会触发


特别是关于Firefox,请注意,默认情况下,他们不会保留该权限,这意味着当您停止gUM流时,如果用户没有在提示中勾选“记住此决定”,则权限将再次无效,事件将不会触发,即使他们勾选了,您必须发出初始请求才能激活它

Ps:我手边只有一台mac笔记本电脑,无法删除内部设备,但我可以确认,当我在Firefox 80中授予适当的权限时,它在添加/删除新设备方面可以正常工作

有或没有
getUserMedia
权限,这不是必需的

这可能就是你困惑的地方

如果此设备不是同类设备中唯一的设备,则需要此权限才能侦听devicechange事件。 从

MediaDeviceKind
的新媒体输入和/或输出设备可用时,该
MediaDeviceKind
的零设备以前可用,或者
MediaDeviceKind
的单独输入和/或输出设备变为不可用,对于
true
false
,用户代理必须在浏览上下文中运行以下步骤,但不能在其他上下文中运行:

换句话说,这意味着如果添加或删除的设备是或曾经是同类设备中唯一的设备,则只有在上下文安全(https://)且权限未授予时,才应立即触发此事件