admin管理员组文章数量:1394990
I'm trying to change the sinkId
at an Audio-Element in a chrome app.
Code:
var audio = new Audio();
audio.setSinkId("munications");
I'll get this error:
DOMException: No permission to use requested device
So to get the permission I tried to do that:
navigator.webkitGetUserMedia({
audio: true
}, (stream) => {
console.log("stream: ", stream);
}, (error) => {
console.log("error: ", error);
});
But now I get this:
error:
NavigatorUserMediaError {name: "InvalidStateError", message: "", constraintName: ""}
I don't know, whether
- 'audio' is not available (but actually it should)
- I need a secure connection (but how do I get this at a chrome app?)
I'm trying to change the sinkId
at an Audio-Element in a chrome app.
Code:
var audio = new Audio();
audio.setSinkId("munications");
I'll get this error:
DOMException: No permission to use requested device
So to get the permission I tried to do that:
navigator.webkitGetUserMedia({
audio: true
}, (stream) => {
console.log("stream: ", stream);
}, (error) => {
console.log("error: ", error);
});
But now I get this:
error:
NavigatorUserMediaError {name: "InvalidStateError", message: "", constraintName: ""}
I don't know, whether
- 'audio' is not available (but actually it should)
- I need a secure connection (but how do I get this at a chrome app?)
- I have the same problem and looked at the docs: developers.google./web/updates/2015/10/media-devices the example (which is also not working on Windows 10): webrtc.github.io/samples/src/content/devices/input-output And an open issue at github: github./WebAudio/web-audio-api/issues/445 It seems to be broken currently.. PS: There is also an Chrome extension which should be able to switch audio outputs here: chrome.google./webstore/detail/audiopick/… It might contains some interesting code? (haven't looked at it) – Wezelkrozum Commented Feb 19, 2018 at 0:42
- 1 Thanks for your reply. Unfortunately, the example and the chrome extension aren't working on my puter (Windows 8, chrome version 63.0.3239.132), too. Hope it will be fixed soon! – Gerrit Commented Feb 19, 2018 at 13:56
- 1 No "invalid state" error here on Chrome v78, but it's still seemingly broken to have to request an audio input stream to get permissions for audio output. I added a bounty to your question to hopefully get a better answer. – Brad Commented Dec 10, 2019 at 4:19
1 Answer
Reset to default 7 +200There is now a mediacapture-output WG and they did define an extension to the MediaDevices
interface which adds a selectAudioOutput()
method which takes care of the internal permission requests.
This method would return a deviceInfo object from where you can extract the deviceId
you would pass to HTMLMediaElement.setSinkId()
.
const deviceInfo = await navigator.mediaDevices.selectAudioOuput();
audio_elem.setSinkId(deviceInfo.deviceId);
Note also that there is active discussions about renaming this setSinkId
method to setAudioOutput
, so it might change again when browsers will start implementing all this.
Firefox 93 starts exposing this method, under the media.setsinkid.enabled
flag.
Alternatively there should be a Permissions.request()
method, which should accept a PermissionDescriptor object which itself should support a PermissionName of value "speaker-selection"
.
So that would give us
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 );
But as of today August of 2021, it seems that still no browser supports this.
Chrome (which is the only one currently supporting MediaElement.setSinkId()
) does expose the Permission.request()
method under chrome://flags/#enable-experimental-web-platform-features
, but they still don't support the PermissionName "speaker-selection"
yet.
So we still need the less than optimal workaround of requesting for the "microphone"
one instead.
(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 );
As a fiddle since Stack-Snippets iframes won't allow for the use of the microphone.
Ps: Note that if/when browsers were supporting the specs defined API, then it would even be possible to run this code on non-secure contexts.
本文标签: google chromeJavaScript get permission for AudiosetSinkIdStack Overflow
版权声明:本文标题:google chrome - JavaScript get permission for Audio.setSinkId - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744109507a2591224.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论