peer.js webrtc >>在运行时更改流 [英] peer.js webrtc >> changing stream in runtime

查看:35
本文介绍了peer.js webrtc >>在运行时更改流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 peer.js 和 webrtc 开发一个跨平台的应用程序.我正在使用科尔多瓦,人行横道.另外我正在使用 webrtc 适配器 (https://github.com/webrtc/adapter)

我的代码基于 webrtc-crosswalk 示例.(https://github.com/crosswalk-project/crosswalk-samples)

我想在不创建新呼叫的情况下更改流的视频源.我的方法是删除流的轨道并添加其他摄像机的新轨道.结果是本地视频显示了正确的内容,但被叫方的远程视频卡住了.

可能我犯了一个非常基本的错误,但我找不到解决方案.我期待您的回答和解决方案.

附上我的主要代码文件.

//Notwendig, um die Dialogfunktion zu aktivierendocument.addEventListener(deviceready", onDeviceReady, false);函数 onDeviceReady() {控制台日志(导航器.通知);//现在可以安全地使用设备 API}document.addEventListener('DOMContentLoaded', function () {//PeerJS 服务器位置var SERVER_IP = '172.20.37.147';var SERVER_PORT = 9000;//当用户与应用程序交互时操作的 DOM 元素var messageBox = document.querySelector('#messages');var callerIdEntry = document.querySelector('#caller-id');var connectBtn = document.querySelector('#connect');var receiverIdEntry = document.querySelector('#recipient-id');var dialBtn = document.querySelector('#dial');var remoteVideo = document.querySelector('#remote-video');var localVideo = document.querySelector('#local-video');var cameraTurn = document.querySelector('#camera_turn');var stop = document.querySelector('#stop');//默认朝向var dir =环境";//为此客户端设置的 IDvar callerId = null;//PeerJS 对象,当此客户端与其连接时实例化//来电显示var peer = null;//使用 getUserMedia() 捕获的本地视频流var localStream = null;//DOM 实用程序var makePara = 函数(文本){var p = document.createElement('p');p.innerText = 文字;返回 p;};var addMessage = 函数(段){如果(messageBox.firstChild){messageBox.insertBefore(para, messageBox.firstChild);}别的 {messageBox.appendChild(para);}};var logError = 函数(文本){var p = makePara('错误:' + 文本);p.style.color = '红色';添加消息(p);};var logMessage = 函数(文本){addMessage(makePara(text));};//获取本地视频和音频流并在其中显示预览//本地"视频元素//successCb: 有签名 successCb(stream);收到//本地视频流作为参数var getLocalStream = function (successCb, ask = true) {if (localStream && successCb) {成功Cb(本地流);}别的 {navigator.mediaDevices.getUserMedia({ audio: true, video: { facesMode: dir } }).then(函数(流){if (localStream == null) {/* 使用流 */本地流 = 流;}别的 {stream.getTracks().forEach(function (track) {localStream.addTrack(track);});}localVideo.src = window.URL.createObjectURL(localStream);如果(成功Cb){成功Cb(流);}}).catch(函数(错误){/* 处理错误 */logError('访问本地摄像头失败');日志错误(错误消息);});}};//设置远程"视频元素源var showRemoteStream = 函数(流){remoteVideo.src = window.URL.createObjectURL(stream);};//设置呼叫者 ID 并连接到 PeerJS 服务器var 连接 = 函数 () {callerId = callerIdEntry.value;如果 (!callerId) {logError('请先设置来电显示');返回;}尝试 {//创建到 ID 服务器的连接peer = new Peer(callerId, { host: SERVER_IP, port: SERVER_PORT });//hack 以解决如果服务器连接无法连接的事实//建立后,peer 和它的 socket 属性仍然有//打开 === true;相反,听包装的 WebSocket//并在其 readyState 变为 CLOSED 时显示错误peer.socket._socket.onclose = function () {logError('没有连接到服务器');对等 = 空;};//一旦包装好,就为传入呼叫准备好本地流//WebSocket 已打开peer.socket._socket.onopen = function () {getLocalStream();};//处理代表来电的事件peer.on('call', answer);}抓住 (e) {对等 = 空;logError('连接服务器时出错');}};//拨出电话var拨号=函数(){如果(!对等){logError('请先连接');返回;}如果(!本地流){logError('无法开始通话,因为没有本地摄像头');返回}var 接收者Id = 接收者IdEntry.value;如果 (!recipientId) {logError('无法开始呼叫,因为没有设置接收者 ID');返回;}getLocalStream(函数(流){logMessage('拨出电话已启动');var call = peer.call(recipientId, stream);call.on('stream', showRemoteStream);call.on('error', function (e) {logError('调用出错');logError(e.message);});});};//接听来电var answer = 函数(调用){如果(!对等){logError('无法在没有连接的情况下接听电话');返回;}如果(!本地流){logError('无法接听电话,因为没有准备好localStream');返回;}//要求用户接听电话navigator.notification.confirm(接电话?",功能(按钮索引){如果(按钮索引 === 1){//用户点击是";logMessage('来电已接');call.on('stream', showRemoteStream);call.answer(localStream);}别的 {//用户点击否";logMessage('来电被拒绝');}},'来电',['是','否']);};函数转向(){if (dir ===用户")返回环境";别的返回用户";}var turnCamera = 函数(调用){dir = turnDirection();localStream.getTracks().forEach(function (track) {track.stop();localStream.removeTrack(track);});getLocalStream(false);};var stopCall = 函数(调用){ };//连接按钮事件connectBtn.addEventListener('click', connect);dialBtn.addEventListener('click', dial);cameraTurn.addEventListener('click', turnCamera);stop.addEventListener('click', stopCall);});

解决方案

如果您删除了一个新的轨道,然后将其添加到 PeerConnection,您需要重新协商 offer-answer 以使其正常工作.我会建议您使用 replaceTrack API 以避免重新- 改变相机输入时的协商问题.

I am developing a cross-plattform application with peer.js and webrtc. I am using cordova, crosswalk. Additionaly I am using the webrtc adapter (https://github.com/webrtc/adapter)

My code is based on the webrtc-crosswalk sample. (https://github.com/crosswalk-project/crosswalk-samples)

I want to change the videosource of the stream without creating a new call. My approche is to remove the tracks of the stream and add the new tracks of the other camera. The result is that the local video shows the right content, but the callee's remote video freezes.

Probably I am doing a very basic mistake, but i can't find a solution. I am looking forward to your answers and solutions.

My main codefile is attached.

//Notwendig, um die Dialogfunktion zu aktivieren
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
    console.log(navigator.notification);
    // Now safe to use device APIs
}


document.addEventListener('DOMContentLoaded', function () {
    // PeerJS server location
    var SERVER_IP = '172.20.37.147';
    var SERVER_PORT = 9000;

    // DOM elements manipulated as user interacts with the app
    var messageBox = document.querySelector('#messages');
    var callerIdEntry = document.querySelector('#caller-id');
    var connectBtn = document.querySelector('#connect');
    var recipientIdEntry = document.querySelector('#recipient-id');
    var dialBtn = document.querySelector('#dial');
    var remoteVideo = document.querySelector('#remote-video');
    var localVideo = document.querySelector('#local-video');
    var cameraTurn = document.querySelector('#camera_turn');
    var stop = document.querySelector('#stop');

    // the default facing direction
    var dir = "environment";

    // the ID set for this client
    var callerId = null;



    // PeerJS object, instantiated when this client connects with its
    // caller ID
    var peer = null;


    // the local video stream captured with getUserMedia()
    var localStream = null;

    // DOM utilities
    var makePara = function (text) {
        var p = document.createElement('p');
        p.innerText = text;
        return p;
    };

    var addMessage = function (para) {
        if (messageBox.firstChild) {
            messageBox.insertBefore(para, messageBox.firstChild);
        }
        else {
            messageBox.appendChild(para);
        }
    };

    var logError = function (text) {
        var p = makePara('ERROR: ' + text);
        p.style.color = 'red';
        addMessage(p);
    };

    var logMessage = function (text) {
        addMessage(makePara(text));
    };

    // get the local video and audio stream and show preview in the
    // "LOCAL" video element
    // successCb: has the signature successCb(stream); receives
    // the local video stream as an argument
    var getLocalStream = function (successCb, ask = true) {
        if (localStream && successCb) {
            successCb(localStream);
        }
        else {
          
                navigator.mediaDevices.getUserMedia({ audio: true, video: { facingMode: dir } })
                    .then(function (stream) {

                        if (localStream == null) {
                            /* use the stream */
                            localStream = stream;
                        }
                        else {
                         
                            stream.getTracks().forEach(function (track) {
                                localStream.addTrack(track);
                            });
                        }


                        localVideo.src = window.URL.createObjectURL(localStream);

                        if (successCb) {
                            successCb(stream);
                        }
                    })
                    .catch(function (err) {
                        /* handle the error */
                        logError('failed to access local camera');
                        logError(err.message);
                    });
            }
           
        
    };

    // set the "REMOTE" video element source
    var showRemoteStream = function (stream) {
        remoteVideo.src = window.URL.createObjectURL(stream);
    };

    // set caller ID and connect to the PeerJS server
    var connect = function () {
        callerId = callerIdEntry.value;

        if (!callerId) {
            logError('please set caller ID first');
            return;
        }

        try {
            // create connection to the ID server
            peer = new Peer(callerId, { host: SERVER_IP, port: SERVER_PORT });

            // hack to get around the fact that if a server connection cannot
            // be established, the peer and its socket property both still have
            // open === true; instead, listen to the wrapped WebSocket
            // and show an error if its readyState becomes CLOSED
            peer.socket._socket.onclose = function () {
                logError('no connection to server');
                peer = null;
            };

            // get local stream ready for incoming calls once the wrapped
            // WebSocket is open
            peer.socket._socket.onopen = function () {
                getLocalStream();
            };

            // handle events representing incoming calls
            peer.on('call', answer);
        }
        catch (e) {
            peer = null;
            logError('error while connecting to server');
        }
    };

    // make an outgoing call
    var dial = function () {
        if (!peer) {
            logError('please connect first');
            return;
        }

        if (!localStream) {
            logError('could not start call as there is no local camera');
            return
        }

        var recipientId = recipientIdEntry.value;

        if (!recipientId) {
            logError('could not start call as no recipient ID is set');
            return;
        }

        getLocalStream(function (stream) {
            logMessage('outgoing call initiated');

            var call = peer.call(recipientId, stream);

            call.on('stream', showRemoteStream);

            call.on('error', function (e) {
                logError('error with call');
                logError(e.message);
            });
        });
    };




    // answer an incoming call
    var answer = function (call) {
        if (!peer) {
            logError('cannot answer a call without a connection');
            return;
        }

        if (!localStream) {
            logError('could not answer call as there is no localStream ready');
            return;
        }


        //Asks user to answer the call
        navigator.notification.confirm(
            "Receive a call?",
            function (buttonIndex) {
                if (buttonIndex === 1) {
                    //user clicked "yes"
                    logMessage('incoming call answered');

                    call.on('stream', showRemoteStream);

                    call.answer(localStream);
                }
                else {
                    //user clicked "no"
                    logMessage('incoming call denied');
                }
            }
            ,
            'Incoming Call',
            ['Yes', 'No']
        );

    };



    function turnDirection() {
        if (dir === "user")
            return "environment";
        else
            return "user";
    }

    var turnCamera = function (call) {
        dir = turnDirection();
        localStream.getTracks().forEach(function (track) {
            track.stop();
            localStream.removeTrack(track);
        });
        getLocalStream(false);
        

    };
    var stopCall = function (call) { };
    // wire up button events
    connectBtn.addEventListener('click', connect);
    dialBtn.addEventListener('click', dial);
    cameraTurn.addEventListener('click', turnCamera);
    stop.addEventListener('click', stopCall);
});

解决方案

If you remove and then add a new track to a PeerConnection you need to renegotiate the offer-answer to get it working. I will recommend you to use the replaceTrack API to avoid the re-negotiation problem while changing the camera input.

这篇关于peer.js webrtc >>在运行时更改流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆