JavaScript 获取 Audio.setSinkId 的权限

2023-11-21

我正在尝试改变sinkId在 Chrome 应用程序中的音频元素处。

Code:

var audio = new Audio();
audio.setSinkId("communications");

我会收到这个错误:

DOMException: No permission to use requested device

因此,为了获得许可,我尝试这样做:

navigator.webkitGetUserMedia({
    audio: true
}, (stream) => {
    console.log("stream: ", stream);
}, (error) => {
    console.log("error: ", error);
});

但现在我明白了:

error:
NavigatorUserMediaError {name: "InvalidStateError", message: "", constraintName: ""}

我不知道,是否

  • “音频”不可用(但实际上应该)
  • 我需要安全连接(但如何在 Chrome 应用程序中获得此连接?)

现在有一个媒体捕捉输出工作组他们确实定义了一个扩展MediaDevices界面添加了一个selectAudioOutput()处理内部权限请求的方法。
这个方法会返回一个设备信息您可以从中提取对象deviceId你会传递给HTMLMediaElement.setSinkId().

const deviceInfo = await navigator.mediaDevices.selectAudioOuput();
audio_elem.setSinkId(deviceInfo.deviceId);

另请注意,关于重命名此内容的讨论非常活跃setSinkId方法setAudioOutput,所以当浏览器开始实现这一切时,它可能会再次改变。

Firefox 93开始公开此方法,在media.setsinkid.enabled flag.



或者应该有一个Permissions.request()方法,它应该接受权限描述符本身应该支持的对象权限名称有价值的"speaker-selection".

这样我们就可以得到

 await navigator.permissions.request( { name: "speaker-selection" } );
 const all_devices = await navigator.mediaDevices.enumerateDevices();
 const audio_outs = all_devices.filter( ({ kind }) => kind === "audiooutput" );
 // ...
 audioElem.setSinkId( audio_outs[ n ].deviceId );


但截至2021年8月的今天,似乎仍然没有浏览器支持这一点。

Chrome(目前唯一支持MediaElement.setSinkId())确实暴露了Permission.request()下的方法chrome://flags/#enable-experimental-web-platform-features,但他们仍然不支持权限名称 "speaker-selection" yet.

所以我们仍然需要请求的不太理想的解决方法"microphone"一个代替。

(async () => {
  const query = await navigator.permissions.query( { name: "microphone" } );
  switch( query.state ) {
    case "denied": throw new Error('denied');
    case "prompt":
      await queryUserMedia();
      await getListOfDevices();
      break;
    case "granted": await getListOfDevices();
  }
  function queryUserMedia() {
    return navigator.mediaDevices.getUserMedia( { audio: true } );
  }
  async function getListOfDevices() {
    const all_devs = await navigator.mediaDevices.enumerateDevices();
    const audioouts = all_devs.filter( ({ kind }) => kind === "audiooutput" );
    const options = audioouts.map( ( dev, index ) => {
      const name = dev.label || ('audio out ' + index );
      return new Option( name , dev.deviceId );
    } );
    sel.append.apply( sel, options );
    sel.onchange = e => aud.setSinkId( sel.value );
  }

})().catch( console.error );

作为小提琴,因为 Stack-Snippets iframe 不允许使用麦克风。


PS:请注意,如果/当浏览器支持规范定义的 API,那么它甚至会有可能 to 在非安全上下文中运行此代码.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript 获取 Audio.setSinkId 的权限 的相关文章

随机推荐

  • 两个日期之间的分钟数

    说我有一个约会是 future time ending 2012 09 21 12 12 22 如何计算当前时间与指定时间之间的分钟数 future time ending Thanks 一种方法 minutes strtotime 201
  • ASP.NET MVC2 + Ninject + NLog(+ 共享托管?)= NullReferenceException

    我有一个基于的 MVC2 应用程序Tekpub 入门网站 因此它使用 Ninject 进行依赖注入 使用 NLog 进行日志记录 并在不同的地方使用一堆其他库 据我所知 正是这些造成了我的问题 使用 ASP NET 开发服务器 Cassin
  • 如何编译lapack以便在安装octave时可以正确使用?

    我正在尝试在运行 redhat IBM LSF 的集群中从源代码安装最新的 Octave 3 8 1 除了我自己的主目录之外 我没有对其他任何地方的写访问权限 这就是为什么我必须从源代码安装八度 集群提供的blas和lapack不起作用所以
  • 如何从 Expression> 动态创建 Expression> 谓词?

    我尝试附加 where 谓词 我的目标是创建与以下相同的表达式 Services Where s gt s Name Modules s Namespace Namespace 我有以下代码 Expression
  • React Native中setTimeout的准确性

    我正在 React Native 中构建一个节拍器 播放点击后 我设置了setTimeout以便下次点击 然而 时机太糟糕了 我做了以下快速测试 let time new Date getTime 50 setTimeout gt cons
  • 连接列表的元素对[重复]

    这个问题在这里已经有答案了 我知道可以连接一个列表来形成一个长字符串 如下所示 x a b c d print join x 显然这会输出 abcd 但是 我想做的只是将列表中的第一个和第二个字符串连接起来 然后连接第三个和第四个字符串 依
  • 将 Visual Studio 项目中的所有文件保存为 UTF-8

    我想知道是否可以将 Visual Studio 2008 项目中的所有文件保存为特定的字符编码 我得到了一个混合编码的解决方案 我想让它们全部相同 带有签名的 UTF 8 我知道如何保存单个文件 但是项目中的所有文件怎么样 既然您已经在 V
  • 用于多个项目的单个 node_modules 文件夹

    我有一个这样的网站列表 project1 site project2 site project4 site projectN site Each site文件夹里面有node modules文件夹 gruntfile js文件和一个pack
  • 如何在 C++03 中将 boost packaged_task 发布到 io_service?

    这是上一个问题的后续问题 here 但我正在开发一个多线程应用程序 我想将 Boost packaged task 发布到线程 io service 我被困在使用 C 03 编译器 所以 std move 已退出 并且 packaged t
  • WPF GridViewColumn Width="auto" 仅适用于当前滚动范围内的项目

    我有一个包含许多项目的 ListView 并尝试将列宽度设置为自动 以便它们自动扩展到列中最长字符串的宽度 起初 它似乎有效 但当我向下滚动列表时 我注意到一些较长的字符串被剪短了 因为该列没有足够的自动扩展 然后我想到 将宽度设置为自动似
  • 匹配正数的正则表达式

    我需要编写一个正则表达式以仅允许正数 整数或小数 我发现了这个 0 0 0 0 00 d d d 0 9 但它只接受最多 2 位小数 我必须进行哪些更改才能使其接受任意位数的小数 另外我在哪里可以找到学习正则表达式的好教程 预先感谢 这将是
  • 将 MATLAB 字符数组转换为字符串

    从 MATLAB 字符数组开始 A A 1 1 A A 1 2 P A 1 3 R A 2 1 M A 2 2 A A 2 3 Y 如何将其转换为字符串单元格 B 这样 B 1 APR B 2 MAY 编辑 A 是一个单元格 使用函数 ce
  • 删除JS数组中最小的数字

    我有一个数字数组 2 1 3 4 5 1 想要删除列表中的最小数字 但不知怎的 我的 IF 语句被跳过了 我检查过 numbers i 1 和 numbers i 本身确实有效 但 numbers i 1 function removeSm
  • ComponentDidCatch 不起作用

    Why componentDidCatch在我的反应本机应用程序中不起作用 componentDidCatch不处理错误 React native v 50 3 React 16 0 0 import React Component fro
  • 递归获取 Active Directory 组的成员,即包括子组

    在 Active Directory 中给定一个这样的组 MainGroup GroupA User1 User2 GroupB User3 User4 我可以使用如下代码轻松确定 User3 是否是 MainGroup 或其任何子组的成员
  • 如何使用 Apache 配置设置 SameSite cookie 属性?

    我无法在 应用程序 选项卡中使用内置开发人员工具看到 SameSite Strict 我在 Apache 配置中添加了以下标头代码 Header always edit Set Cookie 1 SameSite Strict Header
  • PHP GMAIL 使用 DOMDocument 和 cURL 联系 XML 解析

    我当前想要获取的只是 gd email 的属性 即 address 目前仅此而已 我可以到达 xml 部分 哎呀 我什至可以得到任何给定的想法 只要它在标签之内 但要获取任何给定的属性 就像我的情况一样 我完全困惑了 我曾经知道如何做到这一
  • Persistence.createEntityManagerFactory() 需要很长时间才能返回

    我正在使用 Hibernate 4 2 JPA 2 0 和 Postgres 9 2 代码卡在Persistence createEntityManagerFactory peristence unit name 经过进一步调查 我发现 H
  • String.Format进行四舍五入,无法定位非法格式转换源错误?

    我正在编写一个程序 让用户输入 6 个温度读数 然后 返回最高原始值 celcius版本 返回原始值 转换为摄氏度版本 设置数组值的代码如下 System out print Enter Temperature t Get the coun
  • JavaScript 获取 Audio.setSinkId 的权限

    我正在尝试改变sinkId在 Chrome 应用程序中的音频元素处 Code var audio new Audio audio setSinkId communications 我会收到这个错误 DOMException No permi