298 lines
6.6 KiB
JavaScript
298 lines
6.6 KiB
JavaScript
/**
|
|
* Copyright(c) ali-sdk and other contributors.
|
|
* MIT Licensed
|
|
*
|
|
* Authors:
|
|
* rockuw <rockuw@gmail.com> (http://rockuw.com)
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Module dependencies.
|
|
*/
|
|
|
|
var debug = require('debug')('ali-oss:rtmp');
|
|
var jstoxml = require('jstoxml');
|
|
var utility = require('utility');
|
|
var copy = require('copy-to');
|
|
var urlutil = require('url');
|
|
|
|
var proto = exports;
|
|
|
|
/**
|
|
* RTMP operations
|
|
*/
|
|
|
|
/**
|
|
* Create a live channel
|
|
* @param {String} id the channel id
|
|
* @param {Object} conf the channel configuration
|
|
* @param {Object} options
|
|
* @return {Object}
|
|
*/
|
|
proto.putChannel = function* (id, conf, options) {
|
|
options = options || {};
|
|
options.subres = 'live';
|
|
|
|
var params = this._objectRequestParams('PUT', id, options);
|
|
params.xmlResponse = true;
|
|
params.content = jstoxml.toXML({
|
|
LiveChannelConfiguration: conf
|
|
});
|
|
params.successStatuses = [200];
|
|
|
|
var result = yield this.request(params);
|
|
|
|
var publishUrls = result.data.PublishUrls.Url;
|
|
if (!Array.isArray(publishUrls)) {
|
|
publishUrls = [publishUrls];
|
|
}
|
|
var playUrls = result.data.PlayUrls.Url;
|
|
if (!Array.isArray(playUrls)) {
|
|
playUrls = [playUrls];
|
|
}
|
|
|
|
return {
|
|
publishUrls: publishUrls,
|
|
playUrls: playUrls,
|
|
res: result.res
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Get the channel info
|
|
* @param {String} id the channel id
|
|
* @param {Object} options
|
|
* @return {Object}
|
|
*/
|
|
proto.getChannel = function* (id, options) {
|
|
options = options || {};
|
|
options.subres = 'live';
|
|
|
|
var params = this._objectRequestParams('GET', id, options);
|
|
params.xmlResponse = true;
|
|
params.successStatuses = [200];
|
|
|
|
var result = yield this.request(params);
|
|
|
|
return {
|
|
data: result.data,
|
|
res: result.res
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Delete the channel
|
|
* @param {String} id the channel id
|
|
* @param {Object} options
|
|
* @return {Object}
|
|
*/
|
|
proto.deleteChannel = function* (id, options) {
|
|
options = options || {};
|
|
options.subres = 'live';
|
|
|
|
var params = this._objectRequestParams('DELETE', id, options);
|
|
params.successStatuses = [204];
|
|
|
|
var result = yield this.request(params);
|
|
|
|
return {
|
|
res: result.res
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Set the channel status
|
|
* @param {String} id the channel id
|
|
* @param {String} status the channel status
|
|
* @param {Object} options
|
|
* @return {Object}
|
|
*/
|
|
proto.putChannelStatus = function* (id, status, options) {
|
|
options = options || {};
|
|
options.subres = {
|
|
'live': null,
|
|
'status': status
|
|
};
|
|
|
|
var params = this._objectRequestParams('PUT', id, options);
|
|
params.successStatuses = [200];
|
|
|
|
var result = yield this.request(params);
|
|
|
|
return {
|
|
res: result.res,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Get the channel status
|
|
* @param {String} id the channel id
|
|
* @param {Object} options
|
|
* @return {Object}
|
|
*/
|
|
proto.getChannelStatus = function* (id, options) {
|
|
options = options || {};
|
|
options.subres = {
|
|
'live': null,
|
|
'comp': 'stat'
|
|
};
|
|
|
|
var params = this._objectRequestParams('GET', id, options);
|
|
params.xmlResponse = true;
|
|
params.successStatuses = [200];
|
|
|
|
var result = yield this.request(params);
|
|
|
|
return {
|
|
data: result.data,
|
|
res: result.res
|
|
};
|
|
};
|
|
|
|
/**
|
|
* List the channels
|
|
* @param {Object} query the query parameters
|
|
* filter options:
|
|
* - prefix {String}: the channel id prefix (returns channels with this prefix)
|
|
* - marker {String}: the channle id marker (returns channels after this id)
|
|
* - max-keys {Number}: max number of channels to return
|
|
* @param {Object} options
|
|
* @return {Object}
|
|
*/
|
|
proto.listChannels = function* (query, options) {
|
|
// prefix, marker, max-keys
|
|
|
|
options = options || {};
|
|
options.subres = 'live';
|
|
|
|
var params = this._objectRequestParams('GET', '', options);
|
|
params.query = query;
|
|
params.xmlResponse = true;
|
|
params.successStatuses = [200];
|
|
|
|
var result = yield this.request(params);
|
|
|
|
var channels = result.data.LiveChannel || [];
|
|
if (!Array.isArray(channels)) {
|
|
channels = [channels];
|
|
}
|
|
|
|
channels = channels.map(function (x) {
|
|
x.PublishUrls = x.PublishUrls.Url;
|
|
if (!Array.isArray(x.PublishUrls)) {
|
|
x.PublishUrls = [x.PublishUrls];
|
|
}
|
|
x.PlayUrls = x.PlayUrls.Url;
|
|
if (!Array.isArray(x.PlayUrls)) {
|
|
x.PlayUrls = [x.PlayUrls];
|
|
}
|
|
|
|
return x;
|
|
});
|
|
|
|
return {
|
|
channels: channels,
|
|
nextMarker: result.data.NextMarker || null,
|
|
isTruncated: result.data.IsTruncated === 'true',
|
|
res: result.res
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Get the channel history
|
|
* @param {String} id the channel id
|
|
* @param {Object} options
|
|
* @return {Object}
|
|
*/
|
|
proto.getChannelHistory = function* (id, options) {
|
|
options = options || {};
|
|
options.subres = {
|
|
'live': null,
|
|
'comp': 'history'
|
|
};
|
|
|
|
var params = this._objectRequestParams('GET', id, options);
|
|
params.xmlResponse = true;
|
|
params.successStatuses = [200];
|
|
|
|
var result = yield this.request(params);
|
|
|
|
var records = result.data.LiveRecord || [];
|
|
if (!Array.isArray(records)) {
|
|
records = [records];
|
|
}
|
|
return {
|
|
records: records,
|
|
res: result.res
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Create vod playlist
|
|
* @param {String} id the channel id
|
|
* @param {String} name the playlist name
|
|
* @param {Object} time the begin and end time
|
|
* time:
|
|
* - startTime {Number}: the begin time in epoch seconds
|
|
* - endTime {Number}: the end time in epoch seconds
|
|
* @param {Object} options
|
|
* @return {Object}
|
|
*/
|
|
proto.createVod = function* (id, name, time, options) {
|
|
options = options || {};
|
|
options.subres = {
|
|
'vod': null
|
|
}
|
|
copy(time).to(options.subres);
|
|
|
|
var params = this._objectRequestParams('POST', id + '/' + name, options);
|
|
params.query = time;
|
|
params.successStatuses = [200];
|
|
|
|
var result = yield this.request(params);
|
|
|
|
return {
|
|
res: result.res
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Get RTMP Url
|
|
* @param {String} channelId the channel id
|
|
* @param {Object} options
|
|
* options:
|
|
* - expires {Number}: expire time in seconds
|
|
* - params {Object}: the parameters such as 'playlistName'
|
|
* @return {String} the RTMP url
|
|
*/
|
|
proto.getRtmpUrl = function (channelId, options) {
|
|
options = options || {};
|
|
var expires = utility.timestamp() + (options.expires || 1800);
|
|
var res = {
|
|
bucket: this.options.bucket,
|
|
object: this._objectName('live/' + channelId)
|
|
};
|
|
var resource = '/' + res.bucket + '/' + channelId;
|
|
|
|
options.params = options.params || {};
|
|
var query = Object.keys(options.params).sort().map(function (x) {
|
|
return x + ':' + options.params[x] + '\n';
|
|
}).join('');
|
|
|
|
var stringToSign = expires + '\n' + query + resource;
|
|
var signature = this.signature(stringToSign);
|
|
|
|
var url = urlutil.parse(this._getReqUrl(res));
|
|
url.protocol = 'rtmp:';
|
|
url.query = {
|
|
OSSAccessKeyId: this.options.accessKeyId,
|
|
Expires: expires,
|
|
Signature: signature
|
|
}
|
|
copy(options.params).to(url.query);
|
|
|
|
return url.format();
|
|
}
|