Skip to content

Commit 90d67bf

Browse files
committed
2 parents 1db7aec + 1cb5da8 commit 90d67bf

File tree

1 file changed

+391
-0
lines changed

1 file changed

+391
-0
lines changed

src/Live.php

Lines changed: 391 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,391 @@
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

Comments
 (0)