選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

JibriSession.ts 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. import { $iq } from 'strophe.js';
  2. import recordingXMLUtils from './recordingXMLUtils';
  3. import JitsiParticipant from '../../JitsiParticipant';
  4. export interface IJibriSessionOptions {
  5. connection?: any;
  6. focusMucJid?: string;
  7. mode?: string;
  8. sessionID?: string;
  9. status?: string;
  10. }
  11. export interface IStartOptions {
  12. appData?: string;
  13. broadcastId?: string;
  14. focusMucJid: string;
  15. streamId?: string;
  16. }
  17. export interface IStopOptions {
  18. focusMucJid: string;
  19. }
  20. export interface IQOptions {
  21. action?: 'start' | 'stop';
  22. appData?: string;
  23. broadcastId?: string;
  24. focusMucJid: string;
  25. streamId?: string;
  26. }
  27. /**
  28. * Represents a recording session.
  29. */
  30. export default class JibriSession {
  31. private _connection?: any;
  32. private _mode?: string;
  33. private _jibriJid: string | null = null;
  34. private _statusFromJicofo: string = '';
  35. private _sessionID?: string;
  36. private _status?: string;
  37. private _error?: string;
  38. private _liveStreamViewURL?: string;
  39. private _initiator?: JitsiParticipant | string;
  40. private _terminator?: JitsiParticipant | string;
  41. private _focusMucJid?: string;
  42. /**
  43. * Initializes a new JibriSession instance.
  44. *
  45. * @constructor
  46. */
  47. constructor(options: IJibriSessionOptions = {}) {
  48. this._connection = options.connection;
  49. this._mode = options.mode;
  50. this._jibriJid = null;
  51. this._statusFromJicofo = '';
  52. this._setSessionID(options.sessionID);
  53. this.setStatus(options.status);
  54. this._focusMucJid = options.focusMucJid;
  55. }
  56. /**
  57. * Returns the error related to the session instance, if any.
  58. *
  59. * @returns {string|undefined}
  60. */
  61. getError(): string | undefined {
  62. return this._error;
  63. }
  64. /**
  65. * Returns the session ID of the session instance.
  66. *
  67. * @returns {string|undefined}
  68. */
  69. getID(): string | undefined {
  70. return this._sessionID;
  71. }
  72. /**
  73. * Returns the initiator of the session instance.
  74. *
  75. * @returns {JitsiParticipant|string} The participant that started the session.
  76. */
  77. getInitiator(): JitsiParticipant | string {
  78. return this._initiator;
  79. }
  80. /**
  81. * Returns the streaming URL of the session.
  82. *
  83. * @returns {string|undefined}
  84. */
  85. getLiveStreamViewURL(): string | undefined {
  86. return this._liveStreamViewURL;
  87. }
  88. /**
  89. * Returns the current status of the session.
  90. *
  91. * @returns {string|undefined}
  92. */
  93. getStatus(): string | undefined {
  94. // If _status is not set fallback to the status reported by jicofo.
  95. if (this._status) {
  96. return this._status;
  97. }
  98. return this._statusFromJicofo;
  99. }
  100. /**
  101. * @returns {string|undefined} the JID of jibri associated with this session.
  102. */
  103. getJibriJid(): string | undefined {
  104. return this._jibriJid;
  105. }
  106. /**
  107. * Returns the jid of the participant that stopped the session.
  108. *
  109. * @returns {JitsiParticipant|string} The participant that stopped the session.
  110. */
  111. getTerminator(): JitsiParticipant | string {
  112. return this._terminator;
  113. }
  114. /**
  115. * Returns the current recording mode of the session, such as "file".
  116. *
  117. * @returns {string}
  118. */
  119. getMode(): string {
  120. return this._mode;
  121. }
  122. /**
  123. * Sets the last known error message related to the session.
  124. *
  125. * @param {string} error - The error string explaining why the session
  126. * entered an error state.
  127. * @returns {void}
  128. */
  129. setError(error: string): void {
  130. this._error = error;
  131. }
  132. /**
  133. * Sets the last live stream URL for the session instance. Usually this is
  134. * a YouTube URL and usually this is only set for "stream" sessions.
  135. *
  136. * @param {string} url - The live stream URL associated with the session.
  137. * @returns {void}
  138. */
  139. setLiveStreamViewURL(url: string): void {
  140. this._liveStreamViewURL = url;
  141. }
  142. /**
  143. * Sets the last known status for this recording session.
  144. *
  145. * @param {string} status - The new status to set.
  146. * @returns {void}
  147. */
  148. setStatus(status?: string): void {
  149. this._status = status;
  150. }
  151. /**
  152. * Set the session status reported by jicofo. If a jibri is present in the room,
  153. * the status is always 'on'. Otherwise, we fallback to the status reported by jicofo.
  154. *
  155. * @param {string} status
  156. */
  157. setStatusFromJicofo(status: string): void {
  158. this._statusFromJicofo = status;
  159. }
  160. /**
  161. * Set the JID of the jibri associated with this session.
  162. *
  163. * @param {*} jibriJid
  164. */
  165. setJibriJid(jibriJid: string | null): void {
  166. this._jibriJid = jibriJid;
  167. }
  168. /**
  169. * Sets the participant that started the session.
  170. * @param {JitsiParticipant | string} participant - The participant or resource id
  171. * if local participant.
  172. */
  173. setInitiator(participant: JitsiParticipant | string): void {
  174. this._initiator = participant;
  175. }
  176. /**
  177. * Sets the participant that stopped the session.
  178. * @param {JitsiParticipant | string} participant - The participant or the resource id
  179. * if local participant.
  180. */
  181. setTerminator(participant: JitsiParticipant | string): void {
  182. this._terminator = participant;
  183. }
  184. /**
  185. * Sends a message to start the actual recording.
  186. *
  187. * @param {Object} options - Additional arguments for starting the
  188. * recording.
  189. * @param {string} [options.appData] - Data specific to the app/service that
  190. * the result file will be uploaded.
  191. * @param {string} [options.broadcastId] - The broadcast ID of an
  192. * associated YouTube stream, used for knowing the URL from which the stream
  193. * can be viewed.
  194. * @param {string} options.focusMucJid - The JID of the focus participant
  195. * that controls recording.
  196. * @param {streamId} options.streamId - Necessary for live streaming, this
  197. * is the stream key needed to start a live streaming session with the
  198. * streaming service provider.
  199. * @returns Promise
  200. */
  201. start({ appData, broadcastId, focusMucJid, streamId }: IStartOptions): Promise<void> {
  202. return new Promise((resolve, reject) => {
  203. this._connection?.sendIQ(
  204. this._createIQ({
  205. action: 'start',
  206. appData,
  207. focusMucJid,
  208. broadcastId,
  209. streamId
  210. }),
  211. (result: any) => {
  212. this.setStatus('pending');
  213. this._setSessionID(
  214. recordingXMLUtils.getSessionIdFromIq(result)
  215. );
  216. resolve();
  217. },
  218. (error: any) => {
  219. this._setErrorFromIq(error);
  220. reject(error);
  221. }
  222. );
  223. });
  224. }
  225. /**
  226. * Sends a message to actually stop the recording session.
  227. *
  228. * @param {Object} options - Additional arguments for stopping the
  229. * recording.
  230. * @param {Object} options.focusMucJid - The JID of the focus participant
  231. * that controls recording.
  232. * @returns Promise
  233. */
  234. stop({ focusMucJid }: IStopOptions): Promise<any> {
  235. return new Promise((resolve, reject) => {
  236. this._connection?.sendIQ(
  237. this._createIQ({
  238. action: 'stop',
  239. focusMucJid
  240. }),
  241. resolve,
  242. reject
  243. );
  244. });
  245. }
  246. /**
  247. * Generates the message to change the status of the recording session.
  248. *
  249. * @param {string} [options.action] - The action to set the IQ
  250. * @param {string} [options.appData] - Data specific to the app/service that
  251. * the result file will be uploaded.
  252. * @param {string} [options.broadcastId] - The broadcast ID of an
  253. * associated YouTube stream, used for knowing the URL from which the stream
  254. * can be viewed.
  255. * @param {string} options.focusMucJid - The JID of the focus participant
  256. * that controls recording.
  257. * @param {streamId} options.streamId - Necessary for live streaming, this
  258. * is the stream key needed to start a live streaming session with the
  259. * streaming service provider.
  260. * @returns Object - The XMPP IQ message.
  261. */
  262. _createIQ({ action, appData, broadcastId, focusMucJid, streamId }: IQOptions) {
  263. return $iq({
  264. to: focusMucJid,
  265. type: 'set'
  266. })
  267. .c('jibri', {
  268. 'xmlns': 'http://jitsi.org/protocol/jibri',
  269. 'action': action,
  270. 'app_data': appData,
  271. 'recording_mode': this._mode,
  272. 'streamid': streamId,
  273. 'you_tube_broadcast_id': broadcastId
  274. })
  275. .up();
  276. }
  277. /**
  278. * Handles the error from an iq and stores the error.
  279. *
  280. * @param {Node} errorIq - The error response from an Iq.
  281. * @private
  282. * @returns {void}
  283. */
  284. _setErrorFromIq(errorIq: any): void {
  285. const error = errorIq.getElementsByTagName('error')[0];
  286. this.setError(error.children[0].tagName);
  287. }
  288. /**
  289. * Sets the known session ID for this recording session.
  290. *
  291. * @param {string} sessionID
  292. * @private
  293. * @returns {void}
  294. */
  295. _setSessionID(sessionID?: string): void {
  296. this._sessionID = sessionID;
  297. }
  298. }