You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SpeakerStats.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /**
  2. * A model for keeping track of each user's total
  3. * time as a dominant speaker. The model also
  4. * keeps track of the user's last known name
  5. * in case the user has left the meeting,
  6. * which is also tracked.
  7. */
  8. class SpeakerStats {
  9. /**
  10. * Initializes a new SpeakerStats instance.
  11. *
  12. * @constructor
  13. * @param {string} userId - The id of the user being tracked.
  14. * @param {string} displayName - The name of the user being tracked.
  15. * @param {boolean} isLocalStats - True if the stats model tracks
  16. * the local user.
  17. * @returns {void}
  18. */
  19. constructor(userId, displayName, isLocalStats) {
  20. this._userId = userId;
  21. this.setDisplayName(displayName);
  22. this._isLocalStats = isLocalStats || false;
  23. this.setDominantSpeaker(false);
  24. this.totalDominantSpeakerTime = 0;
  25. this._dominantSpeakerStart = 0;
  26. this._isDominantSpeaker = false;
  27. this._isSilent = false;
  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. };
  38. }
  39. /**
  40. * Get the user id being tracked.
  41. *
  42. * @returns {string} The user id.
  43. */
  44. getUserId() {
  45. return this._userId;
  46. }
  47. /**
  48. * Get the name of the user being tracked.
  49. *
  50. * @returns {string} The user name.
  51. */
  52. getDisplayName() {
  53. return this.displayName;
  54. }
  55. /**
  56. * Updates the last known name of the user being tracked.
  57. *
  58. * @param {string} - The user name.
  59. * @returns {void}
  60. */
  61. setDisplayName(newName) {
  62. this.displayName = newName;
  63. }
  64. /**
  65. * Returns true if the stats are tracking the local user.
  66. *
  67. * @returns {boolean}
  68. */
  69. isLocalStats() {
  70. return this._isLocalStats;
  71. }
  72. /**
  73. * Returns true if the tracked user is currently a dominant speaker.
  74. *
  75. * @returns {boolean}
  76. */
  77. isDominantSpeaker() {
  78. return this._isDominantSpeaker;
  79. }
  80. /**
  81. * Returns true if the tracked user is currently a dominant speaker.
  82. *
  83. * @param {boolean} - If true, the user will being accumulating time
  84. * as dominant speaker. If false, the user will not accumulate time
  85. * and will record any time accumulated since starting as dominant speaker.
  86. * @param {boolean} silence - Indecates whether the dominant speaker is silent or not.
  87. * @returns {void}
  88. */
  89. setDominantSpeaker(isNowDominantSpeaker, silence) {
  90. if (!this.isDominantSpeaker() && isNowDominantSpeaker && !silence) {
  91. this._dominantSpeakerStart = Date.now();
  92. } else if (this.isDominantSpeaker()) {
  93. if (!isNowDominantSpeaker) {
  94. if (!this._isSilent) {
  95. const now = Date.now();
  96. const timeElapsed = now - this._dominantSpeakerStart;
  97. this.totalDominantSpeakerTime += timeElapsed;
  98. this._dominantSpeakerStart = 0;
  99. }
  100. } else if (this._isSilent && !silence) {
  101. this._dominantSpeakerStart = Date.now();
  102. } else if (!this._isSilent && silence) {
  103. const now = Date.now();
  104. const timeElapsed = now - this._dominantSpeakerStart;
  105. this.totalDominantSpeakerTime += timeElapsed;
  106. this._dominantSpeakerStart = 0;
  107. }
  108. }
  109. this._isDominantSpeaker = isNowDominantSpeaker;
  110. this._isSilent = silence;
  111. }
  112. /**
  113. * Get how long the tracked user has been dominant speaker.
  114. *
  115. * @returns {number} - The speaker time in milliseconds.
  116. */
  117. getTotalDominantSpeakerTime() {
  118. let total = this.totalDominantSpeakerTime;
  119. if (this.isDominantSpeaker() && !this._isSilent) {
  120. total += Date.now() - this._dominantSpeakerStart;
  121. }
  122. return total;
  123. }
  124. /**
  125. * Get whether or not the user is still in the meeting.
  126. *
  127. * @returns {boolean} True if the user is no longer in the meeting.
  128. */
  129. hasLeft() {
  130. return this._hasLeft;
  131. }
  132. /**
  133. * Set the user as having left the meeting.
  134. *
  135. * @returns {void}
  136. */
  137. markAsHasLeft() {
  138. this._hasLeft = true;
  139. this.setDominantSpeaker(false);
  140. }
  141. /**
  142. * Gets the face expressions of the user.
  143. *
  144. * @returns {Object}
  145. */
  146. getFaceExpressions() {
  147. return this._faceExpressions;
  148. }
  149. /**
  150. * Sets the face expressions of the user.
  151. *
  152. * @param {Object} faceExpressions - object with face expressions.
  153. * @returns {void}
  154. */
  155. setFaceExpressions(faceExpressions) {
  156. this._faceExpressions = faceExpressions;
  157. }
  158. /**
  159. * Adds a new face expression to speaker stats.
  160. *
  161. * @param {string} faceExpression
  162. * @param {number} duration
  163. */
  164. addFaceExpression(faceExpression, duration) {
  165. this._faceExpressions[faceExpression] += duration;
  166. }
  167. }
  168. module.exports = SpeakerStats;