Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

JitsiVideoSIPGWSession.ts 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import { getLogger } from '@jitsi/logger';
  2. import { $iq } from 'strophe.js';
  3. import Listenable from '../util/Listenable';
  4. import ChatRoom from '../xmpp/ChatRoom';
  5. import * as VideoSIPGWConstants from './VideoSIPGWConstants';
  6. const logger = getLogger('modules/videosipgw/JitsiVideoSIPGWSession');
  7. /**
  8. * The event name for current sip video session state changed.
  9. * @type {string} event name for sip video session state changed.
  10. */
  11. const STATE_CHANGED: string = 'STATE_CHANGED';
  12. /**
  13. * Jitsi video SIP GW session. Holding its state and able to start/stop it.
  14. * When session is in OFF or FAILED stated it cannot be used anymore.
  15. */
  16. export default class JitsiVideoSIPGWSession extends Listenable {
  17. sipAddress: string;
  18. displayName: string;
  19. chatRoom: ChatRoom;
  20. state?: string;
  21. /**
  22. * Creates new session with the desired sip address and display name.
  23. *
  24. * @param {string} sipAddress - The sip address to use when
  25. * starting the session.
  26. * @param {string} displayName - The display name to use for
  27. * that participant.
  28. * @param {ChatRoom} chatRoom - The chat room this session is bound to.
  29. */
  30. constructor(sipAddress: string, displayName: string, chatRoom: ChatRoom) {
  31. super();
  32. this.sipAddress = sipAddress;
  33. this.displayName = displayName;
  34. this.chatRoom = chatRoom;
  35. /*
  36. * The initial state is undefined. Initial state cannot be STATE_OFF,
  37. * the session enters this state when it was in STATE_ON and was stopped
  38. * and such session cannot be used anymore.
  39. *
  40. * @type {VideoSIPGWConstants|undefined}
  41. */
  42. this.state = undefined;
  43. }
  44. /**
  45. * Sends a jibri command using an iq.
  46. *
  47. * @private
  48. * @param {string} action - The action to send ('start' or 'stop').
  49. */
  50. private _sendJibriIQ(action: string): void {
  51. const attributes = {
  52. 'xmlns': 'http://jitsi.org/protocol/jibri',
  53. 'action': action,
  54. 'sipaddress': this.sipAddress,
  55. 'displayname': this.displayName
  56. };
  57. const iq = $iq({
  58. to: this.chatRoom.focusMucJid,
  59. type: 'set' })
  60. .c('jibri', attributes)
  61. .up();
  62. logger.debug(`${action} video SIP GW session`, iq.nodeTree);
  63. this.chatRoom.connection.sendIQ(
  64. iq,
  65. () => {}, // eslint-disable-line @typescript-eslint/no-empty-function
  66. (error: any) => {
  67. logger.error(
  68. `Failed to ${action} video SIP GW session, error: `, error);
  69. this.setState(VideoSIPGWConstants.STATE_FAILED);
  70. },
  71. undefined);
  72. }
  73. /**
  74. * Stops the current session.
  75. */
  76. stop(): void {
  77. if (this.state === VideoSIPGWConstants.STATE_OFF
  78. || this.state === VideoSIPGWConstants.STATE_FAILED) {
  79. logger.warn('Video SIP GW session already stopped or failed!');
  80. return;
  81. }
  82. this._sendJibriIQ('stop');
  83. }
  84. /**
  85. * Starts a new session. Sends an iq to the focus.
  86. */
  87. start(): void {
  88. // if state is off, this session was active for some reason
  89. // and we should create new one, rather than reusing it
  90. if (this.state === VideoSIPGWConstants.STATE_ON
  91. || this.state === VideoSIPGWConstants.STATE_OFF
  92. || this.state === VideoSIPGWConstants.STATE_PENDING
  93. || this.state === VideoSIPGWConstants.STATE_RETRYING) {
  94. logger.warn('Video SIP GW session already started!');
  95. return;
  96. }
  97. this._sendJibriIQ('start');
  98. }
  99. /**
  100. * Changes the state of this session.
  101. *
  102. * @param {string} newState - The new {VideoSIPGWConstants} state to set.
  103. * @param {string} [optional] failureReason - The reason why a failure state
  104. * was entered.
  105. * @returns {void}
  106. */
  107. setState(newState: string, failureReason?: string): void {
  108. if (newState === this.state) {
  109. return;
  110. }
  111. const oldState = this.state;
  112. this.state = newState;
  113. this.eventEmitter.emit(STATE_CHANGED,
  114. {
  115. address: this.sipAddress,
  116. failureReason,
  117. oldState,
  118. newState: this.state,
  119. displayName: this.displayName
  120. }
  121. );
  122. }
  123. /**
  124. * Subscribes the passed listener to the event for state change of this
  125. * session.
  126. *
  127. * @param {EventListener} listener - The function that will receive the event.
  128. */
  129. addStateListener(listener: EventListener): void {
  130. this.addListener(STATE_CHANGED, listener);
  131. }
  132. /**
  133. * Unsubscribes the passed handler.
  134. *
  135. * @param {EventListener} listener - The function to be removed.
  136. */
  137. removeStateListener(listener: EventListener): void {
  138. this.removeListener(STATE_CHANGED, listener);
  139. }
  140. }