Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

recording.js 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /* global $, $iq, config, connection, focusMucJid, messageHandler,
  2. Toolbar, Util */
  3. var Moderator = require("./moderator");
  4. var recordingToken = null;
  5. var recordingEnabled;
  6. /**
  7. * Whether to use a jirecon component for recording, or use the videobridge
  8. * through COLIBRI.
  9. */
  10. var useJirecon;
  11. /**
  12. * The ID of the jirecon recording session. Jirecon generates it when we
  13. * initially start recording, and it needs to be used in subsequent requests
  14. * to jirecon.
  15. */
  16. var jireconRid = null;
  17. /**
  18. * The callback to update the recording button. Currently used from colibri
  19. * after receiving a pending status.
  20. */
  21. var recordingStateChangeCallback = null;
  22. function setRecordingToken(token) {
  23. recordingToken = token;
  24. }
  25. function setRecordingJirecon(state, token, callback, connection) {
  26. if (state == recordingEnabled){
  27. return;
  28. }
  29. var iq = $iq({to: config.hosts.jirecon, type: 'set'})
  30. .c('recording', {xmlns: 'http://jitsi.org/protocol/jirecon',
  31. action: (state === 'on') ? 'start' : 'stop',
  32. mucjid: connection.emuc.roomjid});
  33. if (state === 'off'){
  34. iq.attrs({rid: jireconRid});
  35. }
  36. console.log('Start recording');
  37. connection.sendIQ(
  38. iq,
  39. function (result) {
  40. // TODO wait for an IQ with the real status, since this is
  41. // provisional?
  42. jireconRid = $(result).find('recording').attr('rid');
  43. console.log('Recording ' + ((state === 'on') ? 'started' : 'stopped') +
  44. '(jirecon)' + result);
  45. recordingEnabled = state;
  46. if (state === 'off'){
  47. jireconRid = null;
  48. }
  49. callback(state);
  50. },
  51. function (error) {
  52. console.log('Failed to start recording, error: ', error);
  53. callback(recordingEnabled);
  54. });
  55. }
  56. // Sends a COLIBRI message which enables or disables (according to 'state')
  57. // the recording on the bridge. Waits for the result IQ and calls 'callback'
  58. // with the new recording state, according to the IQ.
  59. function setRecordingColibri(state, token, callback, connection) {
  60. var elem = $iq({to: connection.emuc.focusMucJid, type: 'set'});
  61. elem.c('conference', {
  62. xmlns: 'http://jitsi.org/protocol/colibri'
  63. });
  64. elem.c('recording', {state: state, token: token});
  65. connection.sendIQ(elem,
  66. function (result) {
  67. console.log('Set recording "', state, '". Result:', result);
  68. var recordingElem = $(result).find('>conference>recording');
  69. var newState = recordingElem.attr('state');
  70. recordingEnabled = newState;
  71. callback(newState);
  72. if (newState === 'pending' && recordingStateChangeCallback == null) {
  73. recordingStateChangeCallback = callback;
  74. connection.addHandler(function(iq){
  75. var state = $(iq).find('recording').attr('state');
  76. if (state)
  77. recordingStateChangeCallback(state);
  78. }, 'http://jitsi.org/protocol/colibri', 'iq', null, null, null);
  79. }
  80. },
  81. function (error) {
  82. console.warn(error);
  83. callback(recordingEnabled);
  84. }
  85. );
  86. }
  87. function setRecording(state, token, callback, connection) {
  88. if (useJirecon){
  89. setRecordingJirecon(state, token, callback, connection);
  90. } else {
  91. setRecordingColibri(state, token, callback, connection);
  92. }
  93. }
  94. var Recording = {
  95. init: function () {
  96. useJirecon = config.hosts &&
  97. (typeof config.hosts.jirecon != "undefined");
  98. },
  99. toggleRecording: function (tokenEmptyCallback, recordingStateChangeCallback, connection) {
  100. if (!Moderator.isModerator()) {
  101. console.log(
  102. 'non-focus, or conference not yet organized:' +
  103. ' not enabling recording');
  104. return;
  105. }
  106. var self = this;
  107. // Jirecon does not (currently) support a token.
  108. if (!recordingToken && !useJirecon) {
  109. tokenEmptyCallback(function (value) {
  110. setRecordingToken(value);
  111. self.toggleRecording(tokenEmptyCallback, recordingStateChangeCallback, connection);
  112. });
  113. return;
  114. }
  115. var oldState = recordingEnabled;
  116. var newState = (oldState === 'off' || !oldState) ? 'on' : 'off';
  117. setRecording(newState,
  118. recordingToken,
  119. function (state) {
  120. console.log("New recording state: ", state);
  121. if (state === oldState) {
  122. // FIXME: new focus:
  123. // this will not work when moderator changes
  124. // during active session. Then it will assume that
  125. // recording status has changed to true, but it might have
  126. // been already true(and we only received actual status from
  127. // the focus).
  128. //
  129. // SO we start with status null, so that it is initialized
  130. // here and will fail only after second click, so if invalid
  131. // token was used we have to press the button twice before
  132. // current status will be fetched and token will be reset.
  133. //
  134. // Reliable way would be to return authentication error.
  135. // Or status update when moderator connects.
  136. // Or we have to stop recording session when current
  137. // moderator leaves the room.
  138. // Failed to change, reset the token because it might
  139. // have been wrong
  140. setRecordingToken(null);
  141. }
  142. recordingStateChangeCallback(state);
  143. },
  144. connection
  145. );
  146. }
  147. };
  148. module.exports = Recording;