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.

TalkMutedDetection.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import * as JitsiConferenceEvents from '../JitsiConferenceEvents';
  2. /**
  3. *
  4. */
  5. export default class TalkMutedDetection {
  6. /**
  7. * Creates TalkMutedDetection
  8. * @param conference the JitsiConference instance that created us.
  9. * @param callback the callback to call when detected that the local user is
  10. * talking while her microphone is muted.
  11. * @constructor
  12. */
  13. constructor(conference, callback) {
  14. /**
  15. * The callback to call when detected that the local user is talking
  16. * while her microphone is muted.
  17. *
  18. * @private
  19. */
  20. this._callback = callback;
  21. /**
  22. * The indicator which determines whether <tt>callback</tt> has been
  23. * invoked for the current local audio track of <tt>conference</tt> so
  24. * that it is invoked once only.
  25. *
  26. * @private
  27. */
  28. this._eventFired = false;
  29. // XXX I went back and forth on the subject of where to put the access
  30. // to statistics. On the one had, (1) statistics is likely intended to
  31. // be private to conference and (2) there is a desire to keep the
  32. // dependencies of modules to the minimum (i.e. not have
  33. // TalkMutedDetection depend on statistics). On the other hand, (1)
  34. // statistics is technically not private because
  35. // JitsiConferenceEventManager accesses it and (2) TalkMutedDetection
  36. // works exactly because it knows that there are no audio levels for
  37. // JitsiLocalTrack but there are audio levels for the local participant
  38. // through statistics.
  39. conference.statistics.addAudioLevelListener(
  40. this._audioLevel.bind(this));
  41. conference.on(
  42. JitsiConferenceEvents.TRACK_MUTE_CHANGED,
  43. this._trackMuteChanged.bind(this));
  44. conference.on(
  45. JitsiConferenceEvents.TRACK_ADDED,
  46. this._trackAdded.bind(this));
  47. }
  48. /**
  49. * Receives audio level events for all send and receive streams.
  50. *
  51. * @param ssrc - The synchronization source identifier (SSRC) of the
  52. * endpoint/participant/stream being reported.
  53. * @param {number} audioLevel - The audio level of <tt>ssrc</tt>.
  54. * @param {boolean} isLocal - <tt>true</tt> if <tt>ssrc</tt> represents a
  55. * local/send stream or <tt>false</tt> for a remote/receive stream.
  56. */
  57. _audioLevel(ssrc, audioLevel, isLocal) {
  58. // We are interested in the local audio stream only and if event is not
  59. // sent yet.
  60. if (!isLocal || !this.audioTrack || this._eventFired) {
  61. return;
  62. }
  63. if (this.audioTrack.isMuted() && audioLevel > 0.6) {
  64. this._eventFired = true;
  65. this._callback();
  66. }
  67. }
  68. /**
  69. * Determines whether a specific {@link JitsiTrack} represents a local audio
  70. * track.
  71. *
  72. * @param {JitsiTrack} track - The <tt>JitsiTrack</tt> to be checked whether
  73. * it represents a local audio track.
  74. * @private
  75. * @return {boolean} - <tt>true</tt> if the specified <tt>track</tt>
  76. * represents a local audio track; otherwise, <tt>false</tt>.
  77. */
  78. _isLocalAudioTrack(track) {
  79. return track.isAudioTrack() && track.isLocal();
  80. }
  81. /**
  82. * Notifies this <tt>TalkMutedDetection</tt> that a {@link JitsiTrack} was
  83. * added to the associated {@link JitsiConference}. Looks for the local
  84. * audio track only.
  85. *
  86. * @param {JitsiTrack} track - The added <tt>JitsiTrack</tt>.
  87. * @private
  88. */
  89. _trackAdded(track) {
  90. if (this._isLocalAudioTrack(track)) {
  91. this.audioTrack = track;
  92. }
  93. }
  94. /**
  95. * Notifies this <tt>TalkMutedDetection</tt> that the mute state of a
  96. * {@link JitsiTrack} has changed. Looks for the local audio track only.
  97. *
  98. * @param {JitsiTrack} track - The <tt>JitsiTrack</tt> whose mute state has
  99. * changed.
  100. * @private
  101. */
  102. _trackMuteChanged(track) {
  103. if (this._isLocalAudioTrack(track) && track.isMuted()) {
  104. this._eventFired = false;
  105. }
  106. }
  107. }