Browse Source

Fix: Speaker stats are not delivered for the breakout rooms (#11644)

* Send speaker stats for brk room

* Fix comments component loaded
master
abora8x8 3 years ago
parent
commit
15d453de1d
No account linked to committer's email address
1 changed files with 107 additions and 21 deletions
  1. 107
    21
      resources/prosody-plugins/mod_speakerstats_component.lua

+ 107
- 21
resources/prosody-plugins/mod_speakerstats_component.lua View File

7
 local socket = require "socket";
7
 local socket = require "socket";
8
 local json = require "util.json";
8
 local json = require "util.json";
9
 local um_is_admin = require "core.usermanager".is_admin;
9
 local um_is_admin = require "core.usermanager".is_admin;
10
+local jid_split = require 'util.jid'.split;
10
 
11
 
11
 -- we use async to detect Prosody 0.10 and earlier
12
 -- we use async to detect Prosody 0.10 and earlier
12
 local have_async = pcall(require, "util.async");
13
 local have_async = pcall(require, "util.async");
16
 end
17
 end
17
 
18
 
18
 local muc_component_host = module:get_option_string("muc_component");
19
 local muc_component_host = module:get_option_string("muc_component");
19
-if muc_component_host == nil then
20
+local muc_domain_base = module:get_option_string("muc_mapper_domain_base");
21
+
22
+if muc_component_host == nil or muc_domain_base == nil then
20
     log("error", "No muc_component specified. No muc to operate on!");
23
     log("error", "No muc_component specified. No muc to operate on!");
21
     return;
24
     return;
22
 end
25
 end
26
+local breakout_room_component_host = "breakout." .. muc_domain_base;
23
 
27
 
24
 log("info", "Starting speakerstats for %s", muc_component_host);
28
 log("info", "Starting speakerstats for %s", muc_component_host);
25
 
29
 
30
+local main_muc_service;
31
+
26
 local function is_admin(jid)
32
 local function is_admin(jid)
27
     return um_is_admin(jid, module.host);
33
     return um_is_admin(jid, module.host);
28
 end
34
 end
29
 
35
 
36
+-- Searches all rooms in the main muc component that holds a breakout room
37
+-- caches it if found so we don't search it again
38
+local function get_main_room(breakout_room)
39
+    if breakout_room._data and breakout_room._data.main_room then
40
+        return breakout_room._data.main_room;
41
+    end
42
+
43
+    -- let's search all rooms to find the main room
44
+    for room in main_muc_service.each_room() do
45
+        if room._data and room._data.breakout_rooms_active and room._data.breakout_rooms[breakout_room.jid] then
46
+            breakout_room._data.main_room = room;
47
+            return room;
48
+        end
49
+    end
50
+end
51
+
30
 -- receives messages from client currently connected to the room
52
 -- receives messages from client currently connected to the room
31
 -- clients indicates their own dominant speaker events
53
 -- clients indicates their own dominant speaker events
32
 function on_message(event)
54
 function on_message(event)
45
             log("warn", "No room found %s", roomAddress);
67
             log("warn", "No room found %s", roomAddress);
46
             return false;
68
             return false;
47
         end
69
         end
48
-        
70
+
49
         if not room.speakerStats then
71
         if not room.speakerStats then
50
             log("warn", "No speakerStats found for %s", roomAddress);
72
             log("warn", "No speakerStats found for %s", roomAddress);
51
             return false;
73
             return false;
99
             return false;
121
             return false;
100
         end
122
         end
101
         local faceExpressions = room.speakerStats[occupant.jid].faceExpressions;
123
         local faceExpressions = room.speakerStats[occupant.jid].faceExpressions;
102
-        faceExpressions[faceExpression.attr.expression] = 
124
+        faceExpressions[faceExpression.attr.expression] =
103
             faceExpressions[faceExpression.attr.expression] + tonumber(faceExpression.attr.duration);
125
             faceExpressions[faceExpression.attr.expression] + tonumber(faceExpression.attr.duration);
104
     end
126
     end
105
 
127
 
158
     local room = event.room;
180
     local room = event.room;
159
 
181
 
160
     if is_healthcheck_room(room.jid) then
182
     if is_healthcheck_room(room.jid) then
161
-        return;
183
+        return ;
162
     end
184
     end
185
+    room.speakerStats = {};
186
+    room.speakerStats.sessionId = room._data.meetingId;
187
+end
163
 
188
 
189
+-- create speakerStats for the breakout
190
+function breakout_room_created(event)
191
+    local room = event.room;
192
+    if is_healthcheck_room(room.jid) then
193
+        return ;
194
+    end
195
+    local main_room = get_main_room(room);
164
     room.speakerStats = {};
196
     room.speakerStats = {};
197
+    room.speakerStats.isBreakout = true
198
+    room.speakerStats.breakoutRoomId = jid_split(room.jid)
199
+    room.speakerStats.sessionId = main_room._data.meetingId;
165
 end
200
 end
166
 
201
 
167
 -- Create SpeakerStats object for the joined user
202
 -- Create SpeakerStats object for the joined user
184
             for jid, values in pairs(room.speakerStats) do
219
             for jid, values in pairs(room.speakerStats) do
185
                 -- skip reporting those without a nick('dominantSpeakerId')
220
                 -- skip reporting those without a nick('dominantSpeakerId')
186
                 -- and skip focus if sneaked into the table
221
                 -- and skip focus if sneaked into the table
187
-                if values.nick ~= nil and values.nick ~= 'focus' then
222
+                if values and type(values) == 'table' and values.nick ~= nil and values.nick ~= 'focus' then
188
                     local totalDominantSpeakerTime = values.totalDominantSpeakerTime;
223
                     local totalDominantSpeakerTime = values.totalDominantSpeakerTime;
189
                     local faceExpressions = values.faceExpressions;
224
                     local faceExpressions = values.faceExpressions;
190
                     if totalDominantSpeakerTime > 0 or room:get_occupant_jid(jid) == nil or values:isDominantSpeaker()
225
                     if totalDominantSpeakerTime > 0 or room:get_occupant_jid(jid) == nil or values:isDominantSpeaker()
263
 
298
 
264
 module:hook("message/host", on_message);
299
 module:hook("message/host", on_message);
265
 
300
 
266
-function process_host(host)
267
-    if host == muc_component_host then -- the conference muc component
268
-        module:log("info","Hook to muc events on %s", host);
301
+function process_main_muc_loaded(main_muc, host_module)
302
+    -- the conference muc component
303
+    module:log("info", "Hook to muc events on %s", host_module);
304
+    main_muc_service = main_muc;
305
+    module:log("info", "Main muc service %s", main_muc_service)
306
+    host_module:hook("muc-room-created", room_created, -1);
307
+    host_module:hook("muc-occupant-joined", occupant_joined, -1);
308
+    host_module:hook("muc-occupant-pre-leave", occupant_leaving, -1);
309
+    host_module:hook("muc-room-destroyed", room_destroyed, -1);
310
+end
269
 
311
 
270
-        local muc_module = module:context(host);
271
-        muc_module:hook("muc-room-created", room_created, -1);
272
-        muc_module:hook("muc-occupant-joined", occupant_joined, -1);
273
-        muc_module:hook("muc-occupant-pre-leave", occupant_leaving, -1);
274
-        muc_module:hook("muc-room-destroyed", room_destroyed, -1);
275
-    end
312
+function process_breakout_muc_loaded(breakout_muc, host_module)
313
+    -- the Breakout muc component
314
+    module:log("info", "Hook to muc events on %s", host_module);
315
+    host_module:hook("muc-room-created", breakout_room_created, -1);
316
+    host_module:hook("muc-occupant-joined", occupant_joined, -1);
317
+    host_module:hook("muc-occupant-pre-leave", occupant_leaving, -1);
318
+    host_module:hook("muc-room-destroyed", room_destroyed, -1);
276
 end
319
 end
277
 
320
 
278
-if prosody.hosts[muc_component_host] == nil then
279
-    module:log("info","No muc component found, will listen for it: %s", muc_component_host)
321
+-- process a host module directly if loaded or hooks to wait for its load
322
+function process_host_module(name, callback)
323
+    local function process_host(host)
324
+        if host == name then
325
+            callback(module:context(host), host);
326
+        end
327
+    end
328
+
329
+    if prosody.hosts[name] == nil then
330
+        module:log('debug', 'No host/component found, will wait for it: %s', name)
280
 
331
 
281
-    -- when a host or component is added
282
-    prosody.events.add_handler("host-activated", process_host);
283
-else
284
-    process_host(muc_component_host);
332
+        -- when a host or component is added
333
+        prosody.events.add_handler('host-activated', process_host);
334
+    else
335
+        process_host(name);
336
+    end
285
 end
337
 end
286
 
338
 
339
+-- process or waits to process the conference muc component
340
+process_host_module(muc_component_host, function(host_module, host)
341
+    module:log('info', 'Conference component loaded %s', host);
342
+
343
+    local muc_module = prosody.hosts[host].modules.muc;
344
+    if muc_module then
345
+        process_main_muc_loaded(muc_module, host_module);
346
+    else
347
+        module:log('debug', 'Will wait for muc to be available');
348
+        prosody.hosts[host].events.add_handler('module-loaded', function(event)
349
+            if (event.module == 'muc') then
350
+                process_main_muc_loaded(prosody.hosts[host].modules.muc, host_module);
351
+            end
352
+        end);
353
+    end
354
+end);
355
+
356
+-- process or waits to process the breakout rooms muc component
357
+process_host_module(breakout_room_component_host, function(host_module, host)
358
+    module:log('info', 'Breakout component loaded %s', host);
359
+
360
+    local muc_module = prosody.hosts[host].modules.muc;
361
+    if muc_module then
362
+        process_breakout_muc_loaded(muc_module, host_module);
363
+    else
364
+        module:log('debug', 'Will wait for muc to be available');
365
+        prosody.hosts[host].events.add_handler('module-loaded', function(event)
366
+            if (event.module == 'muc') then
367
+                process_breakout_muc_loaded(prosody.hosts[host].modules.muc, host_module);
368
+            end
369
+        end);
370
+    end
371
+end);
372
+
287
 function get_participant_expressions_count(faceExpressions)
373
 function get_participant_expressions_count(faceExpressions)
288
     local count = 0;
374
     local count = 0;
289
-    for expression, value in pairs(faceExpressions) do
375
+    for _, value in pairs(faceExpressions) do
290
         count = count + value;
376
         count = count + value;
291
     end
377
     end
292
 
378
 

Loading…
Cancel
Save