|                                                                                                                                                                                                                                                                                                       |  | /** * 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();};
 |