What codec are you using?

🎻 November 2021 fiddle

Want to learn more about WebRTC?

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, and welcome everyone to our WebRTC Fiddle of the Month. This time we’re going to talk about how do you find out exactly what codec you’re using inside the WebRTC connection. Okay, and why do we want to even do that Phillip?

Philipp: Well, depending on the hardware support you have, you might want to negotiate different codecs. And WebRTC will give you something by default, but whether you get that depends on what the other site supports and things like that. So it’s always good to check what you get, instead of just assuming it works the way it does. 

Tsahi: And this was timely for this fiddle simply because we have a Safari bug in 15.1 on mobile.

Philipp: Yes, Safari 15.1 started crashing when you use H.264. It disables the track via the tracks enabled attribute. This is fixed in 15.2 but you need to work around it in 15.1. 

Tsahi: Okay.

Philipp: And H.264 crash on iOS is pretty bad. 

Tsahi: Yes, okay. Can you show us the fiddle then?

Philipp: Yes. We have our usual fiddle, not much HTML, just a simple log field. We are creating peer connections, connecting there on ICE candidate with the other side ICE candidate method, and we have a couple of helper functions to log something to the text fields. And then what we do down here is we have an asynchronous function that runs the thing, we acquire the camera and the video track from it, add the track to the peer connection, create an offer and then we’re doing it a bit more complicated here because I want to show something later. That we call set remote description with the offer and you will see that we will not negotiate VP8 later. Then we call set local description, create an answer on the other side called set remote description. The first connection set remote description and the second, then we wait for the connection to establish; which is this helper function. It’s a nice way which can be used in a lot of tests to wait for the connection to be up. 

Then we have two ways to query the negotiating codec. We could also look at the SDP but that requires you to parse the SDP and it is uglier. 

The first way is to query it from the get parameters function. And that’s relatively simple. We go to the first peer connection, get the first sender. If you have more than one sender, you should look for the sender that has a track set and where the track kind is video, we call getParameters() on that. And we look at the codecs attribute. And the first product is the one that is typically used for sending. And then we look at the codec MIME type, which is something like video/VP8, video/H.264. And for things like H.264 you need to look at the SDP SMTP line to determine what profile level ID it has and things like that. 

Tsahi: Okay. 

Philipp: And the alternative thing we can do is we can use getStats() function to query statistics about what is actually being sent. There we see a tiny bit more, but essentially the same information. Because the getStats() method, wait for it and then iterate the statistics which we have many reasons to do otherwise. So we might just extract that information while we also do other things. And we’re looking for outbound RTP stats with a pause the video count and then we get the associated codec statistics which is this internally referenced statistics that you can get from the output of RTP codec ID attribute and that gives us the same information as getParameters(). So we have the MIME type SDP SMTP line and the payload type. And in statistics, we also have a bit more information about the encoder implementation.

Tsahi: Which I see that for you is unknown.

Philipp: Yes, that is because this is calling things very early. So if we add a timeout for that, it will be set. Wait a second and there we see it’s libvpx. 

Tsahi: Okay. 

Philipp: And the result will obviously depend on what you’re using. In Safari, it will be H.264 and if we do another trick here and replace VP8 with no such codec, Chrome will not negotiate VP8, because it doesn’t know about no such codec. Let’s do that as well and we see now we’re negotiating VP9 here.

Tsahi: Okay. Chrome will… It’s best to not use H.264.

Philipp: Chrome really doesn’t like H.264. And if we look at the statistics that Google gave a year ago, 80% or 90% of the WebRTC connections in Chrome use VP8 or VP9. And if you look at the H.264 implementation, it’s not great. 

Tsahi: Okay. Okay. So thank you for that Philipp. And we’ll see you all in our next fiddle, next month. Bye bye.