无法更改摄像头/流以进行WebRTC通话

时间:2018-10-02 20:48:55

标签: javascript html5 video socket.io webrtc

来源:https://github.com/anoek/webrtc-group-chat-example/blob/master/client.html

我正在尝试修改此Webrtc示例,以增加更改相机的功能(跨浏览器支持)。

在更换相机后,正常使用情况下效果很好,重新协商失败。

1)通过navigator.mediaDevices.enumerateDevices()

获取设备列表

2)在获取新流后更改local_media_stream

local_media_stream.getTracks().forEach(function(track) {
    track.stop();
});
local_media_stream = stream; 

3)触发重新协商功能(从源代码的第132行复制)

function renegotiate(){
    console.log("Creating RTC offer to ", peer_id);
    peer_connection.createOffer(
                    function (local_description) { 
                        console.log("Local offer description is: ", local_description);
                        peer_connection.setLocalDescription(local_description,
            function() { 
                signaling_socket.emit('relaySessionDescription', 
                    {'peer_id': peer_id, 'session_description': local_description});
                console.log("Offer setLocalDescription succeeded"); 
            },
            function() { Alert("Offer setLocalDescription failed!"); }
        );
    },
    function (error) {
        console.log("Error sending offer: ", error);
    });
};

我认为我的方法是错误的,但是我尝试了Google上发现的许多不同方法来编辑重新协商的代码,但是WebRTC和Socket.io我并不熟悉,仍然无法使事情正常

更换摄像机后,其他参与者显示的视频只是视频最后一帧的静态图像。

有人可以帮我指出我的错误吗?预先感谢。

1 个答案:

答案 0 :(得分:1)

以前,我是按照以下方式完成的(顺序很重要)。

假设您列出了我们所有可用的设备:

var devicesIds = [];

navigator.mediaDevices.enumerateDevices().then(function(devices) {
  devices.forEach(function(device) {
     devicesIds.push(device.deviceId);
  });          
});

现在您要切换:

1)停止当前曲目

localStream.getTracks().forEach(function(track) {
   track.stop();
});

2)获取新流

var constraints = {video: {deviceId: devicesIds[1]}, audio: true};

navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
  replaceTracks(stream);
}).catch(function(error) {

});

3)替换曲目:

function replaceTracks(newStream){

  detachMediaStream(elementId);   

  newStream.getTracks().forEach(function(track) {
     localStream.addTrack(track);
  });

  attachMediaStream(elementId, newStream);

  // optionally, if you have active peer connections:
  _replaceTracksForPeer(peerConnection);

  function _replaceTracksForPeer(peer) {
    peer.getSenders().map(function(sender) {
        sender.replaceTrack(newStream.getTracks().find(function(track) {
            return track.kind === sender.track.kind;
        }));
    });
  }
}

function detachMediaStream = function(id) {
  var elem = document.getElementById(id);

  if (elem) {
    elem.pause();

    if (typeof elem.srcObject === 'object') {
        elem.srcObject = null;
    } else {
        elem.src = '';
    }
  }
};

function attachMediaStream = function(id, stream) {
  var elem = document.getElementById(id);

  if (elem) {
    if (typeof elem.srcObject === 'object') {
        elem.srcObject = stream;
    } else {
        elem.src = window.URL.createObjectURL(stream);
    }

    elem.onloadedmetadata = function(e) {
        elem.play();
    };
  } else {
    throw new Error('Unable to attach media stream');
  }
};