UNPKG

6.79 kBJavaScriptView Raw
1/**
2 * Copyright(c) ali-sdk and other contributors.
3 * MIT Licensed
4 *
5 * Authors:
6 * rockuw <rockuw@gmail.com> (http://rockuw.com)
7 */
8
9
10/**
11 * Module dependencies.
12 */
13
14const jstoxml = require('jstoxml');
15const utility = require('utility');
16const copy = require('copy-to');
17const urlutil = require('url');
18
19const proto = exports;
20
21/**
22 * RTMP operations
23 */
24
25/**
26 * Create a live channel
27 * @param {String} id the channel id
28 * @param {Object} conf the channel configuration
29 * @param {Object} options
30 * @return {Object}
31 */
32proto.putChannel = async function putChannel(id, conf, options) {
33 options = options || {};
34 options.subres = 'live';
35
36 const params = this._objectRequestParams('PUT', id, options);
37 params.xmlResponse = true;
38 params.content = jstoxml.toXML({
39 LiveChannelConfiguration: conf
40 });
41 params.successStatuses = [200];
42
43 const result = await this.request(params);
44
45 let publishUrls = result.data.PublishUrls.Url;
46 if (!Array.isArray(publishUrls)) {
47 publishUrls = [publishUrls];
48 }
49 let playUrls = result.data.PlayUrls.Url;
50 if (!Array.isArray(playUrls)) {
51 playUrls = [playUrls];
52 }
53
54 return {
55 publishUrls,
56 playUrls,
57 res: result.res
58 };
59};
60
61/**
62 * Get the channel info
63 * @param {String} id the channel id
64 * @param {Object} options
65 * @return {Object}
66 */
67proto.getChannel = async function getChannel(id, options) {
68 options = options || {};
69 options.subres = 'live';
70
71 const params = this._objectRequestParams('GET', id, options);
72 params.xmlResponse = true;
73 params.successStatuses = [200];
74
75 const result = await this.request(params);
76
77 return {
78 data: result.data,
79 res: result.res
80 };
81};
82
83/**
84 * Delete the channel
85 * @param {String} id the channel id
86 * @param {Object} options
87 * @return {Object}
88 */
89proto.deleteChannel = async function deleteChannel(id, options) {
90 options = options || {};
91 options.subres = 'live';
92
93 const params = this._objectRequestParams('DELETE', id, options);
94 params.successStatuses = [204];
95
96 const result = await this.request(params);
97
98 return {
99 res: result.res
100 };
101};
102
103/**
104 * Set the channel status
105 * @param {String} id the channel id
106 * @param {String} status the channel status
107 * @param {Object} options
108 * @return {Object}
109 */
110proto.putChannelStatus = async function putChannelStatus(id, status, options) {
111 options = options || {};
112 options.subres = {
113 live: null,
114 status
115 };
116
117 const params = this._objectRequestParams('PUT', id, options);
118 params.successStatuses = [200];
119
120 const result = await this.request(params);
121
122 return {
123 res: result.res
124 };
125};
126
127/**
128 * Get the channel status
129 * @param {String} id the channel id
130 * @param {Object} options
131 * @return {Object}
132 */
133proto.getChannelStatus = async function getChannelStatus(id, options) {
134 options = options || {};
135 options.subres = {
136 live: null,
137 comp: 'stat'
138 };
139
140 const params = this._objectRequestParams('GET', id, options);
141 params.xmlResponse = true;
142 params.successStatuses = [200];
143
144 const result = await this.request(params);
145
146 return {
147 data: result.data,
148 res: result.res
149 };
150};
151
152/**
153 * List the channels
154 * @param {Object} query the query parameters
155 * filter options:
156 * - prefix {String}: the channel id prefix (returns channels with this prefix)
157 * - marker {String}: the channle id marker (returns channels after this id)
158 * - max-keys {Number}: max number of channels to return
159 * @param {Object} options
160 * @return {Object}
161 */
162proto.listChannels = async function listChannels(query, options) {
163 // prefix, marker, max-keys
164
165 options = options || {};
166 options.subres = 'live';
167
168 const params = this._objectRequestParams('GET', '', options);
169 params.query = query;
170 params.xmlResponse = true;
171 params.successStatuses = [200];
172
173 const result = await this.request(params);
174
175 let channels = result.data.LiveChannel || [];
176 if (!Array.isArray(channels)) {
177 channels = [channels];
178 }
179
180 channels = channels.map((x) => {
181 x.PublishUrls = x.PublishUrls.Url;
182 if (!Array.isArray(x.PublishUrls)) {
183 x.PublishUrls = [x.PublishUrls];
184 }
185 x.PlayUrls = x.PlayUrls.Url;
186 if (!Array.isArray(x.PlayUrls)) {
187 x.PlayUrls = [x.PlayUrls];
188 }
189
190 return x;
191 });
192
193 return {
194 channels,
195 nextMarker: result.data.NextMarker || null,
196 isTruncated: result.data.IsTruncated === 'true',
197 res: result.res
198 };
199};
200
201/**
202 * Get the channel history
203 * @param {String} id the channel id
204 * @param {Object} options
205 * @return {Object}
206 */
207proto.getChannelHistory = async function getChannelHistory(id, options) {
208 options = options || {};
209 options.subres = {
210 live: null,
211 comp: 'history'
212 };
213
214 const params = this._objectRequestParams('GET', id, options);
215 params.xmlResponse = true;
216 params.successStatuses = [200];
217
218 const result = await this.request(params);
219
220 let records = result.data.LiveRecord || [];
221 if (!Array.isArray(records)) {
222 records = [records];
223 }
224 return {
225 records,
226 res: result.res
227 };
228};
229
230/**
231 * Create vod playlist
232 * @param {String} id the channel id
233 * @param {String} name the playlist name
234 * @param {Object} time the begin and end time
235 * time:
236 * - startTime {Number}: the begin time in epoch seconds
237 * - endTime {Number}: the end time in epoch seconds
238 * @param {Object} options
239 * @return {Object}
240 */
241proto.createVod = async function createVod(id, name, time, options) {
242 options = options || {};
243 options.subres = {
244 vod: null
245 };
246 copy(time).to(options.subres);
247
248 const params = this._objectRequestParams('POST', `${id}/${name}`, options);
249 params.query = time;
250 params.successStatuses = [200];
251
252 const result = await this.request(params);
253
254 return {
255 res: result.res
256 };
257};
258
259/**
260 * Get RTMP Url
261 * @param {String} channelId the channel id
262 * @param {Object} options
263 * options:
264 * - expires {Number}: expire time in seconds
265 * - params {Object}: the parameters such as 'playlistName'
266 * @return {String} the RTMP url
267 */
268proto.getRtmpUrl = function (channelId, options) {
269 options = options || {};
270 const expires = utility.timestamp() + (options.expires || 1800);
271 const res = {
272 bucket: this.options.bucket,
273 object: this._objectName(`live/${channelId}`)
274 };
275 const resource = `/${res.bucket}/${channelId}`;
276
277 options.params = options.params || {};
278 const query = Object.keys(options.params).sort().map(x => `${x}:${options.params[x]}\n`).join('');
279
280 const stringToSign = `${expires}\n${query}${resource}`;
281 const signature = this.signature(stringToSign);
282
283 const url = urlutil.parse(this._getReqUrl(res));
284 url.protocol = 'rtmp:';
285 url.query = {
286 OSSAccessKeyId: this.options.accessKeyId,
287 Expires: expires,
288 Signature: signature
289 };
290 copy(options.params).to(url.query);
291
292 return url.format();
293};