6

My goal is to enable screen sharing in the middle of a video or audio call using webrtc web application .

Well I found that I can use MediaStreamTrack.applyConstraints() to change video property but is it possible to change the video source ? further more how can I add video to an existing audio stream .

I need this to work on chrome only for now .

jib
  • 40,579
  • 17
  • 100
  • 158
Abdullah Al Noman
  • 2,817
  • 4
  • 20
  • 35
  • Possible duplicate of [How to addTrack in MediaStream in WebRTC](http://stackoverflow.com/questions/35504214/how-to-addtrack-in-mediastream-in-webrtc) – jib Mar 17 '17 at 19:38

5 Answers5

8

As of today, I feel a better approach for your case would be to use the RTCRtpSender.replaceTrack method.

Assuming your camera stream is "camStream", you can obtain the required RTCRtpSender object using the following:

var camVideoTrack = camStream.getVideoTracks()[0];
var camAudioTrack = camStream.getAudioTracks()[0];
var videoSender = peerConnection.addTrack(camVideoTrack, camStream);
var audioSender = peerConnection.addTrack(camAudioTrack, camStream);

...

The last two lines add video and audio capability to the connection.

...

Assuming your screen stream is "screenStream", then you can switch from camera to screen share video like this:

var screenVideoTrack = screenStream.getVideoTracks()[0];
videoSender.replaceTrack(screenVideoTrack);

...

No need to replace audio track since we are only interested in changing the visual while keeping the audio input the same.

Using this approach has the benefit of not requiring peer renegotiation to switch the video sources.

Another benefit of this approach is that you don't need to stop your camStream. When you are done sharing your screen, you can switch back the video source using:

videoSender.replaceTrack(camStream.getVideoTracks()[0]);

You can check out the documentation for replaceTrack here

I have a working webrtc meetings solution which supports screen sharing and screen recording using these similar steps. you can check it out here

It works out of the box on firefox, but to make it work on chrome, you need to enable "Experimental Web Platform" flag (go to chrome://flags/ )

Anthony Anyanwu
  • 987
  • 11
  • 7
  • hi, I am using RTCRtpSender to replace my local track, but my localRtcVIew does not display new track any more – famfamfam Dec 31 '22 at 05:24
4
localStream.stop();
peerconnection.removeStream(localStream);

I was able to find the solution by following steps

  1. remove the current stream

  2. add new stream

  3. create new offer

Note that removeStream is deprecated and no longer in the spec, and not implemented in all browsers. E.g. this won't work in Firefox. stream.stop() is also deprecated in favor of stream.getTracks().forEach(track => track.stop())

Abdullah Al Noman
  • 2,817
  • 4
  • 20
  • 35
  • 4
    Note that `removeStream` is deprecated and no longer in the spec, and not implemented in all browsers. E.g. this won't work in Firefox. `stream.stop()` is also deprecated in favor of `stream.getTracks().forEach(track => track.stop())`. – jib Mar 17 '17 at 19:38
  • thanks jib .. My goal is to make it workable in chrome for now – Abdullah Al Noman Mar 21 '17 at 03:19
0

Use your method to generate the following error

Code as follows:

  var camVideoTrack = options.attachStream.getVideoTracks()[0];
  var camAudioTrack = options.attachStream.getAudioTracks()[0];
  var videoSender = peer.addTrack(camVideoTrack, options.attachStream);
  var audioSender = peer.addTrack(camAudioTrack, options.attachStream);
  var videoTrack = stream.getVideoTracks()[0];
  videoSender.replaceTrack(videoTrack);

the result:

  adapter-latest.js:629 Uncaught (in promise) DOMException: Failed to execute 'addTrack' on 'RTCPeerConnection': A sender already exists for the track.
    at RTCPeerConnection.addTrack (https://education.abc.dev:9559/adapter-latest.js:629:31)
bguiz
  • 27,371
  • 47
  • 154
  • 243
johnny xu
  • 31
  • 2
0

Code as follows:

  addMixedVideo: function(stream, peer) {
    if (!stream) return;
    
    var videoTrack = options.attachStream.getVideoTracks()[0];
    var sender = peer.getSenders().find(function(s) {
        return s.track.kind == videoTrack.kind;
    });
    console.log('addMixedVideo -- found sender: ', sender);
    
    var videoTrackMixer = stream.getVideoTracks()[0];
    sender.replaceTrack(videoTrackMixer);
},
johnny xu
  • 31
  • 2
  • Perhaps a little context to this would be helpful. Also what is `options` here and what does the params mean? – innocent Dec 29 '22 at 16:57
-1

get rtpSender while addTrack to localPeerConnection

then replace whatever track you need

rtpSender.setTrack(camVideoTrack, true); //for camera videoTrack

or

rtpSender.setTrack(screenShareTrack, true); //for screen share videoTrack

Gv Ravi
  • 333
  • 2
  • 5