🎻 May 2022 fiddle
Look us up here for the WebRTC Fiddle of the Month, created… once a month.
Or just enroll to one of our excellent WebRTC training courses.
Tsahi: Hi, everyone, and welcome to the WebRTC Fiddle of the Month. This time we’re going to talk about GetUserMedia again. And this time, we’re going to go and look at what exactly do you need to pass as parameters to GetUserMedia. What are the arguments that you need there? Now, why is it even important? Let’s hear this to see exactly what the problem is.
You go and call GetUserMedia. And let’s say that you want to allow access to the microphone, and the camera. So the first pop up comes in, it has to be about a microphone, the user needs to go and click the Allow button here to get access. Once he did that, he’s been asked to give access to the camera separately. We’re in the process where the user started the session, and then he needs to go and click Allow twice in order to get to where he needs. Calling GetUserMedia for audio, and then GetUserMedia for video is bad for our health. What most of us do, they go and call GetUser Mediawith both audio and video to receive this dialog box from the Chrome browser. Okay, now we get allow request for both camera and microphone. At the same time, we can click Allow and we’re all happy, then everything is fine, right?
Philipp: Well, we’re happy in the good case. We’re not happy if there’s an error with either the camera or the microphone. Because we have a hard time figuring out where the error comes from. Does it come from the camera? Does it come from the microphone?
Tsahi: Okay, so let’s call GetUserMedia, ask for access to the microphone and the camera. Clicked allow, the user clicked allow, function returns with a failure. What do I do now?
Philipp: Yes, I’m… in all cases, you probably want to fail the user experience because there was an error. But if you look at all your sessions, you might want to know whether this was an error with audio or video specifically. So you can track how this develops over time, you will determine if there’s, for example, Chrome regression. If you can determine that then you can find the bug and it gets fixed.
Tsahi: I would say that if I fail to access the camera, I might still want to go on with the call and just do voice.
Philipp: Sometimes. Yes.
Tsahi: Okay. So how do I do that exactly?
Philipp: You want to know, or rather, you want to avoid this two pop ups, but only in cases where you don’t have permission to the devices. Because if you don’t, if you have persistent permissions, then you don’t get the pop ups, you don’t need to click Allow twice, and everything is fine. And in that case, you can call GetUserMedia for audio and video separately, and then combine them into a single media stream.
Tsahi: Let’s go back. This is a service called “philipphancke dot com”, I go to do a call there for the first time. If I do GetUserMedia with both audio and video, it’s not good. But if I’ve already done a call there, and I’ve already allowed access to my camera and my microphone, then going in to GetUserMedia for audio only, and then calling GetUserMedia for video only means that I don’t get the pop up anyway. So the best approach would be to do that, because then I’ve got this granularity of ‘did I have access to the camera’ separately from ‘did I have access to the microphone?’.
Philipp: Yes.
Tsahi: Okay. And how exactly do I know that if I will call GetUserMedia, the user will not be prompted.
Philipp: We have APIs for that. And this is what we will show in this fiddle.
Tsahi: Yes.
Philipp: We have two APIs for that. One is the Permissions API, which is the more explicit way to do it. And you call navigator.permissions.query({name: “microphone”}) for microphone permission and navigator.permissions.query({name: “camera”}) for camera permission. This is a nice API. The problem is it’s not implemented for a camera and microphone, and not supported in Firefox, but it works in Chrome, if that’s enough for you, then you can…
Tsahi: There’s this question that always comes up. What about Safari?
Philipp: I don’t know to be honest.
Tsahi: Okay. So go check, and let us know.
Philipp: Yes.
Tsahi: Not you – the people that are viewing this video.
Philipp: Yes.
Tsahi: Okay.
Philipp: The other alternative is the older navigator mediated enumerateDevices API, which you want to use anyway because you want to know, does the user have a camera and a microphone. And if you have permissions, you can see that and get a much better result.
This is the result from the Permissions API. And there’s audio capture and the status is granted, which means the fiddle has permission to access the microphone.
Tsahi: Okay.
Philipp: Same for video; status granted, so we’re good there.
Tsahi: Okay.
Philipp: And in the enumerate devices, API is less explicit. So you know that you have access or persistent access to the camera if you get a video device whose label is not the empty string, because if you don’t have access, this is hidden for privacy reasons.
Tsahi: Okay. What I’m looking for is to call enumerateDevices, find audio and video devices, and then see if there are labels; if there are labels I can call GetUserMedia without a pop up.
Philipp: Yes, that is what you want.
Tsahi: Which of these approaches would you use?
Philipp: enumerateDevices works best, and you might already use it anyway, because you need to check if you have an audio device at all. If you have no camera and call GetUsingMedia with audio and video, or with video, only then that call will fail. And that’s something you want to avoid as well.
Tsahi: Okay, so let’s sum it up:
In my code, I call first enumerateDevices, or check the new Permissions API, whatever I see fit.
Based on enumeratedDevices; in our case, we’re going to check if there are labels. If there are labels, it means that we have access. And then I would call GetUserMedia for audio separately from GetUser Mediafor video, because there are no pop ups and I’d rather have these granular failures or successes.
If enumeratorDevices doesn’t provide the labels, I would call GetUserMedia with both audio and video. Because that way, I will let the user only see the pop-up once.
Philipp: Yes. And if you don’t have permission, you might want to do a more elaborate flow telling the user ‘Oh, we’re going to ask you for permissions.’ Because you want to avoid user clicking ‘No’ on the permissions.
Tsahi: With an arrow or two, to the right part of the screen, depending on the type of browser.
Philipp: Yes.
Tsahi: Okay. Okay. Thank you for that, Philipp. We’ll see you again in our next WebRTC Fiddle of the Month, next month.