diff --git a/webclient/app-controller.js b/webclient/app-controller.js index f63bb32f4..7f48148aa 100644 --- a/webclient/app-controller.js +++ b/webclient/app-controller.js @@ -93,7 +93,13 @@ angular.module('MatrixWebClientController', ['matrixService', 'mPresence', 'even }; $rootScope.$watch('currentCall', function(newVal, oldVal) { - if (!$rootScope.currentCall) return; + if (!$rootScope.currentCall) { + // This causes the still frame to be flushed out of the video elements, + // avoiding a flash of the last frame of the previous call when starting the next + angular.element('#localVideo')[0].load(); + angular.element('#remoteVideo')[0].load(); + return; + } var roomMembers = angular.copy($rootScope.events.rooms[$rootScope.currentCall.room_id].members); delete roomMembers[matrixService.config().user_id]; @@ -140,7 +146,19 @@ angular.module('MatrixWebClientController', ['matrixService', 'mPresence', 'even } else if (oldVal == 'ringing') { angular.element('#ringAudio')[0].pause(); } else if (newVal == 'connected') { - $scope.videoMode = 'large'; + $timeout(function() { + //if ($scope.currentCall.type == 'video') $scope.videoMode = 'large'; + }, 5000); + } + + if ($rootScope.currentCall && $rootScope.currentCall.type == 'video' && $rootScope.currentCall.state != 'connected') { + $scope.videoMode = 'mini'; + } + }); + $rootScope.$watch('currentCall.type', function(newVal, oldVal) { + // need to listen for this too as the type of the call won't be know when it's created + if ($rootScope.currentCall && $rootScope.currentCall.type == 'video' && $rootScope.currentCall.state != 'connected') { + $scope.videoMode = 'mini'; } }); diff --git a/webclient/app.css b/webclient/app.css index 69e608287..7b6051e0b 100755 --- a/webclient/app.css +++ b/webclient/app.css @@ -97,30 +97,44 @@ a:active { color: #000; } left: 0px; z-index: 1; background-color: rgba(0,0,0,0.0); + pointer-events: none; transition: background-color linear 300ms; } #videoBackground.large { background-color: rgba(0,0,0,0.85); + pointer-events: auto; } -#localVideo { - position: absolute; +#videoContainer { + max-width: 1280px; + margin: auto; top: 32px; - left: 160px; +} + +#videoContainer.large { +} + +#localVideo.mini { + position: relative; + left: 120px; width: 128px; height: 72px; - z-index: 2; +} + +#localVideo.ended { + -webkit-filter: grayscale(1); } #remoteVideo { - position: absolute; - top: 32px; - left: 300px; + transition: all linear 300ms; +} + +#remoteVideo.mini { + position: relative; + left: 120px; width: 128px; height: 72px; - z-index: 2; - transition: all linear 300ms; } #remoteVideo.large { diff --git a/webclient/components/matrix/matrix-call.js b/webclient/components/matrix/matrix-call.js index 636259297..5ba782bac 100644 --- a/webclient/components/matrix/matrix-call.js +++ b/webclient/components/matrix/matrix-call.js @@ -65,7 +65,7 @@ angular.module('MatrixCall', []) var stunServer = 'stun:stun.l.google.com:19302'; var pc; if (window.mozRTCPeerConnection) { - pc = window.mozRTCPeerConnection({'url': stunServer}); + pc = new window.mozRTCPeerConnection({'url': stunServer}); } else { pc = new window.RTCPeerConnection({"iceServers":[{"urls":"stun:stun.l.google.com:19302"}]}); } @@ -118,6 +118,17 @@ angular.module('MatrixCall', []) this.peerConn.setRemoteDescription(new RTCSessionDescription(this.msg.offer), this.onSetRemoteDescriptionSuccess, this.onSetRemoteDescriptionError); this.state = 'ringing'; this.direction = 'inbound'; + + if (window.mozRTCPeerConnection) { + // firefox's RTCPeerConnection doesn't add streams until it starts getting media on them + // so we need to figure out whether a video channel has been offered by ourselves. + if (this.msg.offer.sdp.indexOf('m=video') > -1) { + this.type = 'video'; + } else { + this.type = 'voice'; + } + } + var self = this; $timeout(function() { if (self.state == 'ringing') { @@ -167,7 +178,10 @@ angular.module('MatrixCall', []) MatrixCall.prototype.hangup = function(suppressEvent) { console.log("Ending call "+this.call_id); - this.remoteVideoElement.pause(); + // pausing now keeps the last frame (ish) of the video call in the video element + // rather than it just turning black straight away + if (this.remoteVideoElement) this.remoteVideoElement.pause(); + if (this.localVideoElement) this.localVideoElement.pause(); this.stopAllMedia(); if (this.peerConn) this.peerConn.close(); @@ -318,7 +332,7 @@ angular.module('MatrixCall', []) }; MatrixCall.prototype.getUserMediaFailed = function() { - this.onError("Couldn't start capturing audio! Is your microphone set up?"); + this.onError("Couldn't start capturing! Is your microphone set up?"); this.hangup(); }; @@ -411,6 +425,8 @@ angular.module('MatrixCall', []) MatrixCall.prototype.onHangupReceived = function() { console.log("Hangup received"); + if (this.remoteVideoElement) this.remoteVideoElement.pause(); + if (this.localVideoElement) this.localVideoElement.pause(); this.state = 'ended'; this.hangupParty = 'remote'; this.stopAllMedia(); diff --git a/webclient/index.html b/webclient/index.html index 05801a93b..78a68753d 100644 --- a/webclient/index.html +++ b/webclient/index.html @@ -45,7 +45,12 @@ -
+
+
+ + +
+
- - {{ user_id }}