Pārlūkot izejas kodu

feat(face-landmarks): add face landmarks timeline (#2157)

* feat(face-landmarks): add timeline

* add duration to xmpp payload
tags/v0.0.2
Gabriel Borlea 2 gadus atpakaļ
vecāks
revīzija
eb4873d2c3
Revīzijas autora e-pasta adrese nav piesaistīta nevienam kontam

+ 1
- 1
JitsiConference.js Parādīt failu

@@ -3710,7 +3710,7 @@ JitsiConference.prototype.getSpeakerStats = function() {
3710 3710
  */
3711 3711
 JitsiConference.prototype.sendFaceLandmarks = function(payload) {
3712 3712
     if (payload.faceExpression) {
3713
-        this.xmpp.sendFaceExpressionEvent(this.room.roomjid, payload);
3713
+        this.xmpp.sendFaceLandmarksEvent(this.room.roomjid, payload);
3714 3714
     }
3715 3715
 };
3716 3716
 

+ 0
- 3
JitsiConferenceEvents.spec.ts Parādīt failu

@@ -73,7 +73,6 @@ describe( "/JitsiConferenceEvents members", () => {
73 73
         AV_MODERATION_CHANGED,
74 74
         AV_MODERATION_PARTICIPANT_APPROVED,
75 75
         AV_MODERATION_PARTICIPANT_REJECTED,
76
-        FACE_LANDMARK_ADDED,
77 76
         BREAKOUT_ROOMS_MOVE_TO_ROOM,
78 77
         BREAKOUT_ROOMS_UPDATED,
79 78
         METADATA_UPDATED,
@@ -151,7 +150,6 @@ describe( "/JitsiConferenceEvents members", () => {
151 150
         expect( AV_MODERATION_CHANGED ).toBe( 'conference.av_moderation.changed' );
152 151
         expect( AV_MODERATION_PARTICIPANT_APPROVED ).toBe( 'conference.av_moderation.participant.approved' );
153 152
         expect( AV_MODERATION_PARTICIPANT_REJECTED ).toBe( 'conference.av_moderation.participant.rejected' );
154
-        expect( FACE_LANDMARK_ADDED ).toBe( 'conference.face_landmark.added' );
155 153
         expect( BREAKOUT_ROOMS_MOVE_TO_ROOM ).toBe( 'conference.breakout-rooms.move-to-room' );
156 154
         expect( BREAKOUT_ROOMS_UPDATED ).toBe( 'conference.breakout-rooms.updated' );
157 155
         expect( METADATA_UPDATED ).toBe( 'conference.metadata.updated' );
@@ -227,7 +225,6 @@ describe( "/JitsiConferenceEvents members", () => {
227 225
         expect( JitsiConferenceEvents.AV_MODERATION_CHANGED ).toBe( 'conference.av_moderation.changed' );
228 226
         expect( JitsiConferenceEvents.AV_MODERATION_PARTICIPANT_APPROVED ).toBe( 'conference.av_moderation.participant.approved' );
229 227
         expect( JitsiConferenceEvents.AV_MODERATION_PARTICIPANT_REJECTED ).toBe( 'conference.av_moderation.participant.rejected' );
230
-        expect( JitsiConferenceEvents.FACE_LANDMARK_ADDED ).toBe( 'conference.face_landmark.added' );
231 228
         expect( JitsiConferenceEvents.BREAKOUT_ROOMS_MOVE_TO_ROOM ).toBe( 'conference.breakout-rooms.move-to-room' );
232 229
         expect( JitsiConferenceEvents.BREAKOUT_ROOMS_UPDATED ).toBe( 'conference.breakout-rooms.updated' );
233 230
         expect( JitsiConferenceEvents.METADATA_UPDATED ).toBe( 'conference.metadata.updated' );

+ 0
- 6
JitsiConferenceEvents.ts Parādīt failu

@@ -440,11 +440,6 @@ export enum JitsiConferenceEvents {
440 440
      */
441 441
     AV_MODERATION_PARTICIPANT_REJECTED = 'conference.av_moderation.participant.rejected',
442 442
 
443
-    /**
444
-     * A new face landmark object is added for a participant
445
-     */
446
-    FACE_LANDMARK_ADDED = 'conference.face_landmark.added',
447
-
448 443
     /**
449 444
      * Event fired when a participant is requested to join a given (breakout) room.
450 445
      */
@@ -531,7 +526,6 @@ export const AV_MODERATION_REJECTED = JitsiConferenceEvents.AV_MODERATION_REJECT
531 526
 export const AV_MODERATION_CHANGED = JitsiConferenceEvents.AV_MODERATION_CHANGED;
532 527
 export const AV_MODERATION_PARTICIPANT_APPROVED = JitsiConferenceEvents.AV_MODERATION_PARTICIPANT_APPROVED;
533 528
 export const AV_MODERATION_PARTICIPANT_REJECTED = JitsiConferenceEvents.AV_MODERATION_PARTICIPANT_REJECTED;
534
-export const FACE_LANDMARK_ADDED = JitsiConferenceEvents.FACE_LANDMARK_ADDED;
535 529
 export const BREAKOUT_ROOMS_MOVE_TO_ROOM = JitsiConferenceEvents.BREAKOUT_ROOMS_MOVE_TO_ROOM;
536 530
 export const BREAKOUT_ROOMS_UPDATED = JitsiConferenceEvents.BREAKOUT_ROOMS_UPDATED;
537 531
 export const METADATA_UPDATED = JitsiConferenceEvents.METADATA_UPDATED;

+ 0
- 17
modules/connectivity/ConnectionQuality.js Parādīt failu

@@ -18,12 +18,6 @@ const logger = getLogger(__filename);
18 18
  */
19 19
 const STATS_MESSAGE_TYPE = 'stats';
20 20
 
21
-/**
22
- * The value to use for the "type" field for messages sent
23
- * over the data channel that contain a face landmark.
24
- */
25
-const FACE_LANDMARK_MESSAGE_TYPE = 'face_landmark';
26
-
27 21
 const kSimulcastFormats = [
28 22
     { width: 1920,
29 23
         height: 1080,
@@ -229,17 +223,6 @@ export default class ConnectionQuality {
229 223
                 this._updateRemoteStats(participant.getId(), payload);
230 224
             });
231 225
 
232
-        conference.on(
233
-            ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
234
-            (participant, payload) => {
235
-                if (payload.type === FACE_LANDMARK_MESSAGE_TYPE) {
236
-                    this.eventEmitter.emit(
237
-                        ConferenceEvents.FACE_LANDMARK_ADDED,
238
-                        participant.getId(),
239
-                        payload);
240
-                }
241
-            });
242
-
243 226
         // Listen to local statistics events originating from the RTC module and update the _localStats field.
244 227
         conference.statistics.addConnectionStatsListener(this._updateLocalStats.bind(this));
245 228
 

+ 11
- 19
modules/statistics/SpeakerStats.js Parādīt failu

@@ -26,15 +26,7 @@ class SpeakerStats {
26 26
         this._isDominantSpeaker = false;
27 27
         this._isSilent = false;
28 28
         this._hasLeft = false;
29
-        this._faceExpressions = {
30
-            happy: 0,
31
-            neutral: 0,
32
-            surprised: 0,
33
-            angry: 0,
34
-            fearful: 0,
35
-            disgusted: 0,
36
-            sad: 0
37
-        };
29
+        this._faceLandmarks = [];
38 30
     }
39 31
 
40 32
     /**
@@ -154,32 +146,32 @@ class SpeakerStats {
154 146
     }
155 147
 
156 148
     /**
157
-     * Gets the face expressions of the user.
149
+     * Gets the face landmarks of the user.
158 150
      *
159 151
      * @returns {Object}
160 152
      */
161
-    getFaceExpressions() {
162
-        return this._faceExpressions;
153
+    getFaceLandmarks() {
154
+        return this._faceLandmarks;
163 155
     }
164 156
 
165 157
     /**
166
-     * Sets the face expressions of the user.
158
+     * Sets the face landmarks of the user.
167 159
      *
168
-     * @param {Object} faceExpressions - object with face expressions.
160
+     * @param {Object} faceLandmarks - object with face expressions.
169 161
      * @returns {void}
170 162
      */
171
-    setFaceExpressions(faceExpressions) {
172
-        this._faceExpressions = faceExpressions;
163
+    setFaceLandmarks(faceLandmarks) {
164
+        this._faceLandmarks = faceLandmarks;
173 165
     }
174 166
 
175 167
     /**
176
-     * Adds a new face expression to speaker stats.
168
+     * Adds new face landmarks to speaker stats.
177 169
      *
178 170
      * @param  {string} faceExpression
179 171
      * @param {number} duration
180 172
      */
181
-    addFaceExpression(faceExpression, duration) {
182
-        this._faceExpressions[faceExpression] += duration;
173
+    addFaceLandmarks(faceLandmarks) {
174
+        this._faceLandmarks.push(faceLandmarks);
183 175
     }
184 176
 }
185 177
 

+ 19
- 6
modules/statistics/SpeakerStatsCollector.js Parādīt failu

@@ -3,6 +3,14 @@ import { XMPPEvents } from '../../service/xmpp/XMPPEvents';
3 3
 
4 4
 import SpeakerStats from './SpeakerStats';
5 5
 
6
+
7
+/**
8
+ * The value to use for the "type" field for messages sent
9
+ * over the data channel that contain a face landmark.
10
+ */
11
+
12
+const FACE_LANDMARK_MESSAGE_TYPE = 'face-landmarks';
13
+
6 14
 /**
7 15
  * A collection for tracking speaker stats. Attaches listeners
8 16
  * to the conference to automatically update on tracked events.
@@ -41,9 +49,14 @@ export default class SpeakerStatsCollector {
41 49
         conference.addEventListener(
42 50
             JitsiConferenceEvents.DISPLAY_NAME_CHANGED,
43 51
             this._onDisplayNameChange.bind(this));
44
-        conference.addEventListener(
45
-            JitsiConferenceEvents.FACE_LANDMARK_ADDED,
46
-            this._onFaceLandmarkAdd.bind(this));
52
+
53
+        conference.on(
54
+            JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
55
+                (participant, { type, faceLandmarks }) => {
56
+                    if (type === FACE_LANDMARK_MESSAGE_TYPE) {
57
+                        this._onFaceLandmarkAdd(participant.getId(), faceLandmarks);
58
+                    }
59
+                });
47 60
         if (conference.xmpp) {
48 61
             conference.xmpp.addListener(
49 62
                 XMPPEvents.SPEAKER_STATS_RECEIVED,
@@ -132,8 +145,8 @@ export default class SpeakerStatsCollector {
132 145
     _onFaceLandmarkAdd(userId, data) {
133 146
         const savedUser = this.stats.users[userId];
134 147
 
135
-        if (savedUser && data.faceExpression) {
136
-            savedUser.addFaceExpression(data.faceExpression, data.duration);
148
+        if (savedUser && data) {
149
+            savedUser.addFaceLandmarks(data);
137 150
         }
138 151
     }
139 152
 
@@ -177,7 +190,7 @@ export default class SpeakerStatsCollector {
177 190
                 speakerStatsToUpdate.totalDominantSpeakerTime
178 191
                     = newStats[userId].totalDominantSpeakerTime;
179 192
 
180
-                speakerStatsToUpdate.setFaceExpressions(newStats[userId].faceExpressions);
193
+                speakerStatsToUpdate.setFaceLandmarks(newStats[userId].faceLandmarks);
181 194
             }
182 195
         }
183 196
     }

+ 5
- 4
modules/xmpp/xmpp.js Parādīt failu

@@ -935,11 +935,11 @@ export default class XMPP extends Listenable {
935 935
     }
936 936
 
937 937
     /**
938
-     * Sends face expressions to speaker stats component.
938
+     * Sends face landmarks to speaker stats component.
939 939
      * @param {String} roomJid - The room jid where the speaker event occurred.
940 940
      * @param {Object} payload - The expression to be sent to the speaker stats.
941 941
      */
942
-    sendFaceExpressionEvent(roomJid, payload) {
942
+    sendFaceLandmarksEvent(roomJid, payload) {
943 943
         // no speaker stats component advertised
944 944
         if (!this.speakerStatsComponentAddress || !roomJid) {
945 945
             return;
@@ -947,10 +947,11 @@ export default class XMPP extends Listenable {
947 947
 
948 948
         const msg = $msg({ to: this.speakerStatsComponentAddress });
949 949
 
950
-        msg.c('faceExpression', {
950
+        msg.c('faceLandmarks', {
951 951
             xmlns: 'http://jitsi.org/jitmeet',
952 952
             room: roomJid,
953
-            expression: payload.faceExpression,
953
+            faceExpression: payload.faceExpression,
954
+            timestamp: payload.timestamp,
954 955
             duration: payload.duration
955 956
         }).up();
956 957
 

Notiek ielāde…
Atcelt
Saglabāt