WebRTC - 在通信过程中改变视频流

WebRTC - change video stream in the middle of communication

我的目标是使用 webrtc 网络应用程序在视频或音频通话中启用屏幕共享。

我发现我可以使用 MediaStreamTrack.applyConstraints() 来更改视频 属性 但是可以更改视频源吗?此外,如何将视频添加到现有音频流中。

我暂时需要这个才能在 chrome 上工作。

localStream.stop();
peerconnection.removeStream(localStream);

我能够通过以下步骤找到解决方案

  1. 删除当前流

  2. 添加新流

  3. 创建新报价

请注意,removeStream 已弃用且不再出现在规范中,并且并未在所有浏览器中实现。例如。这在 Firefox 中不起作用。 stream.stop() 也被弃用,取而代之的是 stream.getTracks().forEach(track => track.stop())

截至今天,我觉得对你的情况更好的方法是使用 RTCRtpSender.replaceTrack 方法。

假设您的相机流是 "camStream",您可以使用以下方法获取所需的 RTCRtpSender object:

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

...

最后两行为连接添加了视频和音频功能。

...

假设您的屏幕流是 "screenStream",那么您可以像这样从摄像头切换到屏幕共享视频:

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

...

无需替换音轨,因为我们只对在保持音频输入不变的情况下更改视觉效果感兴趣。

使用这种方法的好处是不需要对等端重新协商来切换视频源。

此方法的另一个好处是您无需停止 camStream。完成屏幕共享后,您可以使用以下方式切换回视频源:

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

您可以查看 replaceTrack 的文档 here

我有一个可用的 webrtc 会议解决方案,它支持使用这些类似步骤的屏幕共享和屏幕录制。你可以看看here

它在 firefox 上开箱即用,但要使其在 chrome 上运行,您需要启用 "Experimental Web Platform" 标志(转到 chrome://flags/ )

使用你的方法产生如下错误

代码如下:

  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);

结果:

  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)

获取 rtpSender,同时将 addTrack 添加到 localPeerConnection

然后替换你需要的曲目

rtpSender.setTrack(camVideoTrack, 真); //对于相机videoTrack


rtpSender.setTrack(screenShareTrack, true); //用于屏幕共享 videoTrack

代码如下:

  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);
},