diff --git a/lib/http-api.js b/lib/http-api.js index 9b37a0def..edddab27e 100644 --- a/lib/http-api.js +++ b/lib/http-api.js @@ -140,7 +140,7 @@ module.exports.MatrixHttpApi.prototype = { /** * Upload content to the Home Server - * @param {File object} file A File object (in a browser) or in Node, + * @param {File} file A File object (in a browser) or in Node, an object with properties: name: The file's name stream: A read stream diff --git a/lib/matrix.js b/lib/matrix.js index ba03067b9..8384afab8 100644 --- a/lib/matrix.js +++ b/lib/matrix.js @@ -24,6 +24,15 @@ module.exports.RoomState = require("./models/room-state"); module.exports.User = require("./models/user"); /** The {@link module:scheduler~MatrixScheduler|MatrixScheduler} class. */ module.exports.MatrixScheduler = require("./scheduler"); +/** + * Create a new Matrix Call. + * @function + * @param {module:client.MatrixClient} client The MatrixClient instance to use. + * @param {string} roomId The room the call is in. + * @return {module:webrtc/call~MatrixCall} The Matrix call or null if the browser + * does not support WebRTC. + */ +module.exports.createNewMatrixCall = require("./webrtc/call").createNewMatrixCall; // expose the underlying request object so different environments can use // different request libs (e.g. request or browser-request) diff --git a/lib/webrtc/call.js b/lib/webrtc/call.js index c673eaff9..32e09384d 100644 --- a/lib/webrtc/call.js +++ b/lib/webrtc/call.js @@ -1,4 +1,8 @@ "use strict"; +/** + * This is an internal module. See {@link createNewMatrixCall} for the public API. + * @module webrtc/call + */ var utils = require("../utils"); var EventEmitter = require("events").EventEmitter; @@ -186,34 +190,13 @@ MatrixCall.prototype.replacedBy = function(newCall) { */ MatrixCall.prototype.hangup = function(reason, suppressEvent) { console.log("Ending call " + this.callId); - - // 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.getRemoteVideoElement() && this.getRemoteVideoElement().pause) { - this.getRemoteVideoElement().pause(); - } - if (this.getLocalVideoElement() && this.getLocalVideoElement().pause) { - this.getLocalVideoElement().pause(); - } - - this.stopAllMedia(); - if (this.peerConn) { - this.peerConn.close(); - } - - this.hangupParty = 'local'; - this.hangupReason = reason; - + terminate(this, "local", reason, !suppressEvent); var content = { version: 0, call_id: this.callId, reason: reason }; this.sendEvent('m.call.hangup', content); - this.state = 'ended'; - if (!suppressEvent) { - this.emit("onHangup", this); - } }; /** @@ -357,14 +340,15 @@ MatrixCall.prototype.receivedAnswer = function(msg) { } var self = this; - this.peerConn.ngsetRemoteDescription( - new this.webRtc.RtcSessionDescription(msg.answer) - ).then(function(s) { - self.onSetRemoteDescriptionSuccess(s); - }, - function(e) { - self.onSetRemoteDescriptionError(e); - }); + this.peerConn.setRemoteDescription( + new this.webRtc.RtcSessionDescription(msg.answer), + function(s) { + self.onSetRemoteDescriptionSuccess(s); + }, + function(e) { + self.onSetRemoteDescriptionError(e); + } + ); this.state = 'connecting'; }; @@ -382,7 +366,7 @@ MatrixCall.prototype.gotLocalOffer = function(description) { return; } - self.peerConn.ngsetLocalDescription(description).then(function() { + self.peerConn.setLocalDescription(description, function() { var content = { version: 0, call_id: self.callId, @@ -411,8 +395,7 @@ MatrixCall.prototype.gotLocalOffer = function(description) { self.state = 'invite_sent'; }, function() { console.log("Error setting local description!"); - } - ); + }); }; /** @@ -572,20 +555,7 @@ MatrixCall.prototype.onRemoteStreamTrackStarted = function(event) { */ MatrixCall.prototype.onHangupReceived = function(msg) { console.log("Hangup received"); - if (this.getRemoteVideoElement() && this.getRemoteVideoElement().pause) { - this.getRemoteVideoElement().pause(); - } - if (this.getLocalVideoElement() && this.getLocalVideoElement().pause) { - this.getLocalVideoElement().pause(); - } - this.state = 'ended'; - this.hangupParty = 'remote'; - this.hangupReason = msg.reason; - stopAllMedia(this); - if (this.peerConn && this.peerConn.signalingState != 'closed') { - this.peerConn.close(); - } - this.emit("onHangup", this); + terminate(this, "remote", msg.reason, true); }; /** @@ -594,20 +564,7 @@ MatrixCall.prototype.onHangupReceived = function(msg) { */ MatrixCall.prototype.onAnsweredElsewhere = function(msg) { console.log("Answered elsewhere"); - if (this.getRemoteVideoElement() && this.getRemoteVideoElement().pause) { - this.getRemoteVideoElement().pause(); - } - if (this.getLocalVideoElement() && this.getLocalVideoElement().pause) { - this.getLocalVideoElement().pause(); - } - this.state = 'ended'; - this.hangupParty = 'remote'; - this.hangupReason = "answered_elsewhere"; - stopAllMedia(this); - if (this.peerConn && this.peerConn.signalingState != 'closed') { - this.peerConn.close(); - } - this.emit("onHangup", this); + terminate(this, "remote", "answered_elsewhere", true); }; /** @@ -636,6 +593,26 @@ MatrixCall.prototype.sendCandidate = function(content) { } }; +var terminate = function(self, hangupParty, hangupReason, shouldEmit) { + if (self.getRemoteVideoElement() && self.getRemoteVideoElement().pause) { + self.getRemoteVideoElement().pause(); + } + if (self.getLocalVideoElement() && self.getLocalVideoElement().pause) { + self.getLocalVideoElement().pause(); + } + self.state = 'ended'; + self.hangupParty = hangupParty; + self.hangupReason = hangupReason; + stopAllMedia(self); + if (self.peerConn && + (hangupParty === "local" || self.peerConn.signalingState != 'closed')) { + self.peerConn.close(); + } + if (shouldEmit) { + self.emit("onHangup", self); + } +}; + var stopAllMedia = function(self) { if (self.localAVStream) { forAllTracksOnStream(self.localAVStream, function(t) { @@ -780,9 +757,19 @@ module.exports.MatrixCall = MatrixCall; */ module.exports.createNewMatrixCall = function(client, roomId) { var w = global.window; + var doc = global.document; var webRtc = {}; webRtc.isOpenWebRTC = function() { - // TODO + var scripts = doc.getElementById("script"); + if (!scripts || !scripts.length) { + return false; + } + for (var i = 0; i < scripts.length; i++) { + if (scripts[i].src.indexOf("owr.js") > -1) { + return true; + } + } + return false; }; var getUserMedia = ( w.navigator.getUserMedia || w.navigator.webkitGetUserMedia ||