问题
In my application a user can make calls if he can produce an audio stream. So, I need to require access to the microphone (audio stream). Without it the application should throw an error. Video is optional. So, I call navigator.getUserMedia
and put constraints
like this:
{ audio: true, video: false }
And it throws an error when a microphone is not present, just like I need. But a side effect from this is that if the user also has access to a camera, video is not present in stream.
But if I set both audio
and video
to true
I would have an error in cases when users have a microphone but do not have access to a camera (which is ok according to my application logic)
How I can make a video stream optional get getUserMedia
?
回答1:
A solution I have found is to call getUserMedia
with video and audio enabled, if the call fails(meaning that they either don't have a camera or a mic) then you call getUserMedia
again from the failure callback that you provide requesting access to the microphone only.
var failedLocalAudioAndVideoStreamCallBack = function (error) {
getUserMedia({ audio: true, video: false },
gotLocalAudioStreamCallBack, failedLocalAudioStreamCallBack )});
}
getUserMedia({ audio: true, video: true },
gotLocalAudioAndVideoStreamCallBack, failedLocalAudioAndVideoStreamCallBack);
Of course, you can handle successes and failures however you like.
NOTE: if there is no camera, the pop-up requesting the initial camera feed(that will fail) never occurs. So, the user will only get one request for access(which makes this solution a tad bit more palatable).
回答2:
There now exists another way. You can now check directly how many cameras and microphones the user has before calling getUserMedia
:
navigator.mediaDevices.enumerateDevices()
.then(devices => {
var cams = devices.filter(device => device.kind == "videoinput");
var mics = devices.filter(device => device.kind == "audioinput");
var constraints = { video: cams.length > 0, audio: mics.length > 0 };
return navigator.mediaDevices.getUserMedia(constraints);
})
.then(stream => video.srcObject = stream)
.catch(failed);
The old way still works as well, but this may be a bit cleaner.
Note that is using enumerateDevices, which in Chrome at this time requires enabling a flag, or using adapter.js.
Update: Chrome now supports enumerateDevices
as well.
来源:https://stackoverflow.com/questions/25308486/make-video-stream-optional-in-getusermedia