10

I know I can define video stream resolution at the initialization state:

var video_constraints = {
  mandatory: {
    maxHeight: 480,
    maxWidth: 640 
  },
  optional: []
};

navigator.getUserMedia({
  audio: false,
  video: video_constraints
}, onsuccess);

I'm wondering is there any way I can change video stream resolution in the middle of communication, i.e. after initialization?

Limon Monte
  • 52,539
  • 45
  • 182
  • 213
  • This doesn't affect your question, but I note that the constraints in your example are Chrome specific rather than [standard](http://stackoverflow.com/questions/28282385/webrtc-firefox-constraints/28911694#28911694). – jib Apr 21 '15 at 03:56

2 Answers2

5

There is MediaStreamTrack.applyConstraints() in the spec but it doesn't look like it is supported in the browsers so far or maybe it was removed? For me it looks like this is not possible at the moment. Also take a look at this question at SO.

The only thing would be according to the question above to change the stream. One possibility would be to create a new stream with higher resolution, add that stream and replace the stream on the otherside. Afterwards you can stop/detach the stream.

Community
  • 1
  • 1
Robert
  • 5,484
  • 1
  • 22
  • 35
  • If talking about browser support, it's probably important to mention that adding/removing/replacing streams lacks good browser support as well. – xdumaine Apr 20 '15 at 17:06
  • Well you can just use addStream/removeStream on `RtcPeerConnection` replacing is not supported though. – Robert Apr 20 '15 at 17:51
  • addStream/removeStream aren't supported in firefox, and there's a bug making addStream fail in Chrome. – xdumaine Apr 20 '15 at 18:19
  • I should say that they're not supported for renegotiation - you can't add/remove once the session has been negotiated. – xdumaine Apr 20 '15 at 18:20
  • @xdumaine I disagree, chrome supports re-negotiation( I have tested it) and firefox is saying they would soon support it( hopefully their next release). – mido Apr 21 '15 at 00:20
  • 3
    Re-negotiation is supported in Chrome and Firefox 38. But, `replaceTrack`, an experimental not-standard-yet feature, [is supported](http://jsfiddle.net/8nem95k7) in release Firefox (37). `MediaStreamTrack.applyConstraints()` support is coming. – jib Apr 21 '15 at 03:51
  • @mido22 Disagree all you want, but I'm telling you it's got a bug. I've been dealing with it for weeks, and other have been, for much longer: https://code.google.com/p/webrtc/issues/detail?id=2782 – xdumaine Apr 21 '15 at 14:41
  • If you can show me a an implementation of renegotiation that works in chrome and firefox from both offerer and answerer, I'd love it, but right now, that doesn't exist. – xdumaine Apr 21 '15 at 15:06
  • What exactly do you mean with "renegotiation"? I am able with my code to create a `RtcPeerConnection` and add streams/data channels afterwards. But I don't know if this needs renegotiation or if it just negotiates once. – Robert Apr 21 '15 at 16:46
  • applyConstraints() works in FF now, but I can only manage to switch from a restricted resolution (like max-width: 360) to a higher resolution. If I then try to restrict again, the higher resolution becomes sticky. In Chrome, applyConstraints() does not work yet, so I managed to do the switch by calling getUserMedia again and re-establishing the peer connection afterwards. Works in both directions (high resolution to low resolution and back). – waldgeist May 12 '16 at 15:30
1

I had the same situation. So I used this technique.

(01) replace the local stream with the new video constraints.

(02) replaced the sender track with the new stream track.

function gotLocalStream(mediaStream) {
    localVideo.srcObject = mediaStream;

    const track = mediaStream.getVideoTracks()[0];
    const constraints = track.getConstraints();

    changePeerTrack()
};


async function startMyLocalStream(constraints){

   return new Promise((resolve,reject)=>{
     try{
         if (localStream) {
            localStream.getTracks().forEach(track => {
                track.stop();
            });
         }

         navigator.mediaDevices.getUserMedia(constraints)
            .then(gotLocalStream)
            .then(()=>{
                resolve(true)
            })
            .catch(e => {
                mediaError('getUserMedia', e.message, e.name);
            });
       }
       catch (e){
          //todo over constraints error
          console.error(e);
          reject(e);
       }
    })
}

function changePeerTrack(){
   if(localPeerConnection){
      localStream.getTracks().forEach( (track)=>{
         var sender = localPeerConnection.getSenders().find(function(s) {
             return s.track.kind == track.kind;
         });
         sender.replaceTrack(track);
      });
   }
 }

/**
 * change the video quality
**/
let constraints = {
    video: {width: {exact: 1280}, height: {exact: 720}, facingMode: "user"}
}
startMyLocalStream(constraints)

It worked for me. You can check your browser compatibilities here