1
+ <?php
2
+ /**
3
+ * @link http://www.tintsoft.com/
4
+ * @copyright Copyright (c) 2012 TintSoft Technology Co. Ltd.
5
+ * @license http://www.tintsoft.com/license/
6
+ */
7
+ namespace aliyun \live ;
8
+
9
+ use yii \base \Component ;
10
+ use yii \base \InvalidConfigException ;
11
+ use GuzzleHttp \HandlerStack ;
12
+ use GuzzleHttp \Client as HttpClient ;
13
+ use aliyun \guzzle \subscriber \Rpc ;
14
+
15
+ /**
16
+ * Class Client
17
+ * @package aliyun\live
18
+ */
19
+ class Live extends Component
20
+ {
21
+ /**
22
+ * @var string
23
+ */
24
+ public $ accessKeyId ;
25
+
26
+ /**
27
+ * @var string
28
+ */
29
+ public $ accessSecret ;
30
+
31
+ /**
32
+ * @var string API版本
33
+ */
34
+ public $ version = '2016-11-01 ' ;
35
+
36
+ /**
37
+ * @var string 网关地址
38
+ */
39
+ public $ baseUri = 'https://live.aliyuncs.com/ ' ;
40
+
41
+ /**
42
+ * @var string 应用名称
43
+ */
44
+ public $ appName ;
45
+
46
+ /**
47
+ * @var string 应用域名
48
+ */
49
+ public $ domain ;
50
+
51
+ /**
52
+ * @var string 推流鉴权
53
+ */
54
+ public $ pushAuth ;
55
+
56
+ /**
57
+ * @var string 媒体中心地址
58
+ */
59
+ public $ pushDomain = 'video-center.alivecdn.com ' ;
60
+
61
+ /**
62
+ * @var bool 是否使用安全连接
63
+ */
64
+ public $ secureConnection = false ;
65
+
66
+ /**
67
+ * @var int 签名有效期,默认有效期是一周
68
+ */
69
+ public $ authTime = 604800 ;
70
+
71
+ /**
72
+ * @var int 秘钥过期时间
73
+ */
74
+ private $ expirationTime ;
75
+
76
+ /**
77
+ * @var string 播放协议
78
+ */
79
+ private $ playScheme ;
80
+
81
+ /**
82
+ * @var string 播放地址
83
+ */
84
+ private $ httpPlayUrl ;
85
+
86
+ /**
87
+ * @var HttpClient
88
+ */
89
+ private $ _httpClient ;
90
+
91
+ /**
92
+ * 初始化直播组件
93
+ * @throws InvalidConfigException
94
+ */
95
+ public function init (){
96
+ parent ::init ();
97
+ $ this ->expirationTime = time () + $ this ->authTime ;
98
+ $ this ->playScheme = $ this ->secureConnection ? 'https:// ' : 'http:// ' ;
99
+ $ this ->httpPlayUrl = $ this ->playScheme . $ this ->domain ;
100
+
101
+ if (empty ($ this ->accessKeyId )) {
102
+ throw new InvalidConfigException ('The "accessKeyId" property must be set. ' );
103
+ }
104
+ if (empty ($ this ->accessSecret )) {
105
+ throw new InvalidConfigException ('The "accessSecret" property must be set. ' );
106
+ }
107
+ if (empty ($ this ->appName )) {
108
+ throw new InvalidConfigException ('The "appName" property must be set. ' );
109
+ }
110
+
111
+ if (empty ($ this ->domain )) {
112
+ throw new InvalidConfigException ('The "domain" property must be set. ' );
113
+ }
114
+ }
115
+
116
+ /**
117
+ * 获取Http Client
118
+ * @return HttpClient
119
+ */
120
+ public function getHttpClient ()
121
+ {
122
+ if (!is_object ($ this ->_httpClient )) {
123
+ $ stack = HandlerStack::create ();
124
+ $ middleware = new Rpc ([
125
+ 'accessKeyId ' => $ this ->accessKeyId ,
126
+ 'accessSecret ' => $ this ->accessSecret ,
127
+ 'Version ' => $ this ->version
128
+ ]);
129
+ $ stack ->push ($ middleware );
130
+
131
+ $ this ->_httpClient = new HttpClient ([
132
+ 'base_uri ' => $ this ->baseUri ,
133
+ 'handler ' => $ stack ,
134
+ 'verify ' => false ,
135
+ 'http_errors ' => false ,
136
+ 'connect_timeout ' => 3 ,
137
+ 'read_timeout ' => 10 ,
138
+ 'debug ' => false ,
139
+ ]);
140
+ }
141
+ return $ this ->_httpClient ;
142
+ }
143
+
144
+ /**
145
+ * 发起Api请求
146
+ * @param array $params
147
+ * @return \Psr\Http\Message\ResponseInterface
148
+ */
149
+ public function createRequest (array $ params )
150
+ {
151
+ return $ this ->getHttpClient ()->get ('/ ' , ['query ' => $ params ]);
152
+ }
153
+
154
+ /**
155
+ * 禁止推流
156
+ * @param string $streamName
157
+ * @return string
158
+ */
159
+ public function forbidLiveStream ($ streamName )
160
+ {
161
+ return $ this ->createRequest ([
162
+ 'Action ' => 'ForbidLiveStream ' ,
163
+ 'DomainName ' => $ this ->domain ,
164
+ 'AppName ' => $ this ->appName ,
165
+ 'StreamName ' => $ streamName ,
166
+ 'LiveStreamType ' => 'publisher ' ,
167
+ 'ResumeTime ' => gmdate ('Y-m-d\TH:i:s\Z ' , mktime (0 , 0 , 0 , 1 , 1 , 2099 ))
168
+ ]);
169
+ }
170
+
171
+ /**
172
+ * 允许推流
173
+ * @param string $streamName
174
+ * @return string
175
+ */
176
+ public function startLiveStream ($ streamName )
177
+ {
178
+ return $ this ->createRequest ([
179
+ 'Action ' => 'ResumeLiveStream ' ,
180
+ 'DomainName ' => $ this ->domain ,
181
+ 'AppName ' => $ this ->appName ,
182
+ 'StreamName ' => $ streamName ,
183
+ 'LiveStreamType ' => 'publisher '
184
+ ]);
185
+ }
186
+
187
+ /**
188
+ * 实时查询在线人数的请求参数
189
+ * @param null|string $streamName
190
+ * @param null|int $startTime
191
+ * @param null|int $endTime
192
+ * @return string
193
+ */
194
+ public function describeLiveStreamOnlineUserNum ($ streamName = null , $ startTime = null , $ endTime = null )
195
+ {
196
+ $ params = [
197
+ 'Action ' => 'DescribeLiveStreamOnlineUserNum ' ,
198
+ 'DomainName ' => $ this ->domain ,
199
+ 'AppName ' => $ this ->appName
200
+ ];
201
+ if (!empty ($ streamName )) {
202
+ $ params ['StreamName ' ] = $ streamName ;
203
+ }
204
+ if (!empty ($ startTime ) && !empty ($ endTime )) {
205
+ $ params ['StartTime ' ] = gmdate ('Y-m-d\TH:i:s\Z ' , $ startTime );
206
+ $ params ['EndTime ' ] = gmdate ('Y-m-d\TH:i:s\Z ' , $ endTime );
207
+ }
208
+ return $ this ->createRequest ($ params );
209
+ }
210
+
211
+ /**
212
+ * 查询在线的直播推流列表
213
+ * @return string
214
+ */
215
+ public function describeLiveStreamsOnlineList ()
216
+ {
217
+ return $ this ->createRequest ([
218
+ 'Action ' => 'DescribeLiveStreamsOnlineList ' ,
219
+ 'DomainName ' => $ this ->domain ,
220
+ 'AppName ' => $ this ->appName
221
+ ]);
222
+ }
223
+
224
+ /**
225
+ * 直播签名
226
+ * @param string $streamName
227
+ * @return string
228
+ */
229
+ public function getSign ($ streamName )
230
+ {
231
+ $ uri = "/ {$ this ->appName }/ {$ streamName }" ;
232
+ if ($ this ->pushAuth ) {
233
+ $ authKey = "?vhost= {$ this ->domain }&auth_key= {$ this ->expirationTime }-0-0- " . md5 ("{$ uri }- {$ this ->expirationTime }-0-0- {$ this ->pushAuth }" );
234
+ } else {
235
+ $ authKey = "?vhost= {$ this ->domain }" ;
236
+ }
237
+ return $ authKey ;
238
+ }
239
+
240
+ /**
241
+ * 获取推流地址
242
+ * @return string
243
+ */
244
+ public function getPushPath ()
245
+ {
246
+ return "rtmp:// {$ this ->pushDomain }/ {$ this ->appName }/ " ;
247
+ }
248
+
249
+ /**
250
+ * 获取串码流
251
+ * @param string $streamName 流名称
252
+ * @return string
253
+ */
254
+ public function getPushArg ($ streamName )
255
+ {
256
+ return $ streamName . $ this ->getSign ($ streamName );
257
+ }
258
+
259
+ /**
260
+ * 获取直播推流地址
261
+ * @param string $streamName
262
+ * @return string
263
+ */
264
+ public function getPushUrl ($ streamName )
265
+ {
266
+ $ uri = "/ {$ this ->appName }/ {$ streamName }" ;
267
+ return "rtmp:// {$ this ->pushDomain }" . $ uri . $ this ->getSign ($ streamName );
268
+ }
269
+
270
+ /**
271
+ * 验证签名
272
+ * @param string $streamName
273
+ * @param string $usrargs
274
+ * @return bool
275
+ */
276
+ public function checkSign ($ streamName , $ usrargs )
277
+ {
278
+ parse_str ($ usrargs , $ args );
279
+ if (isset ($ args ['vhost ' ]) && isset ($ args ['auth_key ' ])) {
280
+ if ($ args ['vhost ' ] != $ this ->domain ) {
281
+ return false ;
282
+ }
283
+ $ params = explode ('- ' , $ args ['auth_key ' ], 4 );
284
+ if (isset ($ params [0 ]) && $ params [3 ]) {
285
+ $ uri = "/ {$ this ->appName }/ {$ streamName }" ;
286
+ if ($ params [3 ] == md5 ("{$ uri }- {$ params [0 ]}-0-0- {$ this ->pushAuth }" )) {
287
+ return true ;
288
+ }
289
+
290
+ }
291
+ }
292
+ return false ;
293
+ }
294
+
295
+ /**
296
+ * 获取签名
297
+ * @param string $uri
298
+ * @return string
299
+ */
300
+ protected function getAuthKey ($ uri )
301
+ {
302
+ $ authKey = '' ;
303
+ if ($ this ->pushAuth ) {
304
+ $ authKey = "?auth_key= {$ this ->expirationTime }-0-0- " . md5 ("{$ uri }- {$ this ->expirationTime }-0-0- {$ this ->pushAuth }" );
305
+ }
306
+ return $ authKey ;
307
+ }
308
+
309
+ /**
310
+ * 获取RTMP拉流地址
311
+ * @param string $streamName
312
+ * @return string
313
+ */
314
+ public function getPlayUrlForRTMP ($ streamName )
315
+ {
316
+ $ uri = "/ {$ this ->appName }/ {$ streamName }" ;
317
+ return 'rtmp:// ' . $ this ->domain . $ uri . $ this ->getAuthKey ($ uri );
318
+ }
319
+
320
+ /**
321
+ * 获取FLV播放地址
322
+ * @param string $streamName
323
+ * @return string
324
+ */
325
+ public function getPlayUrlForFLV ($ streamName )
326
+ {
327
+ $ uri = "/ {$ this ->appName }/ {$ streamName }.flv " ;
328
+ return $ this ->httpPlayUrl . $ uri . $ this ->getAuthKey ($ uri );
329
+ }
330
+
331
+ /**
332
+ * 获取M3U8播放地址
333
+ * @param string $streamName
334
+ * @return string
335
+ */
336
+ public function getPlayUrlForM3U8 ($ streamName )
337
+ {
338
+ $ uri = "/ {$ this ->appName }/ {$ streamName }.m3u8 " ;
339
+ return $ this ->httpPlayUrl . $ uri . $ this ->getAuthKey ($ uri );
340
+ }
341
+
342
+ /**
343
+ * 获取阿里云播放地址
344
+ * @param string $streamName
345
+ * @return array
346
+ */
347
+ public function getPlayUrls ($ streamName )
348
+ {
349
+ return [
350
+ 'rtmp ' => $ this ->getPlayUrlForRTMP ($ streamName ),
351
+ 'flv ' => $ this ->getPlayUrlForFLV ($ streamName ),
352
+ 'm3u8 ' => $ this ->getPlayUrlForM3U8 ($ streamName )
353
+ ];
354
+ }
355
+
356
+ /**
357
+ * 设置签名过期时间
358
+ * @param int $expirationTime
359
+ * @return $this
360
+ */
361
+ public function setExpirationTime ($ expirationTime )
362
+ {
363
+ $ this ->expirationTime = $ expirationTime ;
364
+ return $ this ;
365
+ }
366
+
367
+ /**
368
+ * 获取签名过期时间
369
+ * @return int
370
+ */
371
+ public function getExpirationTime ()
372
+ {
373
+ return $ this ->expirationTime ;
374
+ }
375
+
376
+ /**
377
+ * @return string
378
+ */
379
+ public function getPlayScheme ()
380
+ {
381
+ return $ this ->playScheme ;
382
+ }
383
+
384
+ /**
385
+ * @return string
386
+ */
387
+ public function getHttpPlayUrl ()
388
+ {
389
+ return $ this ->httpPlayUrl ;
390
+ }
391
+ }
0 commit comments