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.ts 5.5KB

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