【问题标题】:Unable to change camera / stream for WebRTC call无法更改 WebRTC 呼叫的摄像头/流
【发布时间】:2018-10-02 20:48:54
【问题描述】:

来源: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);
    });
};

我认为我的方法是错误的,但是我尝试了许多在谷歌上找到的不同方法来编辑重新协商的代码,但是我对 WebRTC 和 Socket.io 不熟悉,仍然无法使事情起作用.

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

有人可以帮忙指出我的错误吗?提前致谢。

【问题讨论】:

    标签: javascript html video socket.io webrtc


    【解决方案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');
      }
    };
    

    【讨论】:

    • 嗨 Rubycon,非常感谢您的解决方案。它完美地工作!最初我认为需要重新谈判,因为我无法让它与 replaceTrack 一起使用,在遵循您的解决方案之后,它可以工作。再次感谢。 =)
    猜你喜欢
    • 1970-01-01
    • 2017-07-31
    • 2016-12-31
    • 2020-11-14
    • 1970-01-01
    • 2018-07-11
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多