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.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* global $, $iq, config, connection, focusMucJid, messageHandler, Moderator,
  2. Toolbar, Util */
  3. var Recording = (function (my) {
  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. my.setRecordingToken = function (token) {
  18. recordingToken = token;
  19. };
  20. my.setRecording = function (state, token, callback) {
  21. if (useJirecon){
  22. this.setRecordingJirecon(state, token, callback);
  23. } else {
  24. this.setRecordingColibri(state, token, callback);
  25. }
  26. };
  27. my.setRecordingJirecon = function (state, token, callback) {
  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. my.setRecordingColibri = function (state, token, callback) {
  62. var elem = $iq({to: 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. my.toggleRecording = function () {
  82. if (!Moderator.isModerator()) {
  83. console.log(
  84. 'non-focus, or conference not yet organized:' +
  85. ' not enabling recording');
  86. return;
  87. }
  88. // Jirecon does not (currently) support a token.
  89. if (!recordingToken && !useJirecon)
  90. {
  91. messageHandler.openTwoButtonDialog(null,
  92. '<h2>Enter recording token</h2>' +
  93. '<input id="recordingToken" type="text" ' +
  94. 'placeholder="token" autofocus>',
  95. false,
  96. "Save",
  97. function (e, v, m, f) {
  98. if (v) {
  99. var token = document.getElementById('recordingToken');
  100. if (token.value) {
  101. my.setRecordingToken(
  102. Util.escapeHtml(token.value));
  103. my.toggleRecording();
  104. }
  105. }
  106. },
  107. function (event) {
  108. document.getElementById('recordingToken').focus();
  109. },
  110. function () {}
  111. );
  112. return;
  113. }
  114. var oldState = recordingEnabled;
  115. Toolbar.setRecordingButtonState(!oldState);
  116. my.setRecording(!oldState,
  117. recordingToken,
  118. function (state) {
  119. console.log("New recording state: ", state);
  120. if (state === oldState)
  121. {
  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. my.setRecordingToken(null);
  141. }
  142. // Update with returned status
  143. Toolbar.setRecordingButtonState(state);
  144. }
  145. );
  146. };
  147. return my;
  148. }(Recording || {}));