浏览代码

ref(recording): change implementation to match VideoSIPGW (#769)

* ref(recording): change implementation to match VideoSIPGW

VideoSIPGW takes in a chat room and uses instance variables
on the chat room. RecordingManager has been changed to
mirror this approach because of the case where jitsi is
deployed on a domain requiring authentication. In that
case, the initial chat room is created and fails, a
new chat room (connection) is created for authentication,
authentication is put onto the failed chat room, and the
failed chat room is used. As such, recordingManager
should not be tied to chat room creation itself but
rather tied to the first chat room.

* squash: use git mv to detect capitalization change
master
virtuacoplenny 6 年前
父节点
当前提交
5a77ba0a76
共有 5 个文件被更改,包括 67 次插入93 次删除
  1. 4
    2
      JitsiConference.js
  2. 43
    55
      modules/recording/RecordingManager.js
  3. 4
    33
      modules/xmpp/ChatRoom.js
  4. 15
    3
      modules/xmpp/ChatRoom.spec.js
  5. 1
    0
      service/xmpp/XMPPEvents.js

+ 4
- 2
JitsiConference.js 查看文件

39
 import TalkMutedDetection from './modules/TalkMutedDetection';
39
 import TalkMutedDetection from './modules/TalkMutedDetection';
40
 import Transcriber from './modules/transcription/transcriber';
40
 import Transcriber from './modules/transcription/transcriber';
41
 import VideoType from './service/RTC/VideoType';
41
 import VideoType from './service/RTC/VideoType';
42
+import RecordingManager from './modules/recording/RecordingManager';
42
 import VideoSIPGW from './modules/videosipgw/VideoSIPGW';
43
 import VideoSIPGW from './modules/videosipgw/VideoSIPGW';
43
 import * as VideoSIPGWConstants from './modules/videosipgw/VideoSIPGWConstants';
44
 import * as VideoSIPGWConstants from './modules/videosipgw/VideoSIPGWConstants';
44
 import * as XMPPEvents from './service/xmpp/XMPPEvents';
45
 import * as XMPPEvents from './service/xmpp/XMPPEvents';
200
     this.p2pJingleSession = null;
201
     this.p2pJingleSession = null;
201
 
202
 
202
     this.videoSIPGWHandler = new VideoSIPGW(this.room);
203
     this.videoSIPGWHandler = new VideoSIPGW(this.room);
204
+    this.recordingManager = new RecordingManager(this.room);
203
 }
205
 }
204
 
206
 
205
 // FIXME convert JitsiConference to ES6 - ASAP !
207
 // FIXME convert JitsiConference to ES6 - ASAP !
1752
  */
1754
  */
1753
 JitsiConference.prototype.startRecording = function(options) {
1755
 JitsiConference.prototype.startRecording = function(options) {
1754
     if (this.room) {
1756
     if (this.room) {
1755
-        return this.room.startRecording(options);
1757
+        return this.recordingManager.startRecording(options);
1756
     }
1758
     }
1757
 
1759
 
1758
     return Promise.reject(new Error('The conference is not created yet!'));
1760
     return Promise.reject(new Error('The conference is not created yet!'));
1767
  */
1769
  */
1768
 JitsiConference.prototype.stopRecording = function(sessionID) {
1770
 JitsiConference.prototype.stopRecording = function(sessionID) {
1769
     if (this.room) {
1771
     if (this.room) {
1770
-        return this.room.stopRecording(sessionID);
1772
+        return this.recordingManager.stopRecording(sessionID);
1771
     }
1773
     }
1772
 
1774
 
1773
     return Promise.reject(new Error('The conference is not created yet!'));
1775
     return Promise.reject(new Error('The conference is not created yet!'));

modules/recording/recordingManager.js → modules/recording/RecordingManager.js 查看文件

8
 const logger = getLogger(__filename);
8
 const logger = getLogger(__filename);
9
 
9
 
10
 /**
10
 /**
11
- * A singleton responsible for starting and stopping recording sessions and
12
- * emitting state updates for them.
11
+ * A class responsible for starting and stopping recording sessions and emitting
12
+ * state updates for them.
13
  */
13
  */
14
-const recordingManager = {
14
+class RecordingManager {
15
     /**
15
     /**
16
-     * All known recording sessions from the current conference.
17
-     */
18
-    _sessions: {},
19
-
20
-    /**
21
-     * Initialize recordingManager with other objects that are necessary for
22
-     * starting a recording.
16
+     * Initialize {@code RecordingManager} with other objects that are necessary
17
+     * for starting a recording.
23
      *
18
      *
24
-     * @param {Object} eventEmitter - The eventEmitter to be used for
25
-     * broadcasting recording state changes.
26
-     * @param {Object} connection - The MUC connection used for sending out
27
-     * messages regarding recording.
28
-     * @param {string} focusMucJid - The ID of the conference (MUC) the focus
29
-     * is in.
19
+     * @param {ChatRoom} chatRoom - The chat room to handle.
30
      * @returns {void}
20
      * @returns {void}
31
      */
21
      */
32
-    init(eventEmitter, connection, focusMucJid) {
33
-        this._eventEmitter = eventEmitter;
34
-        this._connection = connection;
35
-        this._focusMucJid = focusMucJid;
36
-    },
22
+    constructor(chatRoom) {
23
+        /**
24
+         * All known recording sessions from the current conference.
25
+         */
26
+        this._sessions = {};
27
+
28
+        this._chatRoom = chatRoom;
29
+
30
+        this.onPresence = this.onPresence.bind(this);
31
+
32
+        this._chatRoom.eventEmitter.addListener(
33
+            XMPPEvents.PRESENCE_RECEIVED, this.onPresence);
34
+    }
37
 
35
 
38
     /**
36
     /**
39
      * Finds an existing recording session by session ID.
37
      * Finds an existing recording session by session ID.
43
      */
41
      */
44
     getSession(sessionID) {
42
     getSession(sessionID) {
45
         return this._sessions[sessionID];
43
         return this._sessions[sessionID];
46
-    },
44
+    }
47
 
45
 
48
     /**
46
     /**
49
      * Callback to invoke to parse through a presence update to find recording
47
      * Callback to invoke to parse through a presence update to find recording
50
      * related updates (from Jibri participant doing the recording and the
48
      * related updates (from Jibri participant doing the recording and the
51
      * focus which controls recording).
49
      * focus which controls recording).
52
      *
50
      *
53
-     * @param {Node} presence - An XMPP presence update.
54
-     * @param {boolean} isHiddenDomain - Whether or not the presence update
55
-     * comes from a participant that is trusted but not visible, as would be the
56
-     * case with the Jibri recorder participant.
51
+     * @param {Object} event - The presence data from the pubsub event.
52
+     * @param {Node} event.presence - An XMPP presence update.
53
+     * @param {boolean} event.fromHiddenDomain - Whether or not the update comes
54
+     * from a participant that is trusted but not visible, as would be the case
55
+     * with the Jibri recorder participant.
57
      * @returns {void}
56
      * @returns {void}
58
      */
57
      */
59
-    onPresence(presence, isHiddenDomain) {
58
+    onPresence({ fromHiddenDomain, presence }) {
60
         if (recordingXMLUtils.isFromFocus(presence)) {
59
         if (recordingXMLUtils.isFromFocus(presence)) {
61
             this._handleFocusPresence(presence);
60
             this._handleFocusPresence(presence);
62
-        } else if (isHiddenDomain) {
61
+        } else if (fromHiddenDomain) {
63
             this._handleJibriPresence(presence);
62
             this._handleJibriPresence(presence);
64
         }
63
         }
65
-    },
66
-
67
-    /**
68
-     * Sets the currently known ID of the conference (MUC). This method exists
69
-     * in case the ID is not known at init time.
70
-     *
71
-     * @param {string} focusMucJid - The ID of the conference (MUC) the focus
72
-     * is in.
73
-     * @returns {void}
74
-     */
75
-    setFocusMucJid(focusMucJid) {
76
-        this._focusMucJid = focusMucJid;
77
-    },
64
+    }
78
 
65
 
79
     /**
66
     /**
80
      * Start a recording session.
67
      * Start a recording session.
93
     startRecording(options) {
80
     startRecording(options) {
94
         const session = new JibriSession({
81
         const session = new JibriSession({
95
             ...options,
82
             ...options,
96
-            connection: this._connection
83
+            connection: this._chatRoom.connection
97
         });
84
         });
98
 
85
 
99
         return session.start({
86
         return session.start({
100
             broadcastId: options.broadcastId,
87
             broadcastId: options.broadcastId,
101
-            focusMucJid: this._focusMucJid,
88
+            focusMucJid: this._chatRoom.focusMucJid,
102
             streamId: options.streamId
89
             streamId: options.streamId
103
         })
90
         })
104
             .then(() => {
91
             .then(() => {
118
 
105
 
119
                 return Promise.reject(error);
106
                 return Promise.reject(error);
120
             });
107
             });
121
-    },
108
+    }
122
 
109
 
123
     /**
110
     /**
124
      * Stop a recording session.
111
      * Stop a recording session.
132
         const session = this.getSession(sessionID);
119
         const session = this.getSession(sessionID);
133
 
120
 
134
         if (session) {
121
         if (session) {
135
-            return session.stop({ focusMucJid: this._focusMucJid });
122
+            return session.stop({ focusMucJid: this._chatRoom.focusMucJid });
136
         }
123
         }
137
 
124
 
138
         return Promise.reject(new Error('Could not find session'));
125
         return Promise.reject(new Error('Could not find session'));
139
-    },
126
+    }
140
 
127
 
141
     /**
128
     /**
142
      * Stores a reference to the passed in JibriSession.
129
      * Stores a reference to the passed in JibriSession.
146
      */
133
      */
147
     _addSession(session) {
134
     _addSession(session) {
148
         this._sessions[session.getID()] = session;
135
         this._sessions[session.getID()] = session;
149
-    },
136
+    }
150
 
137
 
151
     /**
138
     /**
152
      * Create a new instance of a recording session and stores a reference to
139
      * Create a new instance of a recording session and stores a reference to
159
      */
146
      */
160
     _createSession(sessionID, status, mode) {
147
     _createSession(sessionID, status, mode) {
161
         const session = new JibriSession({
148
         const session = new JibriSession({
162
-            connection: this._connection,
163
-            focusMucJid: this._focusMucJid,
149
+            connection: this._chatRoom.connection,
150
+            focusMucJid: this._chatRoom.focusMucJid,
164
             mode,
151
             mode,
165
             sessionID,
152
             sessionID,
166
             status
153
             status
169
         this._addSession(session);
156
         this._addSession(session);
170
 
157
 
171
         return session;
158
         return session;
172
-    },
159
+    }
173
 
160
 
174
     /**
161
     /**
175
      * Notifies listeners of an update to a recording session.
162
      * Notifies listeners of an update to a recording session.
177
      * @param {JibriSession} session - The session that has been updated.
164
      * @param {JibriSession} session - The session that has been updated.
178
      */
165
      */
179
     _emitSessionUpdate(session) {
166
     _emitSessionUpdate(session) {
180
-        this._eventEmitter.emit(XMPPEvents.RECORDER_STATE_CHANGED, session);
181
-    },
167
+        this._chatRoom.eventEmitter.emit(
168
+            XMPPEvents.RECORDER_STATE_CHANGED, session);
169
+    }
182
 
170
 
183
     /**
171
     /**
184
      * Parses presence to update an existing JibriSession or to create a new
172
      * Parses presence to update an existing JibriSession or to create a new
222
         }
210
         }
223
 
211
 
224
         this._emitSessionUpdate(session);
212
         this._emitSessionUpdate(session);
225
-    },
213
+    }
226
 
214
 
227
     /**
215
     /**
228
      * Handles updates from the Jibri which can broadcast a YouTube URL that
216
      * Handles updates from the Jibri which can broadcast a YouTube URL that
252
 
240
 
253
         this._emitSessionUpdate(session);
241
         this._emitSessionUpdate(session);
254
     }
242
     }
255
-};
243
+}
256
 
244
 
257
-export default recordingManager;
245
+export default RecordingManager;

+ 4
- 33
modules/xmpp/ChatRoom.js 查看文件

6
 import GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';
6
 import GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';
7
 import * as JitsiTranscriptionStatus from '../../JitsiTranscriptionStatus';
7
 import * as JitsiTranscriptionStatus from '../../JitsiTranscriptionStatus';
8
 import Listenable from '../util/Listenable';
8
 import Listenable from '../util/Listenable';
9
-import recordingManager from '../recording/recordingManager';
10
 import Settings from '../settings/Settings';
9
 import Settings from '../settings/Settings';
11
 import * as MediaType from '../../service/RTC/MediaType';
10
 import * as MediaType from '../../service/RTC/MediaType';
12
 import XMPPEvents from '../../service/xmpp/XMPPEvents';
11
 import XMPPEvents from '../../service/xmpp/XMPPEvents';
172
 
171
 
173
         this.locked = false;
172
         this.locked = false;
174
         this.transcriptionStatus = JitsiTranscriptionStatus.OFF;
173
         this.transcriptionStatus = JitsiTranscriptionStatus.OFF;
175
-
176
-        recordingManager.init(
177
-            this.eventEmitter,
178
-            this.connection,
179
-            this.focusMucJid);
180
     }
174
     }
181
 
175
 
182
     /* eslint-enable max-params */
176
     /* eslint-enable max-params */
424
                 && this.options.hiddenDomain
418
                 && this.options.hiddenDomain
425
                     === jid.substring(jid.indexOf('@') + 1, jid.indexOf('/'));
419
                     === jid.substring(jid.indexOf('@') + 1, jid.indexOf('/'));
426
 
420
 
427
-        recordingManager.onPresence(pres, member.isHiddenDomain);
421
+        this.eventEmitter.emit(XMPPEvents.PRESENCE_RECEIVED, {
422
+            fromHiddenDomain: member.isHiddenDomain,
423
+            presence: pres
424
+        });
428
 
425
 
429
         const xEl = pres.querySelector('x');
426
         const xEl = pres.querySelector('x');
430
 
427
 
645
     _initFocus(from, mucJid) {
642
     _initFocus(from, mucJid) {
646
         this.focusMucJid = from;
643
         this.focusMucJid = from;
647
 
644
 
648
-        recordingManager.setFocusMucJid(this.focusMucJid);
649
-
650
         logger.info(`Ignore focus: ${from}, real JID: ${mucJid}`);
645
         logger.info(`Ignore focus: ${from}, real JID: ${mucJid}`);
651
     }
646
     }
652
 
647
 
1255
         return data;
1250
         return data;
1256
     }
1251
     }
1257
 
1252
 
1258
-    /**
1259
-     * Starts a recording session.
1260
-     *
1261
-     * @param {Object} options - Configuration for the recording. See
1262
-     * {@link recordingManager#startRecording} for more info.
1263
-     * @returns {Promise} See {@link recordingManager#startRecording} for more
1264
-     * info.
1265
-     */
1266
-    startRecording(options) {
1267
-        return recordingManager.startRecording(options);
1268
-    }
1269
-
1270
-    /**
1271
-     * Stops a recording session.
1272
-     *
1273
-     * @param {string} sessionID - The ID of the recording session that should
1274
-     * be stopped.
1275
-     * @returns {Promise} See {@link recordingManager#stopRecording} for more
1276
-     * info.
1277
-     */
1278
-    stopRecording(sessionID) {
1279
-        return recordingManager.stopRecording(sessionID);
1280
-    }
1281
-
1282
     /**
1253
     /**
1283
      * Returns true if the SIP calls are supported and false otherwise
1254
      * Returns true if the SIP calls are supported and false otherwise
1284
      */
1255
      */

+ 15
- 3
modules/xmpp/ChatRoom.spec.js 查看文件

155
             const pres = new DOMParser().parseFromString(presStr, 'text/xml').documentElement;
155
             const pres = new DOMParser().parseFromString(presStr, 'text/xml').documentElement;
156
 
156
 
157
             room.onPresence(pres);
157
             room.onPresence(pres);
158
-            expect(emitterSpy.calls.count()).toEqual(1);
158
+            expect(emitterSpy.calls.count()).toEqual(2);
159
+            expect(emitterSpy.calls.argsFor(0)).toEqual([
160
+                XMPPEvents.PRESENCE_RECEIVED,
161
+                jasmine.any(Object)
162
+            ]);
159
             expect(emitterSpy).toHaveBeenCalledWith(
163
             expect(emitterSpy).toHaveBeenCalledWith(
160
                 XMPPEvents.MUC_MEMBER_JOINED,
164
                 XMPPEvents.MUC_MEMBER_JOINED,
161
                 'fromjid',
165
                 'fromjid',
177
             const pres = new DOMParser().parseFromString(presStr, 'text/xml').documentElement;
181
             const pres = new DOMParser().parseFromString(presStr, 'text/xml').documentElement;
178
 
182
 
179
             room.onPresence(pres);
183
             room.onPresence(pres);
180
-            expect(emitterSpy.calls.count()).toEqual(1);
184
+            expect(emitterSpy.calls.count()).toEqual(2);
185
+            expect(emitterSpy.calls.argsFor(0)).toEqual([
186
+                XMPPEvents.PRESENCE_RECEIVED,
187
+                jasmine.any(Object)
188
+            ]);
181
             expect(emitterSpy).toHaveBeenCalledWith(
189
             expect(emitterSpy).toHaveBeenCalledWith(
182
                 XMPPEvents.MUC_MEMBER_JOINED,
190
                 XMPPEvents.MUC_MEMBER_JOINED,
183
                 'fromjid',
191
                 'fromjid',
214
             };
222
             };
215
 
223
 
216
             room.onPresence(pres);
224
             room.onPresence(pres);
217
-            expect(emitterSpy.calls.count()).toEqual(1);
225
+            expect(emitterSpy.calls.count()).toEqual(2);
226
+            expect(emitterSpy.calls.argsFor(0)).toEqual([
227
+                XMPPEvents.PRESENCE_RECEIVED,
228
+                jasmine.any(Object)
229
+            ]);
218
             expect(emitterSpy).toHaveBeenCalledWith(
230
             expect(emitterSpy).toHaveBeenCalledWith(
219
                 XMPPEvents.MUC_MEMBER_JOINED,
231
                 XMPPEvents.MUC_MEMBER_JOINED,
220
                 'fromjid',
232
                 'fromjid',

+ 1
- 0
service/xmpp/XMPPEvents.js 查看文件

148
      * Indicates that phone number changed.
148
      * Indicates that phone number changed.
149
      */
149
      */
150
     PHONE_NUMBER_CHANGED: 'conference.phoneNumberChanged',
150
     PHONE_NUMBER_CHANGED: 'conference.phoneNumberChanged',
151
+    PRESENCE_RECEIVED: 'xmpp.presence_received',
151
     PRESENCE_STATUS: 'xmpp.presence_status',
152
     PRESENCE_STATUS: 'xmpp.presence_status',
152
     PROMPT_FOR_LOGIN: 'xmpp.prompt_for_login',
153
     PROMPT_FOR_LOGIN: 'xmpp.prompt_for_login',
153
 
154
 

正在加载...
取消
保存