summary refs log tree commit diff
path: root/webclient
diff options
context:
space:
mode:
authorDavid Baker <dbkr@matrix.org>2014-08-29 11:29:36 +0100
committerDavid Baker <dbkr@matrix.org>2014-08-29 11:29:36 +0100
commit41d02ab6742643c755f37665c31afa94c0cc8af5 (patch)
tree0771a9e7239d7820833146510f0d70b80b042a59 /webclient
parentFirst basic working VoIP call support (diff)
downloadsynapse-41d02ab6742643c755f37665c31afa94c0cc8af5.tar.xz
More basic functionality for voip calls (like hanging up)
Diffstat (limited to 'webclient')
-rw-r--r--webclient/components/matrix/matrix-call.js70
-rw-r--r--webclient/components/matrix/matrix-phone-service.js2
-rw-r--r--webclient/room/room.html2
3 files changed, 69 insertions, 5 deletions
diff --git a/webclient/components/matrix/matrix-call.js b/webclient/components/matrix/matrix-call.js
index a5f2529b87..3aab6413fc 100644
--- a/webclient/components/matrix/matrix-call.js
+++ b/webclient/components/matrix/matrix-call.js
@@ -16,6 +16,25 @@ limitations under the License.
 
 'use strict';
 
+var forAllVideoTracksOnStream = function(s, f) {
+    var tracks = s.getVideoTracks();
+    for (var i = 0; i < tracks.length; i++) {
+        f(tracks[i]);
+    }
+}
+
+var forAllAudioTracksOnStream = function(s, f) {
+    var tracks = s.getAudioTracks();
+    for (var i = 0; i < tracks.length; i++) {
+        f(tracks[i]);
+    }
+}
+
+var forAllTracksOnStream = function(s, f) {
+    forAllVideoTracksOnStream(s, f);
+    forAllAudioTracksOnStream(s, f);
+}
+
 angular.module('MatrixCall', [])
 .factory('MatrixCall', ['matrixService', 'matrixPhoneService', function MatrixCallFactory(matrixService, matrixPhoneService) {
     var MatrixCall = function(room_id) {
@@ -55,7 +74,15 @@ angular.module('MatrixCall', [])
     };
 
     MatrixCall.prototype.hangup = function() {
-        console.trace("Rejecting call "+this.call_id);
+        console.trace("Ending call "+this.call_id);
+
+        forAllTracksOnStream(this.localAVStream, function(t) {
+            t.stop();
+        });
+        forAllTracksOnStream(this.remoteAVStream, function(t) {
+            t.stop();
+        });
+
         var content = {
             msgtype: "m.call.hangup",
             version: 0,
@@ -66,6 +93,7 @@ angular.module('MatrixCall', [])
     };
 
     MatrixCall.prototype.gotUserMediaForInvite = function(stream) {
+        this.localAVStream = stream;
         var audioTracks = stream.getAudioTracks();
         for (var i = 0; i < audioTracks.length; i++) {
             audioTracks[i].enabled = true;
@@ -86,6 +114,7 @@ angular.module('MatrixCall', [])
     };
 
     MatrixCall.prototype.gotUserMediaForAnswer = function(stream) {
+        this.localAVStream = stream;
         var audioTracks = stream.getAudioTracks();
         for (var i = 0; i < audioTracks.length; i++) {
             audioTracks[i].enabled = true;
@@ -172,7 +201,8 @@ angular.module('MatrixCall', [])
 
     MatrixCall.prototype.onIceConnectionStateChanged = function() {
         console.trace("Ice connection state changed to: "+this.peerConn.iceConnectionState);
-        if (this.peerConn.iceConnectionState == 'completed') {
+        // ideally we'd consider the call to be connected when we get media but chrome doesn't implement nay of the 'onstarted' events yet
+        if (this.peerConn.iceConnectionState == 'completed' || this.peerConn.iceConnectionState == 'connected') {
             this.state = 'connected';
         }
     };
@@ -191,10 +221,44 @@ angular.module('MatrixCall', [])
 
     MatrixCall.prototype.onAddStream = function(event) {
         console.trace("Stream added"+event);
+
+        var s = event.stream;
+
+        this.remoteAVStream = s;
+
+        var self = this;
+        forAllTracksOnStream(s, function(t) {
+            // not currently implemented in chrome
+            t.onstarted = self.onRemoteStreamTrackStarted;
+        });
+
+        // not currently implemented in chrome
+        event.stream.onstarted = this.onRemoteStreamStarted;
         var player = new Audio();
-        player.src = URL.createObjectURL(event.stream);
+        player.src = URL.createObjectURL(s);
         player.play();
     };
 
+    MatrixCall.prototype.onRemoteStreamStarted = function(event) {
+        this.state = 'connected';
+    };
+
+    MatrixCall.prototype.onRemoteStreamTrackStarted = function(event) {
+        this.state = 'connected';
+    };
+
+    MatrixCall.prototype.onHangupReceived = function() {
+        this.state = 'ended';
+
+        forAllTracksOnStream(this.localAVStream, function(t) {
+            t.stop();
+        });
+        forAllTracksOnStream(this.remoteAVStream, function(t) {
+            t.stop();
+        });
+
+        this.onHangup();
+    };
+
     return MatrixCall;
 }]);
diff --git a/webclient/components/matrix/matrix-phone-service.js b/webclient/components/matrix/matrix-phone-service.js
index 6f96875103..7f1ff531c4 100644
--- a/webclient/components/matrix/matrix-phone-service.js
+++ b/webclient/components/matrix/matrix-phone-service.js
@@ -59,7 +59,7 @@ angular.module('matrixPhoneService', [])
                 console.trace("Got hangup for unknown call ID "+msg.call_id);
                 return;
             }
-            call.onHangup();
+            call.onHangupReceived();
             matrixPhoneService.allCalls[msg.call_id] = undefined;
         }
     });
diff --git a/webclient/room/room.html b/webclient/room/room.html
index dceb7322f5..bc3eefaf34 100644
--- a/webclient/room/room.html
+++ b/webclient/room/room.html
@@ -104,6 +104,7 @@
                 <button ng-click="answerCall()">Answer</button>
                 <button ng-click="hangupCall()">Reject</button>
                 </div>
+                <button ng-click="hangupCall()" ng-show="currentCall && currentCall.state != 'ringing'">Hang up</button>
                 {{ currentCall.state }}
             </div>
         
@@ -111,7 +112,6 @@
             <div ng-hide="!state.stream_failure">
                 {{ state.stream_failure.data.error || "Connection failure" }}
             </div>
-           <audio id="remoteAudio" autoplay="autoplay"></audio>
         </div>
     </div>