Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Control video send framerate on the fly in webrtc

Right now I use the b=AS:1000 in the offer SDP to set the upper limit(i.e. 1Mbps) for the upstream video to control the amount of video I am sending to the remote peer. I am looking into a different approach, so I was wondering if there is a way to control video frame rate on the fly of the current active video session?

EDIT: I found out that getUserMedia supports minFrameRate and maxFrameRate parameters. So can I call getUserMedia while my peer connection is in session? Another similar use case, which find reasonable, is to be able to change the camera while I am already in a peer session? Without having to renegotiate SDPs, ICE, ... Is this doable?

like image 261
Aki Avatar asked Mar 27 '15 14:03

Aki


2 Answers

You're asking several questions, and when this answer was first written, the short answer to most of them was: not yet (though I've since updated it thanks to DJ House's answer below!).

applyConstraints

You should be able to alter constraints during an active session, using applyConstraints like this:

const videotrack = stream_from_getUserMedia.getVideoTracks()[0];
videotrack.applyConstraints({ frameRate: { max: 10 } });

Most implementations today are able to decimate frame rates and not just deliver the modes available in the camera.

Try this fiddle.

RTCRtpSender

You should be able to control encoding & transmission in the sender object using setParameters:

const pc = RTCPeerConnection(config);

const videotrack = stream.getVideoTracks()[0];
const sender = pc.addTrack(videotrack, stream);

// get the current parameters first
const params = sender.getParameters();

if (!params.encodings) params.encodings = [{}]; // Firefox workaround!

params.encodings[0].maxBitrate = 60000;
params.encodings[0].scaleResolutionDownBy = 2;
sender.setParameters(params);

encodings is an array, but unless simulcast is used, there's just one entry.

Try this fiddle! (tested in Chrome, Firefox, Safari & Edge!)

RTCRtpSender.replaceTrack

You should also be able to replace the camera track in an ongoing peer session, like this:

const videotrack2 = a_different_stream.getVideoTracks()[0];
await sender.replaceTrack(videotrack2);

It alters what the remote sees, without altering things at this end. Try it in this fiddle.

like image 74
jib Avatar answered Sep 30 '22 02:09

jib


For anyone who ends up here like I did (5 years later), I needed to get the parameters before setting them. I am assuming since this was such an old question that the API just got a little out dated.

Without getting the parameters first, I always got this error:

Failed to execute 'setParameters' on 'RTCRtpSender': required member codecs is undefined.

Here's a quick way to get and manipulate the current parameters:

var pc = RTCPeerConnection(config);

var videotrack = stream.getVideoTracks()[0];
var sender = pc.addTrack(videotrack, stream);

// get the current parameters first
var params = sender.getParameters();

params.encodings[0].maxBitrate = 60000;
params.encodings[0].scaleResolutionDownBy = 2;

sender.setParameters(params);

This was still a great answer for me to quickly debug some Webrtc bandwidth related issues.

like image 44
DJ House Avatar answered Sep 30 '22 01:09

DJ House