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.

recording.js 5.1KB

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