forked from ali-sdk/ali-oss
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrtmp.js
293 lines (246 loc) · 6.63 KB
/
rtmp.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
/**
* 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();
};