您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

AVModeration.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import { getLogger } from 'jitsi-meet-logger';
  2. import { $msg } from 'strophe.js';
  3. import * as MediaType from '../../service/RTC/MediaType';
  4. import XMPPEvents from '../../service/xmpp/XMPPEvents';
  5. const logger = getLogger(__filename);
  6. /**
  7. * The AVModeration logic.
  8. */
  9. export default class AVModeration {
  10. /**
  11. * Constructs AV moderation room.
  12. *
  13. * @param {ChatRoom} room the main room.
  14. */
  15. constructor(room) {
  16. this._xmpp = room.xmpp;
  17. this._mainRoom = room;
  18. this._moderationEnabledByType = {
  19. [MediaType.AUDIO]: false,
  20. [MediaType.VIDEO]: false
  21. };
  22. this._whitelistAudio = [];
  23. this._whitelistVideo = [];
  24. this._xmpp.addListener(XMPPEvents.AV_MODERATION_RECEIVED, this._onMessage.bind(this));
  25. }
  26. /**
  27. * Whether AV moderation is supported on backend.
  28. *
  29. * @returns {boolean} whether AV moderation is supported on backend.
  30. */
  31. isSupported() {
  32. return Boolean(this._xmpp.avModerationComponentAddress);
  33. }
  34. /**
  35. * Enables or disables AV Moderation by sending a msg with command to the component.
  36. */
  37. enable(state, mediaType) {
  38. if (!this.isSupported() || !this._mainRoom.isModerator()) {
  39. logger.error(`Cannot enable:${state} AV moderation supported:${this.isSupported()},
  40. moderator:${this._mainRoom.isModerator()}`);
  41. return;
  42. }
  43. if (state === this._moderationEnabledByType[mediaType]) {
  44. logger.warn(`Moderation already in state:${state} for mediaType:${mediaType}`);
  45. return;
  46. }
  47. // send the enable/disable message
  48. const msg = $msg({ to: this._xmpp.avModerationComponentAddress });
  49. msg.c('av_moderation', {
  50. enable: state,
  51. mediaType
  52. }).up();
  53. this._xmpp.connection.send(msg);
  54. }
  55. /**
  56. * Approves that a participant can unmute by sending a msg with its jid to the component.
  57. */
  58. approve(mediaType, jid) {
  59. if (!this.isSupported() || !this._mainRoom.isModerator()) {
  60. logger.error(`Cannot approve in AV moderation supported:${this.isSupported()},
  61. moderator:${this._mainRoom.isModerator()}`);
  62. return;
  63. }
  64. // send a message to whitelist the jid and approve it to unmute
  65. const msg = $msg({ to: this._xmpp.avModerationComponentAddress });
  66. msg.c('av_moderation', {
  67. mediaType,
  68. jidToWhitelist: jid }).up();
  69. this._xmpp.connection.send(msg);
  70. }
  71. /**
  72. * Rejects that a participant can unmute by sending a msg with its jid to the component.
  73. */
  74. reject(mediaType, jid) {
  75. if (!this.isSupported() || !this._mainRoom.isModerator()) {
  76. logger.error(`Cannot reject in AV moderation supported:${this.isSupported()},
  77. moderator:${this._mainRoom.isModerator()}`);
  78. return;
  79. }
  80. // send a message to remove from whitelist the jid and reject it to unmute
  81. const msg = $msg({ to: this._xmpp.avModerationComponentAddress });
  82. msg.c('av_moderation', {
  83. mediaType,
  84. jidToBlacklist: jid
  85. }).up();
  86. this._xmpp.connection.send(msg);
  87. }
  88. /**
  89. * Receives av_moderation parsed messages as json.
  90. * @param obj the parsed json content of the message to process.
  91. * @private
  92. */
  93. _onMessage(obj) {
  94. const { removed, mediaType: media, enabled, approved, actor, whitelists: newWhitelists } = obj;
  95. if (newWhitelists) {
  96. const oldList = media === MediaType.AUDIO
  97. ? this._whitelistAudio
  98. : this._whitelistVideo;
  99. const newList = Array.isArray(newWhitelists[media]) ? newWhitelists[media] : [];
  100. if (removed) {
  101. oldList.filter(x => !newList.includes(x))
  102. .forEach(jid => this._xmpp.eventEmitter
  103. .emit(XMPPEvents.AV_MODERATION_PARTICIPANT_REJECTED, media, jid));
  104. } else {
  105. newList.filter(x => !oldList.includes(x))
  106. .forEach(jid => this._xmpp.eventEmitter
  107. .emit(XMPPEvents.AV_MODERATION_PARTICIPANT_APPROVED, media, jid));
  108. }
  109. if (media === MediaType.AUDIO) {
  110. this._whitelistAudio = newList;
  111. } else {
  112. this._whitelistVideo = newList;
  113. }
  114. } else if (enabled !== undefined && this._moderationEnabledByType[media] !== enabled) {
  115. this._moderationEnabledByType[media] = enabled;
  116. this._xmpp.eventEmitter.emit(XMPPEvents.AV_MODERATION_CHANGED, enabled, media, actor);
  117. } else if (removed) {
  118. this._xmpp.eventEmitter.emit(XMPPEvents.AV_MODERATION_REJECTED, media);
  119. } else if (approved) {
  120. this._xmpp.eventEmitter.emit(XMPPEvents.AV_MODERATION_APPROVED, media);
  121. }
  122. }
  123. }