Merge pull request #643 from jitsi/fix-recorder-error-states

Fix recorder error and state handling
This commit is contained in:
Paweł Domas 2016-05-05 14:50:51 -05:00
commit 50f261effc
4 changed files with 86 additions and 27 deletions

View File

@ -7,6 +7,8 @@ import AuthHandler from './modules/UI/authentication/AuthHandler';
import ConnectionQuality from './modules/connectionquality/connectionquality'; import ConnectionQuality from './modules/connectionquality/connectionquality';
import Recorder from './modules/recorder/Recorder';
import CQEvents from './service/connectionquality/CQEvents'; import CQEvents from './service/connectionquality/CQEvents';
import UIEvents from './service/UI/UIEvents'; import UIEvents from './service/UI/UIEvents';
@ -346,6 +348,9 @@ export default {
devices => APP.UI.onAvailableDevicesChanged(devices) devices => APP.UI.onAvailableDevicesChanged(devices)
); );
} }
if (config.iAmRecorder)
this.recorder = new Recorder();
// XXX The API will take care of disconnecting from the XMPP server // XXX The API will take care of disconnecting from the XMPP server
// (and, thus, leaving the room) on unload. // (and, thus, leaving the room) on unload.
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -878,10 +883,6 @@ export default {
room.on(ConferenceEvents.RECORDER_STATE_CHANGED, (status, error) => { room.on(ConferenceEvents.RECORDER_STATE_CHANGED, (status, error) => {
console.log("Received recorder status change: ", status, error); console.log("Received recorder status change: ", status, error);
if(status == "error") {
console.error(error);
return;
}
APP.UI.updateRecordingState(status); APP.UI.updateRecordingState(status);
}); });

View File

@ -268,7 +268,8 @@
"on": "Recording", "on": "Recording",
"off": "Recording stopped", "off": "Recording stopped",
"failedToStart": "Recording failed to start", "failedToStart": "Recording failed to start",
"buttonTooltip": "Start / stop recording" "buttonTooltip": "Start / stop recording",
"error": "Recording failed. Please try again."
}, },
"liveStreaming": "liveStreaming":
{ {
@ -278,6 +279,7 @@
"unavailable": "The live streaming service is currently unavailable. Please try again later.", "unavailable": "The live streaming service is currently unavailable. Please try again later.",
"failedToStart": "Live streaming failed to start", "failedToStart": "Live streaming failed to start",
"buttonTooltip": "Start / stop live stream", "buttonTooltip": "Start / stop live stream",
"streamIdRequired": "Please fill in the stream id in order to launch the live streaming." "streamIdRequired": "Please fill in the stream id in order to launch the live streaming.",
"error": "Live streaming failed. Please try again"
} }
} }

View File

@ -205,7 +205,8 @@ var Status = {
OFF: "off", OFF: "off",
AVAILABLE: "available", AVAILABLE: "available",
UNAVAILABLE: "unavailable", UNAVAILABLE: "unavailable",
PENDING: "pending" PENDING: "pending",
ERROR: "error"
}; };
/** /**
@ -248,6 +249,7 @@ var Recording = {
this.recordingOffKey = "liveStreaming.off"; this.recordingOffKey = "liveStreaming.off";
this.recordingPendingKey = "liveStreaming.pending"; this.recordingPendingKey = "liveStreaming.pending";
this.failedToStartKey = "liveStreaming.failedToStart"; this.failedToStartKey = "liveStreaming.failedToStart";
this.recordingErrorKey = "liveStreaming.error";
this.recordingButtonTooltip = "liveStreaming.buttonTooltip"; this.recordingButtonTooltip = "liveStreaming.buttonTooltip";
} }
else { else {
@ -256,6 +258,7 @@ var Recording = {
this.recordingOffKey = "recording.off"; this.recordingOffKey = "recording.off";
this.recordingPendingKey = "recording.pending"; this.recordingPendingKey = "recording.pending";
this.failedToStartKey = "recording.failedToStart"; this.failedToStartKey = "recording.failedToStart";
this.recordingErrorKey = "recording.error";
this.recordingButtonTooltip = "recording.buttonTooltip"; this.recordingButtonTooltip = "recording.buttonTooltip";
} }
@ -338,7 +341,6 @@ var Recording = {
*/ */
updateRecordingUI (recordingState) { updateRecordingUI (recordingState) {
let buttonSelector = $('#toolbar_button_record'); let buttonSelector = $('#toolbar_button_record');
let labelSelector = $('#recordingLabel');
// TODO: handle recording state=available // TODO: handle recording state=available
if (recordingState === Status.ON) { if (recordingState === Status.ON) {
@ -346,11 +348,9 @@ var Recording = {
buttonSelector.removeClass(this.baseClass); buttonSelector.removeClass(this.baseClass);
buttonSelector.addClass(this.baseClass + " active"); buttonSelector.addClass(this.baseClass + " active");
labelSelector.attr("data-i18n", this.recordingOnKey); this._updateStatusLabel(this.recordingOnKey, false);
moveToCorner(labelSelector, true, 3000); }
labelSelector else if (recordingState === Status.OFF
.text(APP.translation.translateString(this.recordingOnKey));
} else if (recordingState === Status.OFF
|| recordingState === Status.UNAVAILABLE) { || recordingState === Status.UNAVAILABLE) {
// We don't want to do any changes if this is // We don't want to do any changes if this is
@ -362,15 +362,13 @@ var Recording = {
buttonSelector.removeClass(this.baseClass + " active"); buttonSelector.removeClass(this.baseClass + " active");
buttonSelector.addClass(this.baseClass); buttonSelector.addClass(this.baseClass);
moveToCorner(labelSelector, false);
let messageKey; let messageKey;
if (this.currentState === Status.PENDING) if (this.currentState === Status.PENDING)
messageKey = this.failedToStartKey; messageKey = this.failedToStartKey;
else else
messageKey = this.recordingOffKey; messageKey = this.recordingOffKey;
labelSelector.attr("data-i18n", messageKey); this._updateStatusLabel(messageKey, true);
labelSelector.text(APP.translation.translateString(messageKey));
setTimeout(function(){ setTimeout(function(){
$('#recordingLabel').css({display: "none"}); $('#recordingLabel').css({display: "none"});
@ -381,16 +379,19 @@ var Recording = {
buttonSelector.removeClass(this.baseClass + " active"); buttonSelector.removeClass(this.baseClass + " active");
buttonSelector.addClass(this.baseClass); buttonSelector.addClass(this.baseClass);
moveToCorner(labelSelector, false); this._updateStatusLabel(this.recordingPendingKey, true);
labelSelector }
.attr("data-i18n", this.recordingPendingKey); else if (recordingState === Status.ERROR) {
labelSelector buttonSelector.removeClass(this.baseClass + " active");
.text(APP.translation.translateString( buttonSelector.addClass(this.baseClass);
this.recordingPendingKey));
this._updateStatusLabel(this.recordingErrorKey, true);
} }
this.currentState = recordingState; this.currentState = recordingState;
let labelSelector = $('#recordingLabel');
// We don't show the label for available state. // We don't show the label for available state.
if (recordingState !== Status.AVAILABLE if (recordingState !== Status.AVAILABLE
&& !labelSelector.is(":visible")) && !labelSelector.is(":visible"))
@ -404,6 +405,20 @@ var Recording = {
this.eventEmitter.emit(UIEvents.RECORDING_TOGGLED, this.eventEmitter.emit(UIEvents.RECORDING_TOGGLED,
this.predefinedToken); this.predefinedToken);
} }
},
/**
* Updates the status label.
* @param textKey the text to show
* @param isCentered indicates if the label should be centered on the window
* or moved to the top right corner.
*/
_updateStatusLabel(textKey, isCentered) {
let labelSelector = $('#recordingLabel');
moveToCorner(labelSelector, !isCentered);
labelSelector.attr("data-i18n", textKey);
labelSelector.text(APP.translation.translateString(textKey));
} }
}; };

View File

@ -0,0 +1,41 @@
/* global APP, $, config */
/**
* The (name of the) command which transports the recorder info.
*/
const _USER_INFO_COMMAND = "userinfo";
/**
* The Recorder class is meant to take care of recorder related presence
* commands.
*/
class Recorder {
constructor() {
if (config.iAmRecorder)
this._sendRecorderInfo();
}
/**
* Sends the information that this is a recorder through the presence.
* @private
*/
_sendRecorderInfo() {
var commands = APP.conference.commands;
// XXX The "Follow Me" command represents a snapshot of all states
// which are to be followed so don't forget to removeCommand before
// sendCommand!
commands.removeCommand(_USER_INFO_COMMAND);
var self = this;
commands.sendCommand(
_USER_INFO_COMMAND,
{
attributes: {
xmlns: 'http://jitsi.org/jitmeet/userinfo',
robot: true
}
});
}
}
export default Recorder;