소스 검색

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

modules/recording/recordingManager.js → modules/recording/RecordingManager.js 파일 보기

@@ -8,32 +8,30 @@ import recordingXMLUtils from './recordingXMLUtils';
8 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 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 37
      * Finds an existing recording session by session ID.
@@ -43,38 +41,27 @@ const recordingManager = {
43 41
      */
44 42
     getSession(sessionID) {
45 43
         return this._sessions[sessionID];
46
-    },
44
+    }
47 45
 
48 46
     /**
49 47
      * Callback to invoke to parse through a presence update to find recording
50 48
      * related updates (from Jibri participant doing the recording and the
51 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 56
      * @returns {void}
58 57
      */
59
-    onPresence(presence, isHiddenDomain) {
58
+    onPresence({ fromHiddenDomain, presence }) {
60 59
         if (recordingXMLUtils.isFromFocus(presence)) {
61 60
             this._handleFocusPresence(presence);
62
-        } else if (isHiddenDomain) {
61
+        } else if (fromHiddenDomain) {
63 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 67
      * Start a recording session.
@@ -93,12 +80,12 @@ const recordingManager = {
93 80
     startRecording(options) {
94 81
         const session = new JibriSession({
95 82
             ...options,
96
-            connection: this._connection
83
+            connection: this._chatRoom.connection
97 84
         });
98 85
 
99 86
         return session.start({
100 87
             broadcastId: options.broadcastId,
101
-            focusMucJid: this._focusMucJid,
88
+            focusMucJid: this._chatRoom.focusMucJid,
102 89
             streamId: options.streamId
103 90
         })
104 91
             .then(() => {
@@ -118,7 +105,7 @@ const recordingManager = {
118 105
 
119 106
                 return Promise.reject(error);
120 107
             });
121
-    },
108
+    }
122 109
 
123 110
     /**
124 111
      * Stop a recording session.
@@ -132,11 +119,11 @@ const recordingManager = {
132 119
         const session = this.getSession(sessionID);
133 120
 
134 121
         if (session) {
135
-            return session.stop({ focusMucJid: this._focusMucJid });
122
+            return session.stop({ focusMucJid: this._chatRoom.focusMucJid });
136 123
         }
137 124
 
138 125
         return Promise.reject(new Error('Could not find session'));
139
-    },
126
+    }
140 127
 
141 128
     /**
142 129
      * Stores a reference to the passed in JibriSession.
@@ -146,7 +133,7 @@ const recordingManager = {
146 133
      */
147 134
     _addSession(session) {
148 135
         this._sessions[session.getID()] = session;
149
-    },
136
+    }
150 137
 
151 138
     /**
152 139
      * Create a new instance of a recording session and stores a reference to
@@ -159,8 +146,8 @@ const recordingManager = {
159 146
      */
160 147
     _createSession(sessionID, status, mode) {
161 148
         const session = new JibriSession({
162
-            connection: this._connection,
163
-            focusMucJid: this._focusMucJid,
149
+            connection: this._chatRoom.connection,
150
+            focusMucJid: this._chatRoom.focusMucJid,
164 151
             mode,
165 152
             sessionID,
166 153
             status
@@ -169,7 +156,7 @@ const recordingManager = {
169 156
         this._addSession(session);
170 157
 
171 158
         return session;
172
-    },
159
+    }
173 160
 
174 161
     /**
175 162
      * Notifies listeners of an update to a recording session.
@@ -177,8 +164,9 @@ const recordingManager = {
177 164
      * @param {JibriSession} session - The session that has been updated.
178 165
      */
179 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 172
      * Parses presence to update an existing JibriSession or to create a new
@@ -222,7 +210,7 @@ const recordingManager = {
222 210
         }
223 211
 
224 212
         this._emitSessionUpdate(session);
225
-    },
213
+    }
226 214
 
227 215
     /**
228 216
      * Handles updates from the Jibri which can broadcast a YouTube URL that
@@ -252,6 +240,6 @@ const recordingManager = {
252 240
 
253 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,7 +6,6 @@ import { $iq, $msg, $pres, Strophe } from 'strophe.js';
6 6
 import GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';
7 7
 import * as JitsiTranscriptionStatus from '../../JitsiTranscriptionStatus';
8 8
 import Listenable from '../util/Listenable';
9
-import recordingManager from '../recording/recordingManager';
10 9
 import Settings from '../settings/Settings';
11 10
 import * as MediaType from '../../service/RTC/MediaType';
12 11
 import XMPPEvents from '../../service/xmpp/XMPPEvents';
@@ -172,11 +171,6 @@ export default class ChatRoom extends Listenable {
172 171
 
173 172
         this.locked = false;
174 173
         this.transcriptionStatus = JitsiTranscriptionStatus.OFF;
175
-
176
-        recordingManager.init(
177
-            this.eventEmitter,
178
-            this.connection,
179
-            this.focusMucJid);
180 174
     }
181 175
 
182 176
     /* eslint-enable max-params */
@@ -424,7 +418,10 @@ export default class ChatRoom extends Listenable {
424 418
                 && this.options.hiddenDomain
425 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 426
         const xEl = pres.querySelector('x');
430 427
 
@@ -645,8 +642,6 @@ export default class ChatRoom extends Listenable {
645 642
     _initFocus(from, mucJid) {
646 643
         this.focusMucJid = from;
647 644
 
648
-        recordingManager.setFocusMucJid(this.focusMucJid);
649
-
650 645
         logger.info(`Ignore focus: ${from}, real JID: ${mucJid}`);
651 646
     }
652 647
 
@@ -1255,30 +1250,6 @@ export default class ChatRoom extends Listenable {
1255 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 1254
      * Returns true if the SIP calls are supported and false otherwise
1284 1255
      */

+ 15
- 3
modules/xmpp/ChatRoom.spec.js 파일 보기

@@ -155,7 +155,11 @@ describe('ChatRoom', () => {
155 155
             const pres = new DOMParser().parseFromString(presStr, 'text/xml').documentElement;
156 156
 
157 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 163
             expect(emitterSpy).toHaveBeenCalledWith(
160 164
                 XMPPEvents.MUC_MEMBER_JOINED,
161 165
                 'fromjid',
@@ -177,7 +181,11 @@ describe('ChatRoom', () => {
177 181
             const pres = new DOMParser().parseFromString(presStr, 'text/xml').documentElement;
178 182
 
179 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 189
             expect(emitterSpy).toHaveBeenCalledWith(
182 190
                 XMPPEvents.MUC_MEMBER_JOINED,
183 191
                 'fromjid',
@@ -214,7 +222,11 @@ describe('ChatRoom', () => {
214 222
             };
215 223
 
216 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 230
             expect(emitterSpy).toHaveBeenCalledWith(
219 231
                 XMPPEvents.MUC_MEMBER_JOINED,
220 232
                 'fromjid',

+ 1
- 0
service/xmpp/XMPPEvents.js 파일 보기

@@ -148,6 +148,7 @@ const XMPPEvents = {
148 148
      * Indicates that phone number changed.
149 149
      */
150 150
     PHONE_NUMBER_CHANGED: 'conference.phoneNumberChanged',
151
+    PRESENCE_RECEIVED: 'xmpp.presence_received',
151 152
     PRESENCE_STATUS: 'xmpp.presence_status',
152 153
     PROMPT_FOR_LOGIN: 'xmpp.prompt_for_login',
153 154
 

Loading…
취소
저장