Merge remote-tracking branch 'upstream/lib-jitsi-meet' into move-dtmf
This commit is contained in:
commit
822860ae22
|
@ -3,13 +3,13 @@
|
|||
var logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||
var RTC = require("./modules/RTC/RTC");
|
||||
var XMPPEvents = require("./service/xmpp/XMPPEvents");
|
||||
var StreamEventTypes = require("./service/RTC/StreamEventTypes");
|
||||
var RTCEvents = require("./service/RTC/RTCEvents");
|
||||
var EventEmitter = require("events");
|
||||
var JitsiConferenceEvents = require("./JitsiConferenceEvents");
|
||||
var JitsiParticipant = require("./JitsiParticipant");
|
||||
var Statistics = require("./modules/statistics/statistics");
|
||||
var JitsiDTMFManager = require('./modules/DTMF/JitsiDTMFManager');
|
||||
var JitsiTrackEvents = require("./JitsiTrackEvents");
|
||||
|
||||
/**
|
||||
* Creates a JitsiConference object with the given name and properties.
|
||||
|
@ -33,7 +33,7 @@ function JitsiConference(options) {
|
|||
this.room = this.xmpp.createRoom(this.options.name, null, null, this.options.config);
|
||||
this.room.updateDeviceAvailability(RTC.getDeviceAvailability());
|
||||
this.rtc = new RTC(this.room, options);
|
||||
if(!options.config.disableAudioLevels)
|
||||
if(!RTC.options.disableAudioLevels)
|
||||
this.statistics = new Statistics();
|
||||
setupListeners(this);
|
||||
this.participants = {};
|
||||
|
@ -102,7 +102,8 @@ JitsiConference.prototype.addEventListener = JitsiConference.prototype.on;
|
|||
JitsiConference.prototype.removeEventListener = JitsiConference.prototype.off;
|
||||
|
||||
/**
|
||||
* Receives notifications from another participants for commands / custom events(send by sendPresenceCommand method).
|
||||
* Receives notifications from another participants for commands / custom events
|
||||
* (send by sendPresenceCommand method).
|
||||
* @param command {String} the name of the command
|
||||
* @param handler {Function} handler for the command
|
||||
*/
|
||||
|
@ -168,11 +169,7 @@ JitsiConference.prototype.removeCommand = function (name) {
|
|||
*/
|
||||
JitsiConference.prototype.setDisplayName = function(name) {
|
||||
if(this.room){
|
||||
this.room.addToPresence("nick", {
|
||||
attributes: {
|
||||
xmlns: 'http://jabber.org/protocol/nick'
|
||||
}, value: name
|
||||
});
|
||||
this.room.addToPresence("nick", {attributes: {xmlns: 'http://jabber.org/protocol/nick'}, value: name});
|
||||
this.room.sendPresence();
|
||||
}
|
||||
};
|
||||
|
@ -182,8 +179,42 @@ JitsiConference.prototype.setDisplayName = function(name) {
|
|||
* @param track the JitsiLocalTrack object.
|
||||
*/
|
||||
JitsiConference.prototype.addTrack = function (track) {
|
||||
this.rtc.addLocalStream(track);
|
||||
this.room.addStream(track.getOriginalStream(), function () {});
|
||||
this.room.addStream(track.getOriginalStream(), function () {
|
||||
this.rtc.addLocalStream(track);
|
||||
var muteHandler = this._fireMuteChangeEvent.bind(this, track);
|
||||
var stopHandler = this.removeTrack.bind(this, track);
|
||||
var audioLevelHandler = this._fireAudioLevelChangeEvent.bind(this);
|
||||
track.addEventListener(JitsiTrackEvents.TRACK_MUTE_CHANGED, muteHandler);
|
||||
track.addEventListener(JitsiTrackEvents.TRACK_STOPPED, stopHandler);
|
||||
track.addEventListener(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED, audioLevelHandler);
|
||||
this.addEventListener(JitsiConferenceEvents.TRACK_REMOVED, function (someTrack) {
|
||||
if (someTrack !== track) {
|
||||
return;
|
||||
}
|
||||
track.removeEventListener(JitsiTrackEvents.TRACK_MUTE_CHANGED, muteHandler);
|
||||
track.removeEventListener(JitsiTrackEvents.TRACK_STOPPED, stopHandler);
|
||||
track.removeEventListener(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED, audioLevelHandler);
|
||||
});
|
||||
this.eventEmitter.emit(JitsiConferenceEvents.TRACK_ADDED, track);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
* Fires TRACK_AUDIO_LEVEL_CHANGED change conference event.
|
||||
* @param audioLevel the audio level
|
||||
*/
|
||||
JitsiConference.prototype._fireAudioLevelChangeEvent = function (audioLevel) {
|
||||
this.eventEmitter.emit(
|
||||
JitsiConferenceEvents.TRACK_AUDIO_LEVEL_CHANGED,
|
||||
this.myUserId(), audioLevel);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fires TRACK_MUTE_CHANGED change conference event.
|
||||
* @param track the JitsiTrack object related to the event.
|
||||
*/
|
||||
JitsiConference.prototype._fireMuteChangeEvent = function (track) {
|
||||
this.eventEmitter.emit(JitsiConferenceEvents.TRACK_MUTE_CHANGED, track);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -191,8 +222,10 @@ JitsiConference.prototype.addTrack = function (track) {
|
|||
* @param track the JitsiLocalTrack object.
|
||||
*/
|
||||
JitsiConference.prototype.removeTrack = function (track) {
|
||||
this.room.removeStream(track.getOriginalStream());
|
||||
this.rtc.removeLocalStream(track);
|
||||
this.room.removeStream(track.getOriginalStream(), function(){
|
||||
this.rtc.removeLocalStream(track);
|
||||
this.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, track);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -289,22 +322,41 @@ JitsiConference.prototype.onDisplayNameChanged = function (jid, displayName) {
|
|||
this.eventEmitter.emit(JitsiConferenceEvents.DISPLAY_NAME_CHANGED, id, displayName);
|
||||
};
|
||||
|
||||
|
||||
JitsiConference.prototype.onTrackAdded = function (track) {
|
||||
var id = track.getParticipantId();
|
||||
var participant = this.getParticipantById(id);
|
||||
participant._tracks.push(track);
|
||||
this.eventEmitter.emit(JitsiConferenceEvents.TRACK_ADDED, track);
|
||||
};
|
||||
|
||||
JitsiConference.prototype.onTrackRemoved = function (track) {
|
||||
var id = track.getParticipantId();
|
||||
var participant = this.getParticipantById(id);
|
||||
var pos = participant._tracks.indexOf(track);
|
||||
if (pos > -1) {
|
||||
participant._tracks.splice(pos, 1);
|
||||
if (!participant) {
|
||||
return;
|
||||
}
|
||||
this.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, track);
|
||||
// add track to JitsiParticipant
|
||||
participant._tracks.push(track);
|
||||
|
||||
var emitter = this.eventEmitter;
|
||||
track.addEventListener(
|
||||
JitsiTrackEvents.TRACK_STOPPED,
|
||||
function () {
|
||||
// remove track from JitsiParticipant
|
||||
var pos = participant._tracks.indexOf(track);
|
||||
if (pos > -1) {
|
||||
participant._tracks.splice(pos, 1);
|
||||
}
|
||||
emitter.emit(JitsiConferenceEvents.TRACK_REMOVED, track);
|
||||
}
|
||||
);
|
||||
track.addEventListener(
|
||||
JitsiTrackEvents.TRACK_MUTE_CHANGED,
|
||||
function () {
|
||||
emitter.emit(JitsiConferenceEvents.TRACK_MUTE_CHANGED, track);
|
||||
}
|
||||
);
|
||||
track.addEventListener(
|
||||
JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
|
||||
function (audioLevel) {
|
||||
emitter.emit(JitsiConferenceEvents.TRACK_AUDIO_LEVEL_CHANGED, id, audioLevel);
|
||||
}
|
||||
);
|
||||
|
||||
this.eventEmitter.emit(JitsiConferenceEvents.TRACK_ADDED, track);
|
||||
};
|
||||
|
||||
JitsiConference.prototype.updateDTMFSupport = function () {
|
||||
|
@ -372,8 +424,15 @@ function setupListeners(conference) {
|
|||
if(conference.statistics)
|
||||
conference.statistics.startRemoteStats(event.peerconnection);
|
||||
});
|
||||
|
||||
conference.room.addListener(XMPPEvents.REMOTE_STREAM_RECEIVED,
|
||||
conference.rtc.createRemoteStream.bind(conference.rtc));
|
||||
function (data, sid, thessrc) {
|
||||
var track = conference.rtc.createRemoteStream(data, sid, thessrc);
|
||||
if (track) {
|
||||
conference.onTrackAdded(track);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
conference.room.addListener(XMPPEvents.MUC_JOINED, function () {
|
||||
conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_JOINED);
|
||||
|
@ -404,24 +463,6 @@ function setupListeners(conference) {
|
|||
conference.eventEmitter.emit(JitsiConferenceEvents.SETUP_FAILED);
|
||||
});
|
||||
|
||||
conference.rtc.addListener(
|
||||
StreamEventTypes.EVENT_TYPE_REMOTE_CREATED, conference.onTrackAdded.bind(conference)
|
||||
);
|
||||
|
||||
//FIXME: Maybe remove event should not be associated with the conference.
|
||||
conference.rtc.addListener(
|
||||
StreamEventTypes.EVENT_TYPE_REMOTE_ENDED, conference.onTrackRemoved.bind(conference)
|
||||
);
|
||||
//FIXME: Maybe remove event should not be associated with the conference.
|
||||
conference.rtc.addListener(StreamEventTypes.EVENT_TYPE_LOCAL_ENDED, function (stream) {
|
||||
conference.removeTrack(stream);
|
||||
conference.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, stream);
|
||||
});
|
||||
|
||||
conference.rtc.addListener(StreamEventTypes.TRACK_MUTE_CHANGED, function (track) {
|
||||
conference.eventEmitter.emit(JitsiConferenceEvents.TRACK_MUTE_CHANGED, track);
|
||||
});
|
||||
|
||||
conference.rtc.addListener(RTCEvents.DOMINANTSPEAKER_CHANGED, function (id) {
|
||||
if(conference.lastActiveSpeaker !== id && conference.room) {
|
||||
conference.lastActiveSpeaker = id;
|
||||
|
@ -443,20 +484,11 @@ function setupListeners(conference) {
|
|||
//FIXME: Maybe remove event should not be associated with the conference.
|
||||
conference.statistics.addAudioLevelListener(function (ssrc, level) {
|
||||
var userId = null;
|
||||
if (ssrc === Statistics.LOCAL_JID) {
|
||||
userId = conference.myUserId();
|
||||
} else {
|
||||
var jid = conference.room.getJidBySSRC(ssrc);
|
||||
if (!jid)
|
||||
return;
|
||||
var jid = conference.room.getJidBySSRC(ssrc);
|
||||
if (!jid)
|
||||
return;
|
||||
|
||||
userId = Strophe.getResourceFromJid(jid);
|
||||
}
|
||||
conference.eventEmitter.emit(JitsiConferenceEvents.TRACK_AUDIO_LEVEL_CHANGED,
|
||||
userId, level);
|
||||
});
|
||||
conference.rtc.addListener(StreamEventTypes.EVENT_TYPE_LOCAL_CREATED, function (stream) {
|
||||
conference.statistics.startLocalStats(stream);
|
||||
conference.rtc.setAudioLevel(jid, level);
|
||||
});
|
||||
conference.xmpp.addListener(XMPPEvents.DISPOSE_CONFERENCE,
|
||||
function () {
|
||||
|
|
|
@ -7,6 +7,7 @@ var JitsiTrackEvents = require("./JitsiTrackEvents");
|
|||
var JitsiTrackErrors = require("./JitsiTrackErrors");
|
||||
var Logger = require("jitsi-meet-logger");
|
||||
var RTC = require("./modules/RTC/RTC");
|
||||
var Statistics = require("./modules/statistics/statistics");
|
||||
|
||||
/**
|
||||
* Namespace for the interface of Jitsi Meet Library.
|
||||
|
@ -42,11 +43,29 @@ var LibJitsiMeet = {
|
|||
* will be returned trough the Promise, otherwise JitsiTrack objects will be returned.
|
||||
* @param {string} options.cameraDeviceId
|
||||
* @param {string} options.micDeviceId
|
||||
* @returns {Promise.<{Array.<JitsiTrack>}, JitsiConferenceError>} A promise that returns an array of created JitsiTracks if resolved,
|
||||
* @returns {Promise.<{Array.<JitsiTrack>}, JitsiConferenceError>}
|
||||
* A promise that returns an array of created JitsiTracks if resolved,
|
||||
* or a JitsiConferenceError if rejected.
|
||||
*/
|
||||
createLocalTracks: function (options) {
|
||||
return RTC.obtainAudioAndVideoPermissions(options || {});
|
||||
return RTC.obtainAudioAndVideoPermissions(options || {}).then(
|
||||
function(tracks) {
|
||||
if(!RTC.options.disableAudioLevels)
|
||||
for(var i = 0; i < tracks.length; i++) {
|
||||
var track = tracks[i];
|
||||
var mStream = track.getOriginalStream();
|
||||
if(track.getType() === "audio"){
|
||||
Statistics.startLocalStats(mStream,
|
||||
track.setAudioLevel.bind(track));
|
||||
track.addEventListener(
|
||||
JitsiTrackEvents.TRACK_STOPPED,
|
||||
function(){
|
||||
Statistics.stopLocalStats(mStream);
|
||||
});
|
||||
}
|
||||
}
|
||||
return tracks;
|
||||
});
|
||||
},
|
||||
isDeviceListAvailable: function () {
|
||||
return RTC.isDeviceListAvailable();
|
||||
|
|
|
@ -10,7 +10,7 @@ var JitsiTrackEvents = {
|
|||
/**
|
||||
* The media track was removed to the conference.
|
||||
*/
|
||||
TRACK_STOPPED: "track.TRACK_STOPPED",
|
||||
TRACK_STOPPED: "track.stopped"
|
||||
};
|
||||
|
||||
module.exports = JitsiTrackEvents;
|
||||
|
|
|
@ -9,8 +9,7 @@ var options = {
|
|||
}
|
||||
|
||||
var confOptions = {
|
||||
openSctp: true,
|
||||
disableAudioLevels: true
|
||||
openSctp: true
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,6 +21,18 @@ function onLocalTracks(tracks)
|
|||
localTracks = tracks;
|
||||
for(var i = 0; i < localTracks.length; i++)
|
||||
{
|
||||
localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,
|
||||
function (audioLevel) {
|
||||
console.debug("Audio Level local: " + audioLevel);
|
||||
});
|
||||
localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
|
||||
function () {
|
||||
console.debug("local track muted");
|
||||
});
|
||||
localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_STOPPED,
|
||||
function () {
|
||||
console.debug("local track stoped");
|
||||
});
|
||||
if(localTracks[i].getType() == "video") {
|
||||
$("body").append("<video autoplay='1' id='localVideo" + i + "' />");
|
||||
localTracks[i].attach($("#localVideo" + i ));
|
||||
|
@ -29,7 +40,6 @@ function onLocalTracks(tracks)
|
|||
$("body").append("<audio autoplay='1' id='localAudio" + i + "' />");
|
||||
localTracks[i].attach($("#localAudio" + i ));
|
||||
}
|
||||
console.log(localTracks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,10 +48,24 @@ function onLocalTracks(tracks)
|
|||
* @param track JitsiTrack object
|
||||
*/
|
||||
function onRemoteTrack(track) {
|
||||
if(track.isLocal())
|
||||
return;
|
||||
var participant = track.getParticipantId();
|
||||
if(!remoteTracks[participant])
|
||||
remoteTracks[participant] = [];
|
||||
var idx = remoteTracks[participant].push(track);
|
||||
track.addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,
|
||||
function (audioLevel) {
|
||||
console.debug("Audio Level remote: " + audioLevel);
|
||||
});
|
||||
track.addEventListener(JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
|
||||
function () {
|
||||
console.debug("remote track muted");
|
||||
});
|
||||
track.addEventListener(JitsiMeetJS.events.track.TRACK_STOPPED,
|
||||
function () {
|
||||
console.debug("remote track stoped");
|
||||
});
|
||||
var id = participant + track.getType() + idx;
|
||||
if(track.getType() == "video") {
|
||||
$("body").append("<video autoplay='1' id='" + participant + "video" + idx + "' />");
|
||||
|
@ -74,8 +98,8 @@ function onUserLeft(id) {
|
|||
function onConnectionSuccess(){
|
||||
room = connection.initJitsiConference("conference2", confOptions);
|
||||
room.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
|
||||
room.on(JitsiMeetJS.events.conference.TRACK_REMOVED, function () {
|
||||
console.debug("track removed!!!");
|
||||
room.on(JitsiMeetJS.events.conference.TRACK_REMOVED, function (track) {
|
||||
console.debug("track removed!!!" + track);
|
||||
});
|
||||
room.on(JitsiMeetJS.events.conference.CONFERENCE_JOINED, onConferenceJoined);
|
||||
room.on(JitsiMeetJS.events.conference.USER_JOINED, function(id){ remoteTracks[id] = [];});
|
||||
|
@ -88,7 +112,7 @@ function onConnectionSuccess(){
|
|||
});
|
||||
room.on(JitsiMeetJS.events.conference.TRACK_AUDIO_LEVEL_CHANGED,
|
||||
function(userID, audioLevel){
|
||||
// console.log(userID + " - " + audioLevel);
|
||||
console.log(userID + " - " + audioLevel);
|
||||
});
|
||||
room.join();
|
||||
};
|
||||
|
@ -120,6 +144,7 @@ $(window).bind('unload', unload);
|
|||
|
||||
// JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.ERROR);
|
||||
var initOptions = {
|
||||
// disableAudioLevels: true,
|
||||
// Desktop sharing method. Can be set to 'ext', 'webrtc' or false to disable.
|
||||
desktopSharingChromeMethod: 'ext',
|
||||
// The ID of the jidesha extension for Chrome.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
var JitsiTrack = require("./JitsiTrack");
|
||||
var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
|
||||
var RTCBrowserType = require("./RTCBrowserType");
|
||||
var JitsiTrackEvents = require('../../JitsiTrackEvents');
|
||||
var RTC = require("./RTCUtils");
|
||||
|
||||
/**
|
||||
|
@ -13,14 +13,15 @@ function JitsiLocalTrack(stream, videoType,
|
|||
this.videoType = videoType;
|
||||
this.dontFireRemoveEvent = false;
|
||||
this.resolution = resolution;
|
||||
this.startMuted = false;
|
||||
var self = this;
|
||||
JitsiTrack.call(this, null, stream,
|
||||
function () {
|
||||
if(!self.dontFireRemoveEvent && self.rtc)
|
||||
self.rtc.eventEmitter.emit(
|
||||
StreamEventTypes.EVENT_TYPE_LOCAL_ENDED, self);
|
||||
self.dontFireRemoveEvent = false;
|
||||
});
|
||||
if(!this.dontFireRemoveEvent)
|
||||
this.eventEmitter.emit(
|
||||
JitsiTrackEvents.TRACK_STOPPED);
|
||||
this.dontFireRemoveEvent = false;
|
||||
}.bind(this));
|
||||
|
||||
}
|
||||
|
||||
|
@ -33,14 +34,14 @@ JitsiLocalTrack.prototype.constructor = JitsiLocalTrack;
|
|||
*/
|
||||
JitsiLocalTrack.prototype._setMute = function (mute) {
|
||||
if(!this.rtc) {
|
||||
console.error("Mute is not supported for streams not attached to conference!");
|
||||
this.startMuted = mute;
|
||||
return;
|
||||
}
|
||||
var isAudio = this.type === JitsiTrack.AUDIO;
|
||||
this.dontFireRemoveEvent = false;
|
||||
|
||||
if ((window.location.protocol != "https:") ||
|
||||
(isAudio) || this.videoType === "screen" ||
|
||||
(isAudio) || this.videoType === "desktop" ||
|
||||
// FIXME FF does not support 'removeStream' method used to mute
|
||||
RTCBrowserType.isFirefox()) {
|
||||
|
||||
|
@ -52,7 +53,7 @@ JitsiLocalTrack.prototype._setMute = function (mute) {
|
|||
this.rtc.room.setAudioMute(mute);
|
||||
else
|
||||
this.rtc.room.setVideoMute(mute);
|
||||
this.rtc.eventEmitter.emit(StreamEventTypes.TRACK_MUTE_CHANGED, this);
|
||||
this.eventEmitter.emit(JitsiTrackEvents.TRACK_MUTE_CHANGED);
|
||||
} else {
|
||||
if (mute) {
|
||||
this.dontFireRemoveEvent = true;
|
||||
|
@ -63,7 +64,7 @@ JitsiLocalTrack.prototype._setMute = function (mute) {
|
|||
else
|
||||
this.rtc.room.setVideoMute(mute);
|
||||
this.stream = null;
|
||||
this.rtc.eventEmitter.emit(StreamEventTypes.TRACK_MUTE_CHANGED, this);
|
||||
this.eventEmitter.emit(JitsiTrackEvents.TRACK_MUTE_CHANGED);
|
||||
//FIXME: Maybe here we should set the SRC for the containers to something
|
||||
} else {
|
||||
var self = this;
|
||||
|
@ -95,7 +96,8 @@ JitsiLocalTrack.prototype._setMute = function (mute) {
|
|||
self.rtc.room.setAudioMute(mute);
|
||||
else
|
||||
self.rtc.room.setVideoMute(mute);
|
||||
self.rtc.eventEmitter.emit(StreamEventTypes.TRACK_MUTE_CHANGED, self);
|
||||
self.eventEmitter.emit(
|
||||
JitsiTrackEvents.TRACK_MUTE_CHANGED);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -111,7 +113,7 @@ JitsiLocalTrack.prototype.stop = function () {
|
|||
return;
|
||||
if(this.rtc)
|
||||
this.rtc.room.removeStream(this.stream);
|
||||
this.rtc.stopMediaStream(this.stream);
|
||||
RTC.stopMediaStream(this.stream);
|
||||
this.detach();
|
||||
}
|
||||
|
||||
|
@ -148,4 +150,11 @@ JitsiLocalTrack.prototype._setRTC = function (rtc) {
|
|||
this.rtc = rtc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return true;
|
||||
*/
|
||||
JitsiLocalTrack.prototype.isLocal = function () {
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = JitsiLocalTrack;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var JitsiTrack = require("./JitsiTrack");
|
||||
var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
|
||||
var JitsiTrackEvents = require("../../JitsiTrackEvents");
|
||||
|
||||
/**
|
||||
* Represents a single media track (either audio or video).
|
||||
|
@ -10,11 +10,11 @@ var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
|
|||
* @param eventEmitter the event emitter
|
||||
* @constructor
|
||||
*/
|
||||
function JitsiRemoteTrack(RTC, data, sid, ssrc, eventEmitter) {
|
||||
function JitsiRemoteTrack(RTC, data, sid, ssrc) {
|
||||
JitsiTrack.call(this, RTC, data.stream,
|
||||
function () {
|
||||
eventEmitter.emit(StreamEventTypes.EVENT_TYPE_REMOTE_ENDED, self);
|
||||
});
|
||||
this.eventEmitter.emit(JitsiTrackEvents.TRACK_STOPPED);
|
||||
}.bind(this));
|
||||
this.rtc = RTC;
|
||||
this.sid = sid;
|
||||
this.stream = data.stream;
|
||||
|
@ -24,10 +24,8 @@ function JitsiRemoteTrack(RTC, data, sid, ssrc, eventEmitter) {
|
|||
this.muted = false;
|
||||
if((this.type === JitsiTrack.AUDIO && data.audiomuted)
|
||||
|| (this.type === JitsiTrack.VIDEO && data.videomuted)) {
|
||||
this.muted = true
|
||||
this.muted = true;
|
||||
}
|
||||
this.eventEmitter = eventEmitter;
|
||||
var self = this;
|
||||
}
|
||||
|
||||
JitsiRemoteTrack.prototype = Object.create(JitsiTrack.prototype);
|
||||
|
@ -40,7 +38,7 @@ JitsiRemoteTrack.prototype.constructor = JitsiRemoteTrack;
|
|||
JitsiRemoteTrack.prototype.setMute = function (value) {
|
||||
this.stream.muted = value;
|
||||
this.muted = value;
|
||||
this.eventEmitter.emit(StreamEventTypes.TRACK_MUTE_CHANGED, this);
|
||||
this.eventEmitter.emit(JitsiTrackEvents.TRACK_MUTE_CHANGED);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -59,6 +57,13 @@ JitsiRemoteTrack.prototype.getParticipantId = function() {
|
|||
return Strophe.getResourceFromJid(this.peerjid);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return false;
|
||||
*/
|
||||
JitsiRemoteTrack.prototype.isLocal = function () {
|
||||
return false;
|
||||
}
|
||||
|
||||
delete JitsiRemoteTrack.prototype.stop;
|
||||
|
||||
delete JitsiRemoteTrack.prototype.start;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
var RTCBrowserType = require("./RTCBrowserType");
|
||||
var JitsiTrackEvents = require("../../JitsiTrackEvents");
|
||||
var EventEmitter = require("events");
|
||||
|
||||
/**
|
||||
* This implements 'onended' callback normally fired by WebRTC after the stream
|
||||
|
@ -54,6 +56,8 @@ function JitsiTrack(rtc, stream, streamInactiveHandler)
|
|||
this.containers = [];
|
||||
this.rtc = rtc;
|
||||
this.stream = stream;
|
||||
this.eventEmitter = new EventEmitter();
|
||||
this.audioLevel = -1;
|
||||
this.type = (this.stream.getVideoTracks().length > 0)?
|
||||
JitsiTrack.VIDEO : JitsiTrack.AUDIO;
|
||||
if(this.type == "audio") {
|
||||
|
@ -198,5 +202,42 @@ JitsiTrack.prototype.isActive = function () {
|
|||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attaches a handler for events(For example - "audio level changed".).
|
||||
* All possible event are defined in JitsiTrackEvents.
|
||||
* @param eventId the event ID.
|
||||
* @param handler handler for the event.
|
||||
*/
|
||||
JitsiTrack.prototype.on = function (eventId, handler) {
|
||||
if(this.eventEmitter)
|
||||
this.eventEmitter.on(eventId, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes event listener
|
||||
* @param eventId the event ID.
|
||||
* @param [handler] optional, the specific handler to unbind
|
||||
*/
|
||||
JitsiTrack.prototype.off = function (eventId, handler) {
|
||||
if(this.eventEmitter)
|
||||
this.eventEmitter.removeListener(eventId, handler);
|
||||
}
|
||||
|
||||
// Common aliases for event emitter
|
||||
JitsiTrack.prototype.addEventListener = JitsiTrack.prototype.on;
|
||||
JitsiTrack.prototype.removeEventListener = JitsiTrack.prototype.off;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the audio level for the stream
|
||||
* @param audioLevel the new audio level
|
||||
*/
|
||||
JitsiTrack.prototype.setAudioLevel = function (audioLevel) {
|
||||
if(this.audioLevel !== audioLevel) {
|
||||
this.eventEmitter.emit(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
|
||||
audioLevel);
|
||||
this.audioLevel = audioLevel;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = JitsiTrack;
|
||||
|
|
|
@ -9,7 +9,6 @@ var JitsiRemoteTrack = require("./JitsiRemoteTrack.js");
|
|||
var DesktopSharingEventTypes
|
||||
= require("../../service/desktopsharing/DesktopSharingEventTypes");
|
||||
var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
|
||||
var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
|
||||
var RTCEvents = require("../../service/RTC/RTCEvents.js");
|
||||
|
||||
function createLocalTracks(streams) {
|
||||
|
@ -20,10 +19,6 @@ function createLocalTracks(streams) {
|
|||
newStreams.push(localStream);
|
||||
if (streams[i].isMuted === true)
|
||||
localStream.setMute(true);
|
||||
//FIXME:
|
||||
// var eventType = StreamEventTypes.EVENT_TYPE_LOCAL_CREATED;
|
||||
//
|
||||
// eventEmitter.emit(eventType, localStream);
|
||||
}
|
||||
return newStreams;
|
||||
}
|
||||
|
@ -31,6 +26,8 @@ function createLocalTracks(streams) {
|
|||
function RTC(room, options) {
|
||||
this.room = room;
|
||||
this.localStreams = [];
|
||||
//FIXME: we should start removing those streams.
|
||||
//FIXME: We should support multiple streams per jid.
|
||||
this.remoteStreams = {};
|
||||
this.localAudio = null;
|
||||
this.localVideo = null;
|
||||
|
@ -38,12 +35,14 @@ function RTC(room, options) {
|
|||
var self = this;
|
||||
this.options = options || {};
|
||||
room.addPresenceListener("videomuted", function (values, from) {
|
||||
if(self.remoteStreams[from])
|
||||
if(self.remoteStreams[from]) {
|
||||
self.remoteStreams[from][JitsiTrack.VIDEO].setMute(values.value == "true");
|
||||
}
|
||||
});
|
||||
room.addPresenceListener("audiomuted", function (values, from) {
|
||||
if(self.remoteStreams[from])
|
||||
if(self.remoteStreams[from]) {
|
||||
self.remoteStreams[from][JitsiTrack.AUDIO].setMute(values.value == "true");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -104,7 +103,8 @@ RTC.isRTCReady = function () {
|
|||
}
|
||||
|
||||
RTC.init = function (options) {
|
||||
return RTCUtils.init(options || {});
|
||||
this.options = options || {};
|
||||
return RTCUtils.init(this.options);
|
||||
}
|
||||
|
||||
RTC.getDeviceAvailability = function () {
|
||||
|
@ -132,8 +132,7 @@ RTC.prototype.removeLocalStream = function (stream) {
|
|||
};
|
||||
|
||||
RTC.prototype.createRemoteStream = function (data, sid, thessrc) {
|
||||
var remoteStream = new JitsiRemoteTrack(this, data, sid, thessrc,
|
||||
this.eventEmitter);
|
||||
var remoteStream = new JitsiRemoteTrack(this, data, sid, thessrc);
|
||||
if(!data.peerjid)
|
||||
return;
|
||||
var jid = data.peerjid;
|
||||
|
@ -141,7 +140,6 @@ RTC.prototype.createRemoteStream = function (data, sid, thessrc) {
|
|||
this.remoteStreams[jid] = {};
|
||||
}
|
||||
this.remoteStreams[jid][remoteStream.type]= remoteStream;
|
||||
this.eventEmitter.emit(StreamEventTypes.EVENT_TYPE_REMOTE_CREATED, remoteStream);
|
||||
return remoteStream;
|
||||
};
|
||||
|
||||
|
@ -193,24 +191,6 @@ RTC.prototype.getVideoElementName = function () {
|
|||
RTC.prototype.dispose = function() {
|
||||
};
|
||||
|
||||
RTC.prototype.muteRemoteVideoStream = function (jid, value) {
|
||||
var stream;
|
||||
|
||||
if(this.remoteStreams[jid] &&
|
||||
this.remoteStreams[jid][MediaStreamType.VIDEO_TYPE]) {
|
||||
stream = this.remoteStreams[jid][MediaStreamType.VIDEO_TYPE];
|
||||
}
|
||||
|
||||
if(!stream)
|
||||
return true;
|
||||
|
||||
if (value != stream.muted) {
|
||||
stream.setMute(value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
RTC.prototype.switchVideoStreams = function (newStream) {
|
||||
this.localVideo.stream = newStream;
|
||||
|
||||
|
@ -222,37 +202,8 @@ RTC.prototype.switchVideoStreams = function (newStream) {
|
|||
this.localStreams.push(this.localVideo);
|
||||
};
|
||||
|
||||
RTC.prototype.isVideoMuted = function (jid) {
|
||||
if (jid === APP.xmpp.myJid()) {
|
||||
var localVideo = APP.RTC.localVideo;
|
||||
return (!localVideo || localVideo.isMuted());
|
||||
} else {
|
||||
if (!this.remoteStreams[jid] ||
|
||||
!this.remoteStreams[jid][MediaStreamType.VIDEO_TYPE]) {
|
||||
return null;
|
||||
}
|
||||
return this.remoteStreams[jid][MediaStreamType.VIDEO_TYPE].muted;
|
||||
}
|
||||
};
|
||||
|
||||
RTC.prototype.setVideoMute = function (mute, callback, options) {
|
||||
if (!this.localVideo)
|
||||
return;
|
||||
|
||||
if (mute == this.localVideo.isMuted())
|
||||
{
|
||||
APP.xmpp.sendVideoInfoPresence(mute);
|
||||
if (callback)
|
||||
callback(mute);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.localVideo.setMute(mute);
|
||||
this.room.setVideoMute(
|
||||
mute,
|
||||
callback,
|
||||
options);
|
||||
}
|
||||
};
|
||||
|
||||
RTC.prototype.setAudioLevel = function (jid, audioLevel) {
|
||||
if(this.remoteStreams[jid] && this.remoteStreams[jid][JitsiTrack.AUDIO])
|
||||
this.remoteStreams[jid][JitsiTrack.AUDIO].setAudioLevel(audioLevel);
|
||||
}
|
||||
module.exports = RTC;
|
||||
|
|
|
@ -4,9 +4,6 @@
|
|||
*/
|
||||
|
||||
var RTCBrowserType = require('../RTC/RTCBrowserType');
|
||||
var StatisticsEvents = require('../../service/statistics/Events');
|
||||
|
||||
var LOCAL_JID = require("../../service/statistics/constants").LOCAL_JID;
|
||||
|
||||
/**
|
||||
* Size of the webaudio analyzer buffer.
|
||||
|
@ -67,16 +64,16 @@ function animateLevel(newLevel, lastLevel) {
|
|||
*
|
||||
* @param stream the local stream
|
||||
* @param interval stats refresh interval given in ms.
|
||||
* @param callback function that receives the audio levels.
|
||||
* @constructor
|
||||
*/
|
||||
function LocalStatsCollector(stream, interval, statisticsService, eventEmitter) {
|
||||
function LocalStatsCollector(stream, interval, callback) {
|
||||
window.AudioContext = window.AudioContext || window.webkitAudioContext;
|
||||
this.stream = stream;
|
||||
this.intervalId = null;
|
||||
this.intervalMilis = interval;
|
||||
this.eventEmitter = eventEmitter;
|
||||
this.audioLevel = 0;
|
||||
this.statisticsService = statisticsService;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,10 +103,7 @@ LocalStatsCollector.prototype.start = function () {
|
|||
var audioLevel = timeDomainDataToAudioLevel(array);
|
||||
if (audioLevel != self.audioLevel) {
|
||||
self.audioLevel = animateLevel(audioLevel, self.audioLevel);
|
||||
self.eventEmitter.emit(
|
||||
StatisticsEvents.AUDIO_LEVEL,
|
||||
self.statisticsService.LOCAL_JID,
|
||||
self.audioLevel);
|
||||
self.callback(self.audioLevel);
|
||||
}
|
||||
},
|
||||
this.intervalMilis
|
||||
|
@ -126,4 +120,4 @@ LocalStatsCollector.prototype.stop = function () {
|
|||
}
|
||||
};
|
||||
|
||||
module.exports = LocalStatsCollector;
|
||||
module.exports = LocalStatsCollector;
|
||||
|
|
|
@ -18,8 +18,9 @@ var StatisticsEvents = require("../../service/statistics/Events");
|
|||
// }
|
||||
//}
|
||||
|
||||
var eventEmitter = new EventEmitter();
|
||||
|
||||
function Statistics() {
|
||||
this.localStats = null;
|
||||
this.rtpStats = null;
|
||||
this.eventEmitter = new EventEmitter();
|
||||
}
|
||||
|
@ -33,14 +34,13 @@ Statistics.prototype.startRemoteStats = function (peerconnection) {
|
|||
this.rtpStats.start();
|
||||
}
|
||||
|
||||
Statistics.prototype.startLocalStats = function (stream) {
|
||||
if(stream.getType() !== "audio")
|
||||
return;
|
||||
this.localStats = new LocalStats(stream.getOriginalStream(), 200, this,
|
||||
this.eventEmitter);
|
||||
this.localStats.start();
|
||||
}
|
||||
Statistics.localStats = [];
|
||||
|
||||
Statistics.startLocalStats = function (stream, callback) {
|
||||
var localStats = new LocalStats(stream, 200, callback);
|
||||
this.localStats.push(localStats);
|
||||
localStats.start();
|
||||
}
|
||||
|
||||
Statistics.prototype.addAudioLevelListener = function(listener)
|
||||
{
|
||||
|
@ -53,20 +53,29 @@ Statistics.prototype.removeAudioLevelListener = function(listener)
|
|||
}
|
||||
|
||||
Statistics.prototype.dispose = function () {
|
||||
this.stopLocal();
|
||||
Statistics.stopAllLocalStats();
|
||||
this.stopRemote();
|
||||
if(this.eventEmitter)
|
||||
{
|
||||
this.eventEmitter.removeAllListeners();
|
||||
}
|
||||
|
||||
if(eventEmitter)
|
||||
eventEmitter.removeAllListeners();
|
||||
}
|
||||
|
||||
|
||||
Statistics.prototype.stopLocal = function () {
|
||||
if (this.localStats) {
|
||||
this.localStats.stop();
|
||||
this.localStats = null;
|
||||
}
|
||||
Statistics.stopAllLocalStats = function () {
|
||||
for(var i = 0; i < this.localStats.length; i++)
|
||||
this.localStats[i].stop();
|
||||
this.localStats = [];
|
||||
}
|
||||
|
||||
Statistics.stopLocalStats = function (stream) {
|
||||
for(var i = 0; i < Statistics.localStats.length; i++)
|
||||
if(Statistics.localStats[i].stream === stream){
|
||||
var localStats = Statistics.localStats.splice(i, 1);
|
||||
localStats.stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Statistics.prototype.stopRemote = function () {
|
||||
|
@ -144,4 +153,4 @@ Statistics.LOCAL_JID = require("../../service/statistics/constants").LOCAL_JID;
|
|||
|
||||
|
||||
|
||||
module.exports = Statistics;
|
||||
module.exports = Statistics;
|
||||
|
|
|
@ -515,10 +515,10 @@ ChatRoom.prototype.setJingleSession = function(session){
|
|||
};
|
||||
|
||||
|
||||
ChatRoom.prototype.removeStream = function (stream) {
|
||||
ChatRoom.prototype.removeStream = function (stream, callback) {
|
||||
if(!this.session)
|
||||
return;
|
||||
this.session.peerconnection.removeStream(stream);
|
||||
this.session.removeStream(stream, callback);
|
||||
};
|
||||
|
||||
ChatRoom.prototype.switchStreams = function (stream, oldStream, callback, isAudio) {
|
||||
|
|
|
@ -1235,6 +1235,43 @@ JingleSessionPC.prototype.addStream = function (stream, callback) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove streams.
|
||||
* @param stream stream that will be removed.
|
||||
* @param success_callback callback executed after successful stream addition.
|
||||
*/
|
||||
JingleSessionPC.prototype.removeStream = function (stream, callback) {
|
||||
|
||||
var self = this;
|
||||
|
||||
// Remember SDP to figure out added/removed SSRCs
|
||||
var oldSdp = null;
|
||||
if(this.peerconnection) {
|
||||
if(this.peerconnection.localDescription) {
|
||||
oldSdp = new SDP(this.peerconnection.localDescription.sdp);
|
||||
}
|
||||
if(stream)
|
||||
this.peerconnection.removeStream(stream);
|
||||
}
|
||||
|
||||
// Conference is not active
|
||||
if(!oldSdp || !this.peerconnection) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
this.addingStreams = true;
|
||||
this.modifySourcesQueue.push(function() {
|
||||
logger.log('modify sources done');
|
||||
|
||||
callback();
|
||||
|
||||
var newSdp = new SDP(self.peerconnection.localDescription.sdp);
|
||||
logger.log("SDPs", oldSdp, newSdp);
|
||||
self.notifyMySSRCUpdate(oldSdp, newSdp);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Figures out added/removed ssrcs and send update IQs.
|
||||
* @param old_sdp SDP object for old description.
|
||||
|
|
|
@ -206,45 +206,49 @@ var normalizePlanB = function(desc) {
|
|||
});
|
||||
};
|
||||
|
||||
if (TraceablePeerConnection.prototype.__defineGetter__ !== undefined) {
|
||||
TraceablePeerConnection.prototype.__defineGetter__(
|
||||
'signalingState',
|
||||
function() { return this.peerconnection.signalingState; });
|
||||
TraceablePeerConnection.prototype.__defineGetter__(
|
||||
'iceConnectionState',
|
||||
function() { return this.peerconnection.iceConnectionState; });
|
||||
TraceablePeerConnection.prototype.__defineGetter__(
|
||||
'localDescription',
|
||||
function() {
|
||||
var desc = this.peerconnection.localDescription;
|
||||
var getters = {
|
||||
signalingState: function () {
|
||||
return this.peerconnection.signalingState;
|
||||
},
|
||||
iceConnectionState: function () {
|
||||
return this.peerconnection.iceConnectionState;
|
||||
},
|
||||
localDescription: function() {
|
||||
var desc = this.peerconnection.localDescription;
|
||||
|
||||
// FIXME this should probably be after the Unified Plan -> Plan B
|
||||
// transformation.
|
||||
desc = SSRCReplacement.mungeLocalVideoSSRC(desc);
|
||||
desc = SSRCReplacement.mungeLocalVideoSSRC(desc);
|
||||
|
||||
this.trace('getLocalDescription::preTransform', dumpSDP(desc));
|
||||
this.trace('getLocalDescription::preTransform', dumpSDP(desc));
|
||||
|
||||
// if we're running on FF, transform to Plan B first.
|
||||
if (RTCBrowserType.usesUnifiedPlan()) {
|
||||
desc = this.interop.toPlanB(desc);
|
||||
this.trace('getLocalDescription::postTransform (Plan B)', dumpSDP(desc));
|
||||
}
|
||||
return desc;
|
||||
});
|
||||
TraceablePeerConnection.prototype.__defineGetter__(
|
||||
'remoteDescription',
|
||||
function() {
|
||||
var desc = this.peerconnection.remoteDescription;
|
||||
this.trace('getRemoteDescription::preTransform', dumpSDP(desc));
|
||||
// if we're running on FF, transform to Plan B first.
|
||||
if (RTCBrowserType.usesUnifiedPlan()) {
|
||||
desc = this.interop.toPlanB(desc);
|
||||
this.trace('getLocalDescription::postTransform (Plan B)', dumpSDP(desc));
|
||||
}
|
||||
return desc;
|
||||
},
|
||||
remoteDescription: function() {
|
||||
var desc = this.peerconnection.remoteDescription;
|
||||
this.trace('getRemoteDescription::preTransform', dumpSDP(desc));
|
||||
|
||||
// if we're running on FF, transform to Plan B first.
|
||||
if (RTCBrowserType.usesUnifiedPlan()) {
|
||||
desc = this.interop.toPlanB(desc);
|
||||
this.trace('getRemoteDescription::postTransform (Plan B)', dumpSDP(desc));
|
||||
}
|
||||
return desc;
|
||||
});
|
||||
}
|
||||
// if we're running on FF, transform to Plan B first.
|
||||
if (RTCBrowserType.usesUnifiedPlan()) {
|
||||
desc = this.interop.toPlanB(desc);
|
||||
this.trace('getRemoteDescription::postTransform (Plan B)', dumpSDP(desc));
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
};
|
||||
Object.keys(getters).forEach(function (prop) {
|
||||
Object.defineProperty(
|
||||
TraceablePeerConnection.prototype,
|
||||
prop, {
|
||||
get: getters[prop]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
TraceablePeerConnection.prototype.addStream = function (stream) {
|
||||
this.trace('addStream', stream.id);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
var logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||
var EventEmitter = require("events");
|
||||
var Pako = require("pako");
|
||||
var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
|
||||
var RTCEvents = require("../../service/RTC/RTCEvents");
|
||||
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
|
||||
var JitsiConnectionErrors = require("../../JitsiConnectionErrors");
|
||||
|
@ -124,7 +123,7 @@ XMPP.prototype._connect = function (jid, password) {
|
|||
logger.warn("Ping NOT supported by " + pingJid);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
if (password)
|
||||
authenticatedUser = true;
|
||||
if (self.connection && self.connection.connected &&
|
||||
|
|
Loading…
Reference in New Issue