Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
220 lines
6 KiB
JavaScript
Executable file
220 lines
6 KiB
JavaScript
Executable file
/* global mDBG */
|
|
(function(exports) {
|
|
'use strict';
|
|
|
|
/**
|
|
* This object parses and process the message casted
|
|
* between receiver and controller.
|
|
*
|
|
* The message casted is in JSON and shall carry properties below:
|
|
* - seq: Number. The sequence of message sent. Increased by 1 when sending
|
|
* one new message. The message sequences from controller and receiver
|
|
* shall be independent to each other.
|
|
* - type: String. Indicate the message type.
|
|
* - other extra properties depending on the type
|
|
*
|
|
* For example, the message of loading request from a controller may be like:
|
|
* {
|
|
* 'seq': 3,
|
|
* 'type': 'load',
|
|
* 'url': 'http://www.example.com/foo.ogg'
|
|
* }
|
|
*/
|
|
var castingMessage = {};
|
|
|
|
castingMessage.type = Object.freeze({
|
|
|
|
/**
|
|
* Represent the device info.
|
|
* The extra message properties:
|
|
* - displayName: String. The device display name
|
|
*/
|
|
'device-info': {
|
|
name: 'device-info',
|
|
sanitizeMsg: function (msg) {
|
|
|
|
if (msg.displayName !== undefined &&
|
|
typeof msg.displayName != 'string'
|
|
) {
|
|
throw new Error('Ilegal display name = ' + msg.displayName +
|
|
' in casting message of type = ' + this.name);
|
|
}
|
|
return msg;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Represent acknowledgement of message receiving.
|
|
* The extra message properties:
|
|
* - error: String. Present if there is error
|
|
*/
|
|
ack: {
|
|
name: 'ack',
|
|
sanitizeMsg: function (msg) {
|
|
|
|
if (msg.error !== null &&
|
|
msg.error !== undefined &&
|
|
typeof msg.error != 'string'
|
|
) {
|
|
throw new Error('Ilegal error = ' + msg.error +
|
|
' in casting message of type = ' + this.name);
|
|
}
|
|
return msg;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Represent video playing status. The extra message properties:
|
|
* - time: Number. The current video time
|
|
* - status: String. Describe status, could be
|
|
* - buffering: Video buffering
|
|
* - loaded: The media's metadata has finished loading;
|
|
* all attributes now contain as much useful information
|
|
* as they're going to.
|
|
* - buffered: Video buffered and ready to play
|
|
* - playing: Video is playing
|
|
* - seeked: Video seeking is done
|
|
* - stopped: Video is not playing (maybe ended or paused).
|
|
* - error: Error on playing.
|
|
* When error occurs, one more extra message properties:
|
|
* - error: String. The error code.
|
|
*/
|
|
status: {
|
|
name: 'status',
|
|
sanitizeMsg: function (msg) {
|
|
|
|
if (typeof msg.time != 'number' || (msg.time >= 0) === false) {
|
|
throw new Error('Ilegal time = ' + msg.time +
|
|
' in casting message of type = ' + this.name);
|
|
}
|
|
|
|
var validStatus = [
|
|
'buffering', 'loaded', 'buffered',
|
|
'playing', 'seeked', 'stopped', 'error'
|
|
];
|
|
if (validStatus.indexOf(msg.status) < 0) {
|
|
throw new Error('Ilegal status = ' + msg.status +
|
|
' in casting message of type = ' + this.name);
|
|
}
|
|
|
|
if (msg.status == 'error' && typeof msg.error != 'string') {
|
|
throw new Error('Ilegal error = ' + msg.error +
|
|
' in casting message of type = ' + this.name);
|
|
}
|
|
|
|
return msg;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Request to load and play video. The extra message properties:
|
|
* - url : String. The video url.
|
|
*/
|
|
load: {
|
|
name: 'load',
|
|
sanitizeMsg: function (msg) {
|
|
if (typeof msg.url != 'string' || !msg.url) {
|
|
throw new Error('Ilegal url = ' + msg.url +
|
|
' in casting message of type = ' + this.name);
|
|
}
|
|
return msg;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Request to play video
|
|
*/
|
|
play: {
|
|
name: 'play'
|
|
},
|
|
|
|
/**
|
|
* Request to pause video
|
|
*/
|
|
pause: {
|
|
name: 'pause'
|
|
},
|
|
|
|
/**
|
|
* Request to seek on video. The extra message properties:
|
|
* - time: Number. The time to seek.
|
|
*/
|
|
seek: {
|
|
name: 'seek',
|
|
sanitizeMsg: function (msg) {
|
|
if (typeof msg.time != 'number' || (msg.time >= 0) === false) {
|
|
throw new Error('Ilegal time in casting message of type = ' +
|
|
this.name, msg.time);
|
|
}
|
|
return msg;
|
|
}
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Validate and make sure the message format, datatype.
|
|
*
|
|
* @param {Object} content the message content to sanitize
|
|
* @return {Object} Sanitized message
|
|
*/
|
|
castingMessage.sanitizeMsg = function (content) {
|
|
mDBG.log('castingMessage#sanitizeMsg');
|
|
mDBG.log('Sanitize message content:', content);
|
|
|
|
if (this.type[content.type]) {
|
|
|
|
if (typeof content.seq == 'number' && content.seq >= 0) {
|
|
|
|
if (typeof this.type[content.type].sanitizeMsg == 'function') {
|
|
content = this.type[content.type].sanitizeMsg(content);
|
|
}
|
|
|
|
} else {
|
|
throw new Error('Missing sequence of casting message : ' +
|
|
JSON.stringify(content));
|
|
}
|
|
|
|
} else {
|
|
throw new Error('Unknown type of casting message : ' + content.type);
|
|
}
|
|
return content;
|
|
};
|
|
|
|
/**
|
|
* @param {String} txt the message txt sent from controller
|
|
* @return {Array.<Object>} the parsed messages
|
|
*/
|
|
castingMessage.parse = function (txt) {
|
|
mDBG.log('castingMessage#parse');
|
|
mDBG.log('Parsing : ', txt);
|
|
|
|
var data = '[' + txt.replace(/}{/g, '},{') + ']';
|
|
mDBG.log('Transformed : ', data);
|
|
|
|
var msgs = JSON.parse(data);
|
|
mDBG.log('JSON Parsed : ', msgs);
|
|
|
|
var results = [];
|
|
msgs.forEach((m) => {
|
|
try {
|
|
results.push(this.sanitizeMsg(m));
|
|
} catch (e) {
|
|
mDBG.error(e);
|
|
}
|
|
});
|
|
mDBG.log('Sanitized : ', results);
|
|
|
|
return results;
|
|
};
|
|
|
|
/**
|
|
* @param {Object} content the message content being sent.
|
|
* @return {String} the messsage txt to sent
|
|
*/
|
|
castingMessage.stringify = function (content) {
|
|
return JSON.stringify(this.sanitizeMsg(content));
|
|
};
|
|
|
|
exports.castingMessage = castingMessage;
|
|
|
|
})(window);
|