Reputation: 402
I use the following code from (https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia):
navigator.mediaDevices = navigator.mediaDevices || ((navigator.mozGetUserMedia || navigator.webkitGetUserMedia) ? {
getUserMedia: function(c) {
return new Promise(function(y, n) {
(navigator.mozGetUserMedia || navigator.webkitGetUserMedia).call(navigator, c, y, n);
});
}
} : null);
to setup the microphone for use. This works great in Chrome (v45) and Firefox (v36), but in Firefox (v41) I get the following error in the console:
Error: setting a property that has only a getter
RecorderSvc.initAudio@http://fakewebsite.com/js/services/recorder.js:61:1
I can solve the problem by doing:
if (navigator.mozGetUserMedia || navigator.webkitGetUserMedia) {
navigator.mediaDevices.getUserMedia = function(c) {
return new Promise(function(y, n) {
(navigator.mozGetUserMedia || navigator.webkitGetUserMedia).call(navigator, c, y, n);
});
}
}
but this doesn't work in Chrome or Firefox (v36).
I can't figure out how to fix this without breaking one of the browsers. Any ideas?
Upvotes: 2
Views: 1599
Reputation: 42480
The code you've copied (which I wrote incidentally) does a lousy job trying to polyfill navigator.mediaDevices.getUserMedia
into browsers that don't have it natively yet. It has since been removed from where you found it. Thanks for spotting that it's broken.
Polyfilling is tricky business, so I highly recommend using adapter.js, the official WebRTC polyfill, instead of attempting to shim it manually. You can use a recent version of adapter.js, or link to the always latest one directly, like this:
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
See https://jsfiddle.net/srn9db4h/ for an example of this that works in the browsers you mention.
I wont try to correct the code you mention, because polyfilling navigator.mediaDevices
correctly got quite complicated.
It's also insufficient, because the location of getUserMedia
isn't the only thing that has changed in the specification. The format of the constraints argument has changed as well, which is why navigator.mediaDevices.getUsermedia
is still behind an experimental flag in Chrome 45.
adapter.js takes care of all this until the browsers catch up.
Upvotes: 2
Reputation: 26
If you surround your statement in a Try Catch block, it'll work.
if (navigator.mediaDevices || (navigator.mozGetUserMedia || navigator.webkitGetUserMedia)) {
try {
navigator.mediaDevices = {
getUserMedia: function(c) {
return new Promise(function(y, n) {
(navigator.mozGetUserMedia || navigator.webkitGetUserMedia).call(navigator, c, y, n);
});
}
};
}
catch(err) {
navigator.mediaDevices.getUserMedia = function(c) {
return new Promise(function(y, n) {
(navigator.mozGetUserMedia || navigator.webkitGetUserMedia).call(navigator, c, y, n);
});
}
}
} else {
navigator.mediaDevices = null;
}
Upvotes: 1