|
@@ -4,10 +4,16 @@
|
4
|
4
|
* @param sid my session identifier(resource)
|
5
|
5
|
* @constructor
|
6
|
6
|
*/
|
7
|
|
-function SessionBase(connection, sid){
|
8
|
|
-
|
|
7
|
+function SessionBase(connection, sid) {
|
9
|
8
|
this.connection = connection;
|
10
|
9
|
this.sid = sid;
|
|
10
|
+
|
|
11
|
+ /**
|
|
12
|
+ * The indicator which determines whether the (local) video has been muted
|
|
13
|
+ * in response to a user command in contrast to an automatic decision made
|
|
14
|
+ * by the application logic.
|
|
15
|
+ */
|
|
16
|
+ this.muteByUser = true;
|
11
|
17
|
}
|
12
|
18
|
|
13
|
19
|
|
|
@@ -63,6 +69,7 @@ SessionBase.prototype.removeSource = function (elem, fromJid) {
|
63
|
69
|
|
64
|
70
|
this.modifySources();
|
65
|
71
|
};
|
|
72
|
+
|
66
|
73
|
/**
|
67
|
74
|
* Switches video streams.
|
68
|
75
|
* @param new_stream new stream that will be used as video of this session.
|
|
@@ -230,20 +237,85 @@ SessionBase.prototype.sendSSRCUpdateIq = function(sdpMediaSsrcs, sid, initiator,
|
230
|
237
|
}
|
231
|
238
|
};
|
232
|
239
|
|
233
|
|
-// SDP-based mute by going recvonly/sendrecv
|
234
|
|
-// FIXME: should probably black out the screen as well
|
235
|
|
-SessionBase.prototype.toggleVideoMute = function (callback) {
|
|
240
|
+/**
|
|
241
|
+ * Determines whether the (local) video is mute i.e. all video tracks are
|
|
242
|
+ * disabled.
|
|
243
|
+ *
|
|
244
|
+ * @return <tt>true</tt> if the (local) video is mute i.e. all video tracks are
|
|
245
|
+ * disabled; otherwise, <tt>false</tt>
|
|
246
|
+ */
|
|
247
|
+SessionBase.prototype.isVideoMute = function () {
|
|
248
|
+ var tracks = connection.jingle.localVideo.getVideoTracks();
|
|
249
|
+ var mute = true;
|
|
250
|
+
|
|
251
|
+ for (var i = 0; i < tracks.length; ++i) {
|
|
252
|
+ if (tracks[i].enabled) {
|
|
253
|
+ mute = false;
|
|
254
|
+ break;
|
|
255
|
+ }
|
|
256
|
+ }
|
|
257
|
+ return mute;
|
|
258
|
+};
|
236
|
259
|
|
237
|
|
- var ismuted = false;
|
238
|
|
- var localVideo = connection.jingle.localVideo;
|
239
|
|
- for (var idx = 0; idx < localVideo.getVideoTracks().length; idx++) {
|
240
|
|
- ismuted = !localVideo.getVideoTracks()[idx].enabled;
|
|
260
|
+/**
|
|
261
|
+ * Mutes/unmutes the (local) video i.e. enables/disables all video tracks.
|
|
262
|
+ *
|
|
263
|
+ * @param mute <tt>true</tt> to mute the (local) video i.e. to disable all video
|
|
264
|
+ * tracks; otherwise, <tt>false</tt>
|
|
265
|
+ * @param callback a function to be invoked with <tt>mute</tt> after all video
|
|
266
|
+ * tracks have been enabled/disabled. The function may, optionally, return
|
|
267
|
+ * another function which is to be invoked after the whole mute/unmute operation
|
|
268
|
+ * has completed successfully.
|
|
269
|
+ * @param options an object which specifies optional arguments such as the
|
|
270
|
+ * <tt>boolean</tt> key <tt>byUser</tt> with default value <tt>true</tt> which
|
|
271
|
+ * specifies whether the method was initiated in response to a user command (in
|
|
272
|
+ * contrast to an automatic decision made by the application logic)
|
|
273
|
+ */
|
|
274
|
+SessionBase.prototype.setVideoMute = function (mute, callback, options) {
|
|
275
|
+ var byUser;
|
|
276
|
+
|
|
277
|
+ if (options) {
|
|
278
|
+ byUser = options.byUser;
|
|
279
|
+ if (typeof byUser === 'undefined') {
|
|
280
|
+ byUser = true;
|
|
281
|
+ }
|
|
282
|
+ } else {
|
|
283
|
+ byUser = true;
|
|
284
|
+ }
|
|
285
|
+ // The user's command to mute the (local) video takes precedence over any
|
|
286
|
+ // automatic decision made by the application logic.
|
|
287
|
+ if (byUser) {
|
|
288
|
+ this.muteByUser = mute;
|
|
289
|
+ } else if (this.muteByUser) {
|
|
290
|
+ return;
|
241
|
291
|
}
|
242
|
|
- for (var idx = 0; idx < localVideo.getVideoTracks().length; idx++) {
|
243
|
|
- localVideo.getVideoTracks()[idx].enabled = !localVideo.getVideoTracks()[idx].enabled;
|
|
292
|
+ if (mute == this.isVideoMute())
|
|
293
|
+ {
|
|
294
|
+ // Even if no change occurs, the specified callback is to be executed.
|
|
295
|
+ // The specified callback may, optionally, return a successCallback
|
|
296
|
+ // which is to be executed as well.
|
|
297
|
+ var successCallback = callback(mute);
|
|
298
|
+
|
|
299
|
+ if (successCallback) {
|
|
300
|
+ successCallback();
|
|
301
|
+ }
|
|
302
|
+ } else {
|
|
303
|
+ var tracks = connection.jingle.localVideo.getVideoTracks();
|
|
304
|
+
|
|
305
|
+ for (var i = 0; i < tracks.length; ++i) {
|
|
306
|
+ tracks[i].enabled = !mute;
|
|
307
|
+ }
|
|
308
|
+
|
|
309
|
+ if (this.peerconnection) {
|
|
310
|
+ this.peerconnection.hardMuteVideo(mute);
|
|
311
|
+ }
|
|
312
|
+
|
|
313
|
+ this.modifySources(callback(mute));
|
244
|
314
|
}
|
|
315
|
+};
|
245
|
316
|
|
246
|
|
- if(this.peerconnection)
|
247
|
|
- this.peerconnection.hardMuteVideo(!ismuted);
|
248
|
|
- this.modifySources(callback(!ismuted));
|
|
317
|
+// SDP-based mute by going recvonly/sendrecv
|
|
318
|
+// FIXME: should probably black out the screen as well
|
|
319
|
+SessionBase.prototype.toggleVideoMute = function (callback) {
|
|
320
|
+ setVideoMute(isVideoMute(), callback);
|
249
|
321
|
};
|