1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | const jstoxml = require('jstoxml');
|
15 | const utility = require('utility');
|
16 | const copy = require('copy-to');
|
17 | const urlutil = require('url');
|
18 |
|
19 | const proto = exports;
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | proto.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 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | proto.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 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 | proto.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 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 | proto.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 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 | proto.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 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 | proto.listChannels = async function listChannels(query, options) {
|
163 |
|
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 |
|
203 |
|
204 |
|
205 |
|
206 |
|
207 | proto.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 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 | proto.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 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 |
|
266 |
|
267 |
|
268 | proto.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 | };
|