如何在webRTC应用程序中保存屏幕共享流

时间:2018-03-28 18:34:35

标签: javascript asp.net webrtc

我有一个用asp.net编写的视频应用程序和用JS中的webRTC编写的c#。 有些外包不久前给我写了(不能再联系到他了)应用程序工作得非常好,除了一个问题。 这个视频应用程序是为屏幕共享使用而编写的,它使用一些chrome扩展来进行屏幕共享,这也很有效。问题是,只要您从屏幕共享返回到网络摄像头流,您就无法返回到屏幕共享流。它看起来像程序员这样写的。 我尝试再次打开扩展程序,但它发送给我一个错误。我的问题是,有没有办法可以保存屏幕共享流并更改视频源而不用触摸扩展名? 这是webrtc的js代码: 第三个'if'

中getfeed的主要问题
     getFeed = function (shareScreen, username, userType, reinit, cb) {
         if (shareScreen) {
             $("#screen-share").attr("disabled", "disabled");
             $("#video-share").removeAttr("disabled");

           //  getUserMedia(session, onSuccess, onError);
             if (webrtcDetectedBrowser == "chrome") {
                 DetectRTC.screen.isChromeExtensionAvailable(function (isAvaliabe) {
                     if (isInScreenSharing) {
                         return;
                     }
                     if (isAvaliabe) {
                         isInScreenSharing = true;
                         captureUserMedia(onSuccess);

                     } else {
                         alertify.confirm("Screen sharing extension is not installed," +
                             " do you wish to install it now?",
                             function(e) {
                                 if (e) {

    window.open("https://chrome.google.com/webstore/detail/screen-capturing- 
    for-micr/hmppjaalobpkbpneompfdpfilcmfhfik", "_blank");
                                     alertify.alert("Click Ok to reload page 
    after installing extension ", function () {
                                         location.href = location.href;
                                     });
                                 }
                             });
                     }
                 });

             } else {
                 isInScreenSharing = false;
                 getScreenId(function (error, sourceId, screen_constraints) {
                     screen_constraints.video = _showWebCam;
                     screen_constraints.audio = _showWebCam;
                     getUserMedia(screen_constraints, onSuccess, onError);
                 });
             }


         } else {
             $("#video-share").attr("disabled", "disabled");
             $("#screen-share").removeAttr("disabled");

             getUserMedia(
             {
                 // Permissions to request
                 video: _showWebCam,
                 audio: _showWebCam
             }, onSuccess, onError);
         }

         function onSuccess(stream) { // succcess callback gives us a media stream
             $('.instructions').hide();
             if (reinit) {

                 if (screenStream) {
                     screenStream.getTracks().forEach(function (e) {
                         e.stop();
                     });
                     screenStream = null;
                 }
                 // Store off the stream reference so we can share it later
                 _mediaStream = stream;
                 if (webrtcDetectedBrowser == "chrome") {
                     if (shareScreen) {
                         //get the audio track from video stream and put it in screeen stream

                         var audioTrack = videoStream.getAudioTracks()[0];
                         var screenAudio = stream.getAudioTracks()[0];
                         if (screenAudio) {
                             _mediaStream.removeTrack(screenAudio)

                         }
                         _mediaStream.addTrack(audioTrack)
                         screenStream = _mediaStream;


                     } else {
                         videoStream = stream;
                     }
                 }

                 // Load the stream into a video element so it starts playing in the UI
                 console.log('playing my local video feed');
                 var videoElement = document.querySelector('.video.mine');
                 attachMediaStream(videoElement, _mediaStream);
                 if (cb) {
                     cb();
                 }
             } else {
                 if (webrtcDetectedBrowser == "chrome") {
                     videoStream = stream;
                 }
                 var gameId =viewModel.GameId();
                 // Now we have everything we need for interaction, so fire up SignalR
                 _connect(username, userType,gameId,     function (hub) {
                     // tell the viewmodel our conn id, so we can be treated like the special person we are.
                     viewModel.MyConnectionId(hub.connection.id);

                     // Initialize our client signal manager, giving it a 
  signaler (the SignalR hub) and some callbacks
                     console.log('initializing connection manager');
                     connectionManager.initialize(hub.server, _callbacks.onReadyForStream, _callbacks.onStreamAdded, _callbacks.onStreamRemoved);

                     // Store off the stream reference so we can share it later
                     _mediaStream = stream;

                     // Load the stream into a video element so it starts playing in the UI
                     console.log('playing my local video feed');
                     var videoElement = document.querySelector('.video.mine');
                     attachMediaStream(videoElement, _mediaStream);

                     // Hook up the UI
                     _attachUiHandlers();

                     viewModel.Loading(false);
                     if (cb) {
                         cb();
                     }

                 }, function (event) {
                     alertify.alert('<h4>Failed SignalR Connection</h4> We were not able to connect you to the signaling server.<br/><br/>Error: ' + JSON.stringify(event));
                     viewModel.Loading(false);
                 });
             }

         }

         function onError(error) {
             if (webrtcDetectedBrowser == "firefox") {
                 if (window.location.protocol === "https:") {
                     alertify.confirm("Screen sharing extension is not installed," +
                            " do you wish to install it now?",
                            function (e) {
                                if (e) {
                                    InstallTrigger.install({ "ScreenShare": { URL: "https://addons.mozilla.org/firefox/downloads/file/457292/easy_screen_sharing_for_microgamecoaching_ltd-1.0.000-fx.xpi" } });
                                }
                            });
                     return;
                 }
             }
             alertify.alert(JSON.stringify(error));
             viewModel.Loading(false);

         }

     },
    _startSession = function (username, userType, gameId) {
     //   viewModel.Username(username); // Set the selected username in the UI
        viewModel.Loading(true); // Turn on the loading indicator
       // viewModel.UserType(userType); // Set the selected username in the UI
        //viewModel.GameId(gameId); 

        if (location.hash === "#ss") {
            getFeed(true, username, userType);

        } else {
            getFeed(false, username, userType);
        }
        $("#screen-share").click(function () {
            getFeed(true, username, userType, true, function () {
                var p = connectionManager.currentPartnerId;
                connectionManager.closeAllConnections();

                _hub.server.hangUp(true);
              //  _hub.server.callUser(p,true);

            });
        });
        $("#video-share").click(function () {
            getFeed(false, username, userType, true, function () {
                var p = connectionManager.currentPartnerId;
                connectionManager.closeAllConnections();
                _hub.server.hangUp(true);
              //  _hub.server.callUser(p, true);


            });
        });

        $("#mute").click(function () {
            if (_mediaStream) {
                _mediaStream.getAudioTracks().forEach(function (t) {
                    t.enabled = t.muted = false;
                });
                var videoElement = document.querySelector('.video.mine');
                attachMediaStream(videoElement, _mediaStream);

            }
        });

        $("#unmute").click(function () {
            if (_mediaStream) {
                _mediaStream.getAudioTracks().forEach(function (t) {
                    t.enabled = t.muted = true;
                });
                var videoElement = document.querySelector('.video.mine');
                attachMediaStream(videoElement, _mediaStream);

            }
        });
    },

    _attachUiHandlers = function() {
        // Add click handler to users in the "Users" pane
        $(document).on("click", ".user", function () {

            var userName = viewModel.Username();

            if (!userName) {
                alertify.alert("Please log in to enter the room", function() {
                    location.href = viewModel.LoginUrl() + "?returnUrl="+location.href;
                });
                return;
            }

            // Find the target user's SignalR client id
            var targetConnectionId = $(this).attr('data-cid');

            // Make sure we are in a state where we can make a call
            if (viewModel.Mode() !== 'idle') {
                alertify.error('Sorry, you are already in a call.  Conferencing is not yet implemented.');
                return;
            }

            // Then make sure we aren't calling ourselves.
            if (targetConnectionId != viewModel.MyConnectionId()) {
                // Initiate a call
                _hub.server.callUser(targetConnectionId, false);

                // UI in calling mode
                viewModel.Mode('calling');
            } else {
                alertify.error("Ah, nope.  Can't call yourself.");
            }
        });

        $('#btnMessageSend').click(function() {
            sendChatMessage();
        });

        $('#inpMessageText').keypress(function (e) {
            if (e.keyCode === 13) {
                sendChatMessage();
            }
        });

        function sendChatMessage() {
            var text = $('#inpMessageText').val();
            if (text !== '') {
                $('#inpMessageText').val('');
                _hub.server.sendMessage(text, viewModel.MyConnectionId(), _callPartner.ConnectionId);

                if (_lastMessageMine === null || !_lastMessageMine) {
                    $('#pnlMessagesContainer .message-container')
                        .append('<div><div class="autor">You</div><div class="message">' + text + '</div></div>');
                } else {
                    $('#pnlMessagesContainer .message-container')
                        .append('<div><div class="message">' + text + '</div></div>');
                }
                _lastMessageMine = true;
            }
            $('#pnlMessagesContainer .message-container').scrollTop($('#pnlMessagesContainer .message-container').prop("scrollHeight"));
        }

        // Add handler for the hangup button
        $('.hangup').click(function () {
            // Only allow hangup if we are not idle
            if (viewModel.Mode() != 'idle') {
                _hub.server.hangUp(false);
                connectionManager.closeAllConnections();
                viewModel.Mode('idle');

                $('#videoTitle').html('Coaching Session');
                $('#videoPartnerName').html('');
                $('#pnlMessagesContainer .message-container').empty();
                $('#pnlChatContainer').hide();
            }
        });


        $('input[name="rbtnWebcamToogle"]').change(function () {
            _showWebCam = $(this).val() === "1";

            if (!_showWebCam) {

    //connectionManager.closeConnection(viewModel.MyConnectionId());
                var mediaStream = _mediaStream.getVideoTracks()[0];
                mediaStream.stop();
            } else {
                getFeed(false, viewModel.Username(), viewModel.UserType(), true, function () {
                    var p = connectionManager.currentPartnerId;
                    connectionManager.closeAllConnections();
                    _hub.server.hangUp(true);
                });
            }
        });
    },

    _setupHubCallbacks = function (hub) {
        // Hub Callback: Incoming Call
        hub.client.incomingCall = function (callingUser, switching) {
            console.log('incoming call from: ' + JSON.stringify(callingUser));
            if (switching) {
                hub.server.answerCall(true, callingUser.ConnectionId);

                // So lets go into call mode on the UI
                viewModel.Mode('incall');

                $('#videoTitle').html('Your Session is LIVE');
                $('#videoPartnerName').html('Your ' + callingUser.Usertype + ': ' + callingUser.Username);
                return;
            }
            // Ask if we want to talk
            alertify.confirm(callingUser.Username + ' is calling.  Do you want to chat?', function (e) {
                if (e) {
                    // I want to chat
                    hub.server.answerCall(true, callingUser.ConnectionId);
                    _callPartner = callingUser;
                    // So lets go into call mode on the UI
                    viewModel.Mode('incall');

                    $('#videoTitle').html('Your Session is LIVE');
                    $('#videoPartnerName').html('Your ' + callingUser.Usertype + ': ' + callingUser.Username);
                    $('#pnlMessagesContainer .message-container').empty();
                    $('#pnlChatContainer').show();
                } else {
                    // Go away, I don't want to chat with you
                    hub.server.answerCall(false, callingUser.ConnectionId);
                    $('#videoTitle').html('Coaching Session');
                    $('#videoPartnerName').html('');
                    $('#pnlMessagesContainer .message-container').empty();
                    $('#pnlChatContainer').hide();
                }
            });
        };

        // Hub Callback: Call Accepted
        hub.client.callAccepted = function (acceptingUser) {
            console.log('call accepted from: ' + JSON.stringify(acceptingUser) + '.  Initiating WebRTC call and offering my stream up...');

            // Callee accepted our call, let's send them an offer with our video stream
            connectionManager.initiateOffer(acceptingUser.ConnectionId, _mediaStream);
            _callPartner = acceptingUser;
            // Set UI into call mode
            viewModel.Mode('incall');

            $('#videoTitle').html('Your Session is LIVE');
            $('#videoPartnerName').html('Your ' + acceptingUser.Usertype + ': ' + acceptingUser.Username);
            $('#pnlMessagesContainer .message-container').empty();
            $('#pnlChatContainer').show();
        };

        // Hub Callback: Call Declined
        hub.client.callDeclined = function (decliningConnectionId, reason) {
            console.log('call declined from: ' + decliningConnectionId);
            _callPartner = null;
            // Let the user know that the callee declined to talk
            alertify.error(reason);

            // Back to an idle UI
            viewModel.Mode('idle');
        };

        // Hub Callback: Call Ended
        hub.client.callEnded = function (connectionId, reason, switching) {
            console.log('call with ' + connectionId + ' has ended: ' + reason);

            if (!switching) {
                // Let the user know why the server says the call is over
                alertify.error(reason);

                connectionManager.closeConnection(connectionId);

                // Set the UI back into idle mode
                viewModel.Mode('idle');

                $('#pnlMessagesContainer .message-container').empty();
                $('#pnlChatContainer').hide();
                _callPartner = null;

                $('#videoTitle').html('Coaching Session');
                $('#videoPartnerName').html('');

            } else {
                connectionManager.closeConnection(connectionId);
                _hub.server.callUser(connectionId, true);

            }

            // Close the WebRTC connection

        };

        hub.client.receiveMessage = function (senderUser, message) {
            if (_lastMessageMine == null || _lastMessageMine) {
                $('#pnlMessagesContainer .message-container')
                    .append('<div><div class="autor">' + senderUser.Username + '</div><div class="message">' + message + '</div></div>');
            } else {
                $('#pnlMessagesContainer .message-container')
                    .append('<div><div class="message">' + message + '</div></div>');
            }
            $('#pnlMessagesContainer .message-container').scrollTop($('#pnlMessagesContainer .message-container').prop("scrollHeight"));
            _lastMessageMine = false;
        }

        // Hub Callback: Update User List
        hub.client.updateUserList = function (userList) {
            viewModel.setUsers(userList);
        };

        // Hub Callback: WebRTC Signal Received
        hub.client.receiveSignal = function (callingUser, data) {
            connectionManager.newSignal(callingUser.ConnectionId, data);
        };
    },

    // Connection Manager Callbacks
    _callbacks = {
        onReadyForStream: function (connection) {
            // The connection manager needs our stream
            // todo: not sure I like this
            connection.addStream(_mediaStream);
        },
        onStreamAdded: function (connection, event) {
            console.log('binding remote stream to the partner window');

            // Bind the remote stream to the partner window
            var otherVideo = document.querySelector('.video.partner');
            attachMediaStream(otherVideo, event.stream); // from adapter.js
        },
        onStreamRemoved: function (connection, streamId) {
            console.log('removing remote stream from partner window');

            // Clear out the partner window
            var otherVideo = document.querySelector('.video.partner');
            otherVideo.src = '';
        }
    };

return {
    start: _start, // Starts the UI process
    getStream: function() { // Temp hack for the connection manager to reach back in here for a stream
        return _mediaStream;
    }
};
    })(WebRtcDemo.ViewModel, WebRtcDemo.ConnectionManager);

    // Kick off the app
    WebRtcDemo.App.start();


     var isChrome = !!navigator.webkitGetUserMedia;

     var DetectRTC = {};

    (function () {
var screenCallback;

DetectRTC.screen = {
    chromeMediaSource: 'screen',
    getSourceId: function (callback) {
        if (!callback) throw '"callback" parameter is mandatory.';
        screenCallback = callback;
        window.postMessage('get-sourceId', '*');
    },
    isChromeExtensionAvailable: function (callback) {
        if (!callback) return;

        if (DetectRTC.screen.chromeMediaSource == 'desktop') callback(true);

        // ask extension if it is available
        window.postMessage('are-you-there', '*');

        setTimeout(function () {
            if (DetectRTC.screen.chromeMediaSource == 'screen') {
                callback(false);
            } else callback(true);
        }, 2000);
    },
    onMessageCallback: function (data) {
        console.log('chrome message', data);

        // "cancel" button is clicked
        if (data == 'PermissionDeniedError') {
            DetectRTC.screen.chromeMediaSource = 'PermissionDeniedError';
            if (screenCallback) return 
    screenCallback('PermissionDeniedError');
            else throw new Error('PermissionDeniedError');
        }

        // extension notified his presence
        if (data == 'rtcmulticonnection-extension-loaded') {
            DetectRTC.screen.chromeMediaSource = 'desktop';
        }

        // extension shared temp sourceId
        if (data.sourceId) {
            DetectRTC.screen.sourceId = data.sourceId;
            if (screenCallback) screenCallback(DetectRTC.screen.sourceId);
        }
    }
};
// check if desktop-capture extension installed.
if (window.postMessage && isChrome) {
    DetectRTC.screen.isChromeExtensionAvailable();
}
    })();
    window.addEventListener('message', function (event) {
if (event.origin != window.location.origin) {
    return;
}
DetectRTC.screen.onMessageCallback(event.data);
    });
    function captureUserMedia(onStreamApproved) {
// this statement defines getUserMedia constraints
// that will be used to capture content of screen
var screen_constraints = {
    mandatory: {
        chromeMediaSource: DetectRTC.screen.chromeMediaSource,
        maxWidth: 1920,
        maxHeight: 1080,
        minAspectRatio: 1.77
    },
    optional: []
};
// this statement verifies chrome extension availability
// if installed and available then it will invoke extension API
// otherwise it will fallback to command-line based screen capturing API
if (DetectRTC.screen.chromeMediaSource == 'desktop' && !DetectRTC.screen.sourceId) {
    DetectRTC.screen.getSourceId(function (error) {
        // if exception occurred or access denied
        if (error && error == 'PermissionDeniedError') {
            alert('PermissionDeniedError: User denied to share content of his screen.');
        }
        captureUserMedia(onStreamApproved);
    });
    return;
}
// this statement sets gets 'sourceId" and sets "chromeMediaSourceId" 
if (DetectRTC.screen.chromeMediaSource == 'desktop') {
    screen_constraints.mandatory.chromeMediaSourceId = DetectRTC.screen.sourceId;
}
// it is the session that we want to be captured
// audio must be false
var session = {
    audio: false,
    video: screen_constraints
};
// now invoking native getUserMedia API
navigator.webkitGetUserMedia(session, onStreamApproved, function (error){console.error(error)});
    };

0 个答案:

没有答案