123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- /**
- * Copyright(c) ali-sdk and other contributors.
- * MIT Licensed
- *
- * Authors:
- * rockuw <rockuw@gmail.com> (http://rockuw.com)
- */
- /**
- * Module dependencies.
- */
- const jstoxml = require('jstoxml');
- const utility = require('utility');
- const copy = require('copy-to');
- const urlutil = require('url');
- const 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 = async function putChannel(id, conf, options) {
- options = options || {};
- options.subres = 'live';
- const params = this._objectRequestParams('PUT', id, options);
- params.xmlResponse = true;
- params.content = jstoxml.toXML({
- LiveChannelConfiguration: conf
- });
- params.successStatuses = [200];
- const result = await this.request(params);
- let publishUrls = result.data.PublishUrls.Url;
- if (!Array.isArray(publishUrls)) {
- publishUrls = [publishUrls];
- }
- let playUrls = result.data.PlayUrls.Url;
- if (!Array.isArray(playUrls)) {
- playUrls = [playUrls];
- }
- return {
- publishUrls,
- playUrls,
- res: result.res
- };
- };
- /**
- * Get the channel info
- * @param {String} id the channel id
- * @param {Object} options
- * @return {Object}
- */
- proto.getChannel = async function getChannel(id, options) {
- options = options || {};
- options.subres = 'live';
- const params = this._objectRequestParams('GET', id, options);
- params.xmlResponse = true;
- params.successStatuses = [200];
- const result = await 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 = async function deleteChannel(id, options) {
- options = options || {};
- options.subres = 'live';
- const params = this._objectRequestParams('DELETE', id, options);
- params.successStatuses = [204];
- const result = await 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 = async function putChannelStatus(id, status, options) {
- options = options || {};
- options.subres = {
- live: null,
- status
- };
- const params = this._objectRequestParams('PUT', id, options);
- params.successStatuses = [200];
- const result = await this.request(params);
- return {
- res: result.res
- };
- };
- /**
- * Get the channel status
- * @param {String} id the channel id
- * @param {Object} options
- * @return {Object}
- */
- proto.getChannelStatus = async function getChannelStatus(id, options) {
- options = options || {};
- options.subres = {
- live: null,
- comp: 'stat'
- };
- const params = this._objectRequestParams('GET', id, options);
- params.xmlResponse = true;
- params.successStatuses = [200];
- const result = await 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 = async function listChannels(query, options) {
- // prefix, marker, max-keys
- options = options || {};
- options.subres = 'live';
- const params = this._objectRequestParams('GET', '', options);
- params.query = query;
- params.xmlResponse = true;
- params.successStatuses = [200];
- const result = await this.request(params);
- let channels = result.data.LiveChannel || [];
- if (!Array.isArray(channels)) {
- channels = [channels];
- }
- channels = channels.map((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,
- 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 = async function getChannelHistory(id, options) {
- options = options || {};
- options.subres = {
- live: null,
- comp: 'history'
- };
- const params = this._objectRequestParams('GET', id, options);
- params.xmlResponse = true;
- params.successStatuses = [200];
- const result = await this.request(params);
- let records = result.data.LiveRecord || [];
- if (!Array.isArray(records)) {
- records = [records];
- }
- return {
- 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 = async function createVod(id, name, time, options) {
- options = options || {};
- options.subres = {
- vod: null
- };
- copy(time).to(options.subres);
- const params = this._objectRequestParams('POST', `${id}/${name}`, options);
- params.query = time;
- params.successStatuses = [200];
- const result = await 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 || {};
- const expires = utility.timestamp() + (options.expires || 1800);
- const res = {
- bucket: this.options.bucket,
- object: this._objectName(`live/${channelId}`)
- };
- const resource = `/${res.bucket}/${channelId}`;
- options.params = options.params || {};
- const query = Object.keys(options.params).sort().map(x => `${x}:${options.params[x]}\n`).join('');
- const stringToSign = `${expires}\n${query}${resource}`;
- const signature = this.signature(stringToSign);
- const 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();
- };
|