diff --git a/phpunit.xml b/phpunit.xml
index 41a11a35..bce8cb77 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -11,6 +11,7 @@
./tests
./tests/OSS/Tests/BucketCnameTest.php
+ ./tests/OSS/Tests/BucketLiveChannelTest.php
diff --git a/src/OSS/Model/LiveChannelConfig.php b/src/OSS/Model/LiveChannelConfig.php
new file mode 100644
index 00000000..0c4aa56c
--- /dev/null
+++ b/src/OSS/Model/LiveChannelConfig.php
@@ -0,0 +1,135 @@
+id = $option['id'];
+ }
+ if (isset($option['description'])) {
+ $this->description = $option['description'];
+ }
+ if (isset($option['status'])) {
+ $this->status = $option['status'];
+ }
+ if (isset($option['type'])) {
+ $this->type = $option['type'];
+ }
+ if (isset($option['fragDuration'])) {
+ $this->fragDuration = $option['fragDuration'];
+ }
+ if (isset($option['fragCount'])) {
+ $this->fragCount = $option['fragCount'];
+ }
+ if (isset($option['playListName'])) {
+ $this->playListName = $option['playListName'];
+ }
+ }
+
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ public function getFragDuration()
+ {
+ return $this->fragDuration;
+ }
+
+ public function getFragCount()
+ {
+ return $this->fragCount;
+ }
+
+ public function getPlayListName()
+ {
+ return $this->playListName;
+ }
+
+ public function parseFromXml($strXml)
+ {
+ $xml = simplexml_load_string($strXml);
+ $this->description = strval($xml->Description);
+ $this->status = strval($xml->Status);
+ $target = $xml->Target;
+ $this->type = strval($target->Type);
+ $this->fragDuration = intval($target->FragDuration);
+ $this->fragCount = intval($target->FragCount);
+ $this->playListName = strval($target->PlayListName);
+ }
+
+ public function serializeToXml()
+ {
+ $strXml = <<
+
+
+EOF;
+ $xml = new \SimpleXMLElement($strXml);
+ if (isset($this->description)) {
+ $xml->addChild('Description', $this->description);
+ }
+
+ if (isset($this->status)) {
+ $xml->addChild('Status', $this->status);
+ }
+
+ $node = $xml->addChild('Target');
+ $node->addChild('Type', $this->type);
+
+ if (isset($this->fragDuration)) {
+ $node->addChild('FragDuration', $this->fragDuration);
+ }
+
+ if (isset($this->fragCount)) {
+ $node->addChild('FragCount', $this->fragCount);
+ }
+
+ if (isset($this->playListName)) {
+ $node->addChild('PlayListName', $this->playListName);
+ }
+
+ return $xml->asXML();
+ }
+
+ public function __toString()
+ {
+ return $this->serializeToXml();
+ }
+}
diff --git a/src/OSS/Model/LiveChannelInfo.php b/src/OSS/Model/LiveChannelInfo.php
new file mode 100644
index 00000000..e5642678
--- /dev/null
+++ b/src/OSS/Model/LiveChannelInfo.php
@@ -0,0 +1,107 @@
+id = $id;
+ $this->description = $description;
+ $this->publishUrls = array();
+ $this->playUrls = array();
+ }
+
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ public function setId($id)
+ {
+ $this->id = $id;
+ }
+
+ public function getPublishUrls()
+ {
+ return $this->publishUrls;
+ }
+
+ public function getPlayUrls()
+ {
+ return $this->playUrls;
+ }
+
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ public function getLastModified()
+ {
+ return $this->lastModified;
+ }
+
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ public function setDescription($description)
+ {
+ $this->description = $description;
+ }
+
+ public function parseFromXmlNode($xml)
+ {
+ if (isset($xml->Id)) {
+ $this->id = strval($xml->Id);
+ }
+
+ if (isset($xml->Description)) {
+ $this->description = strval($xml->Description);
+ }
+
+ if (isset($xml->Status)) {
+ $this->status = strval($xml->Status);
+ }
+
+ if (isset($xml->LastModified)) {
+ $this->lastModified = strval($xml->LastModified);
+ }
+
+ if (isset($xml->PublishUrls)) {
+ foreach ($xml->PublishUrls as $url) {
+ $this->publishUrls[] = strval($url->Url);
+ }
+ }
+
+ if (isset($xml->PlayUrls)) {
+ foreach ($xml->PlayUrls as $url) {
+ $this->playUrls[] = strval($url->Url);
+ }
+ }
+ }
+
+ public function parseFromXml($strXml)
+ {
+ $xml = simplexml_load_string($strXml);
+ $this->parseFromXmlNode($xml);
+ }
+
+ public function serializeToXml()
+ {
+ throw new OssException("Not implemented.");
+ }
+}
diff --git a/src/OSS/Model/LiveChannelListInfo.php b/src/OSS/Model/LiveChannelListInfo.php
new file mode 100644
index 00000000..6be16e4e
--- /dev/null
+++ b/src/OSS/Model/LiveChannelListInfo.php
@@ -0,0 +1,108 @@
+bucketName;
+ }
+
+ public function setBucketName($name)
+ {
+ $this->bucketName = $name;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPrefix()
+ {
+ return $this->prefix;
+ }
+
+ /**
+ * @return string
+ */
+ public function getMarker()
+ {
+ return $this->marker;
+ }
+
+ /**
+ * @return int
+ */
+ public function getMaxKeys()
+ {
+ return $this->maxKeys;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getIsTruncated()
+ {
+ return $this->isTruncated;
+ }
+
+ /**
+ * @return LiveChannelInfo[]
+ */
+ public function getChannelList()
+ {
+ return $this->channelList;
+ }
+
+ /**
+ * @return string
+ */
+ public function getNextMarker()
+ {
+ return $this->nextMarker;
+ }
+
+ public function parseFromXml($strXml)
+ {
+ $xml = simplexml_load_string($strXml);
+
+ $this->prefix = strval($xml->Prefix);
+ $this->marker = strval($xml->Marker);
+ $this->maxKeys = intval($xml->MaxKeys);
+ $this->isTruncated = (strval($xml->IsTruncated) == 'true');
+ $this->nextMarker = strval($xml->NextMarker);
+
+ if (isset($xml->LiveChannel)) {
+ foreach ($xml->LiveChannel as $chan) {
+ $channel = new LiveChannelInfo();
+ $channel->parseFromXmlNode($chan);
+ $this->channelList[] = $channel;
+ }
+ }
+ }
+
+ public function serializeToXml()
+ {
+ throw new OssException("Not implemented.");
+ }
+}
\ No newline at end of file
diff --git a/src/OSS/OssClient.php b/src/OSS/OssClient.php
index 982297bd..8c86f50e 100644
--- a/src/OSS/OssClient.php
+++ b/src/OSS/OssClient.php
@@ -9,6 +9,9 @@
use OSS\Model\CorsConfig;
use OSS\Model\CnameConfig;
use OSS\Model\LoggingConfig;
+use OSS\Model\LiveChannelConfig;
+use OSS\Model\LiveChannelInfo;
+use OSS\Model\LiveChannelListInfo;
use OSS\Result\AclResult;
use OSS\Result\BodyResult;
use OSS\Result\GetCorsResult;
@@ -26,6 +29,8 @@
use OSS\Result\ListPartsResult;
use OSS\Result\PutSetDeleteResult;
use OSS\Result\ExistResult;
+use OSS\Result\PutLiveChannelResult;
+use OSS\Result\ListLiveChannelResult;
use OSS\Model\ObjectListInfo;
use OSS\Result\UploadPartResult;
use OSS\Model\BucketListInfo;
@@ -513,6 +518,119 @@ public function deleteBucketCname($bucket, $cname, $options = NULL)
return $result->getData();
}
+ /**
+ * 为指定Bucket创建直播流
+ *
+ * @param string $bucket bucket名称
+ * @param LiveChannelConfig $channelConfig
+ * @param array $options
+ * @throws OssException
+ * @return LiveChannelInfo
+ */
+ public function putBucketLiveChannel($bucket, $channelConfig, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = $channelConfig->getId();
+ $options[self::OSS_SUB_RESOURCE] = 'live';
+ $options[self::OSS_CONTENT_TYPE] = 'application/xml';
+ $options[self::OSS_CONTENT] = $channelConfig->serializeToXml();
+
+ $response = $this->auth($options);
+ $result = new PutLiveChannelResult($response);
+ $info = $result->getData();
+ $info->setId($channelConfig->getId());
+ $info->setDescription($channelConfig->getDescription());
+
+ return $info;
+ }
+
+ /**
+ * 获取指定Bucket的直播流列表
+ *
+ * @param string $bucket bucket名称
+ * @param array $options
+ * @throws OssException
+ * @return LiveChannelListInfo
+ */
+ public function listBucketLiveChannels($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'live';
+ $options[self::OSS_QUERY_STRING] = array(
+ 'prefix' => isset($options['prefix']) ? $options['prefix'] : '',
+ 'marker' => isset($options['marker']) ? $options['marker'] : '',
+ 'max-keys' => isset($options['max-keys']) ? $options['max-keys'] : '',
+ );
+ $response = $this->auth($options);
+ $result = new ListLiveChannelResult($response);
+ $list = $result->getData();
+ $list->setBucketName($bucket);
+
+ return $list;
+ }
+
+ /**
+ * 删除指定Bucket的直播流
+ *
+ * @param string $bucket bucket名称
+ * @param string $channelId
+ * @param array $options
+ * @throws OssException
+ * @return null
+ */
+ public function deleteBucketLiveChannel($bucket, $channelId, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE;
+ $options[self::OSS_OBJECT] = $channelId;
+ $options[self::OSS_SUB_RESOURCE] = 'live';
+
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 生成签名后的推流地址
+ *
+ * @param string $bucket bucket名称
+ * @param string $channelId
+ * @param array $options
+ * @throws OssException
+ * @return null
+ */
+ public function getLiveChannelUrl($bucket, $channelId, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $channelId, $options, false);
+ $expires = isset($options['expires']) ? intval($options['expires']) : 3600;
+ $expires = time() + $expires;
+ $proto = 'rtmp://';
+ $hostname = $this->generateHostname($bucket);
+ $cano_params = '';
+ $query_items = array();
+ $params = isset($options['params']) ? $options['params'] : array();
+ uksort($params, 'strnatcasecmp');
+ foreach ($params as $key => $value) {
+ $cano_params = $cano_params . $key . ':' . $value . '\n';
+ $query_items[] = rawurlencode($key) . '=' . rawurlencode($value);
+ }
+ $resource = '/' . $bucket . '/' . $channelId;
+
+ $string_to_sign = $expires . '\n' . $cano_params . $resource;
+ $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->accessKeySecret, true));
+ $query_items[] = 'AccessKeyId=' . rawurlencode($this->accessKeyId);
+ $query_items[] = 'Expires=' . rawurlencode($expires);
+ $query_items[] = 'Signature=' . rawurlencode($signature);
+
+ return $proto . $hostname . '/live/' . $channelId . '?' . implode('&', $query_items);
+ }
+
/**
* 检验跨域资源请求, 发送跨域请求之前会发送一个preflight请求(OPTIONS)并带上特定的来源域,
* HTTP方法和header信息等给OSS以决定是否发送真正的请求。 OSS可以通过putBucketCors接口
@@ -1521,7 +1639,7 @@ private function auth($options)
// 获得当次请求使用的协议头,是https还是http
$scheme = $this->useSSL ? 'https://' : 'http://';
// 获得当次请求使用的hostname,如果是公共域名或者专有域名,bucket拼在前面构成三级域名
- $hostname = $this->generateHostname($options);
+ $hostname = $this->generateHostname($options[self::OSS_BUCKET]);
$string_to_sign = '';
$headers = $this->generateHeaders($options, $hostname);
$signable_query_string_params = $this->generateSignableQueryStringParam($options);
@@ -1782,10 +1900,10 @@ private function authPrecheckAcl($options)
* 获得档次请求使用的域名
* bucket在前的三级域名,或者二级域名,如果是cname或者ip的话,则是二级域名
*
- * @param $options
+ * @param $bucket
* @return string 剥掉协议头的域名
*/
- private function generateHostname($options)
+ private function generateHostname($bucket)
{
if ($this->hostType === self::OSS_HOST_TYPE_IP) {
$hostname = $this->hostname;
@@ -1793,7 +1911,7 @@ private function generateHostname($options)
$hostname = $this->hostname;
} else {
// 专有域或者官网endpoint
- $hostname = ($options[self::OSS_BUCKET] == '') ? $this->hostname : ($options[self::OSS_BUCKET] . '.') . $this->hostname;
+ $hostname = ($bucket == '') ? $this->hostname : ($bucket . '.') . $this->hostname;
}
return $hostname;
}
diff --git a/src/OSS/Result/GetCnameResult.php b/src/OSS/Result/GetCnameResult.php
index 1f42e235..eed01f90 100644
--- a/src/OSS/Result/GetCnameResult.php
+++ b/src/OSS/Result/GetCnameResult.php
@@ -16,19 +16,4 @@ protected function parseDataFromResponse()
$config->parseFromXml($content);
return $config;
}
-
- /**
- * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种
- * 有效响应
- *
- * @return bool
- */
- protected function isResponseOk()
- {
- $status = $this->rawResponse->status;
- if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) {
- return true;
- }
- return false;
- }
}
\ No newline at end of file
diff --git a/src/OSS/Result/ListLiveChannelResult.php b/src/OSS/Result/ListLiveChannelResult.php
new file mode 100644
index 00000000..18a64192
--- /dev/null
+++ b/src/OSS/Result/ListLiveChannelResult.php
@@ -0,0 +1,19 @@
+rawResponse->body;
+ $channelList = new LiveChannelListInfo();
+ $channelList->parseFromXml($content);
+ return $channelList;
+ }
+}
\ No newline at end of file
diff --git a/src/OSS/Result/PutLiveChannelResult.php b/src/OSS/Result/PutLiveChannelResult.php
new file mode 100644
index 00000000..82c8662a
--- /dev/null
+++ b/src/OSS/Result/PutLiveChannelResult.php
@@ -0,0 +1,19 @@
+rawResponse->body;
+ $channel = new LiveChannelInfo();
+ $channel->parseFromXml($content);
+ return $channel;
+ }
+}
\ No newline at end of file
diff --git a/tests/OSS/Tests/BucketLiveChannelTest.php b/tests/OSS/Tests/BucketLiveChannelTest.php
new file mode 100644
index 00000000..a2c6d108
--- /dev/null
+++ b/tests/OSS/Tests/BucketLiveChannelTest.php
@@ -0,0 +1,149 @@
+client = Common::getOssClient();
+ $this->bucketName = 'php-sdk-test-bucket-' . strval(rand(0, 10));
+ $this->client->createBucket($this->bucketName);
+ }
+
+ public function tearDown()
+ {
+ $this->client->deleteBucket($this->bucketName);
+ }
+
+ public function testPutLiveChannel()
+ {
+ $config = new LiveChannelConfig(array(
+ 'id' => 'live-1',
+ 'description' => 'live channel 1',
+ 'type' => 'hls',
+ 'fragDuration' => 1000,
+ 'playDuration' => 5000,
+ 'playListName' => 'hello'
+ ));
+ $info = $this->client->putBucketLiveChannel($this->bucketName, $config);
+
+ $this->assertEquals('live-1', $info->getId());
+ $this->assertEquals('live channel 1', $info->getDescription());
+ $this->assertEquals(1, count($info->getPublishUrls()));
+ $this->assertEquals(1, count($info->getPlayUrls()));
+ }
+
+ public function testListLiveChannels()
+ {
+ $config = new LiveChannelConfig(array(
+ 'id' => 'live-1',
+ 'description' => 'live channel 1',
+ 'type' => 'hls',
+ 'fragDuration' => 1000,
+ 'playDuration' => 5000,
+ 'playListName' => 'hello'
+ ));
+ $this->client->putBucketLiveChannel($this->bucketName, $config);
+
+ $config = new LiveChannelConfig(array(
+ 'id' => 'live-2',
+ 'description' => 'live channel 2',
+ 'type' => 'hls',
+ 'fragDuration' => 1000,
+ 'playDuration' => 5000,
+ 'playListName' => 'hello'
+ ));
+ $this->client->putBucketLiveChannel($this->bucketName, $config);
+
+ $list = $this->client->listBucketLiveChannels($this->bucketName);
+
+ $this->assertEquals($this->bucketName, $list->getBucketName());
+ $this->assertEquals(false, $list->getIsTruncated());
+ $channels = $list->getChannelList();
+ $this->assertEquals(2, count($channels));
+
+ $chan1 = $channels[0];
+ $this->assertEquals('live-1', $chan1->getId());
+ $this->assertEquals('live channel 1', $chan1->getDescription());
+ $this->assertEquals(1, count($chan1->getPublishUrls()));
+ $this->assertEquals(1, count($chan1->getPlayUrls()));
+
+ $chan2 = $channels[1];
+ $this->assertEquals('live-2', $chan2->getId());
+ $this->assertEquals('live channel 2', $chan2->getDescription());
+ $this->assertEquals(1, count($chan2->getPublishUrls()));
+ $this->assertEquals(1, count($chan2->getPlayUrls()));
+
+ $list = $this->client->listBucketLiveChannels($this->bucketName, array(
+ 'prefix' => 'live-',
+ 'marker' => 'live-1',
+ 'max-keys' => 10
+ ));
+ $channels = $list->getChannelList();
+ $this->assertEquals(1, count($channels));
+ $chan2 = $channels[0];
+ $this->assertEquals('live-2', $chan2->getId());
+ $this->assertEquals('live channel 2', $chan2->getDescription());
+ $this->assertEquals(1, count($chan2->getPublishUrls()));
+ $this->assertEquals(1, count($chan2->getPlayUrls()));
+ }
+
+ /*
+ public function testDeleteLiveChannel()
+ {
+ $channelId = 'live-to-delete';
+ $config = new LiveChannelConfig(array(
+ 'id' => $channelId,
+ 'description' => 'live channel to delete',
+ 'type' => 'hls',
+ 'fragDuration' => 1000,
+ 'playDuration' => 5000,
+ 'playListName' => 'hello'
+ ));
+ $this->client->putBucketLiveChannel($this->bucketName, $config);
+
+ $this->client->deleteBucketLiveChannel($channelId);
+ $list = $this->listLiveChannels($this->bucketName, array(
+ 'prefix' => $channelId
+ ));
+
+ $this->assertEquals(0, count($list->getChannelList()));
+ }
+ */
+
+ public function testGetLiveChannelUrl()
+ {
+ $channelId = '90475';
+ $bucket = 'douyu';
+ $now = time();
+ $url = $this->client->getLiveChannelUrl($bucket, $channelId, array(
+ 'expires' => 900,
+ 'params' => array(
+ 'a' => 'hello',
+ 'b' => 'world'
+ )
+ ));
+
+ $ret = parse_url($url);
+ $this->assertEquals('rtmp', $ret['scheme']);
+ parse_str($ret['query'], $query);
+
+ $this->assertTrue(isset($query['AccessKeyId']));
+ $this->assertTrue(isset($query['Signature']));
+ $this->assertTrue(intval($query['Expires']) - ($now + 900) < 3);
+ $this->assertEquals('hello', $query['a']);
+ $this->assertEquals('world', $query['b']);
+ }
+}
diff --git a/tests/OSS/Tests/LiveChannelXmlTest.php b/tests/OSS/Tests/LiveChannelXmlTest.php
new file mode 100644
index 00000000..45401529
--- /dev/null
+++ b/tests/OSS/Tests/LiveChannelXmlTest.php
@@ -0,0 +1,161 @@
+
+
+ xxx
+ enabled
+
+ hls
+ 1000
+ 5
+ hello
+
+
+BBBB;
+
+ private $info = <<
+
+ live-1
+ xxx
+
+ rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/213443245345
+
+
+ http://bucket.oss-cn-hangzhou.aliyuncs.com/213443245345/播放列表.m3u8
+
+ enabled
+ 2015-11-24T14:25:31.000Z
+
+BBBB;
+
+ private $list = <<
+
+xxx
+ yyy
+ 100
+ false
+ 121312132
+
+ 12123214323431
+ xxx
+
+ rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/1
+
+
+ http://bucket.oss-cn-hangzhou.aliyuncs.com/1/播放列表.m3u8
+
+ enabled
+ 2015-11-24T14:25:31.000Z
+
+
+ 432423432423
+ yyy
+
+ rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/2
+
+
+ http://bucket.oss-cn-hangzhou.aliyuncs.com/2/播放列表.m3u8
+
+ enabled
+ 2016-11-24T14:25:31.000Z
+
+
+BBBB;
+
+ public function testConfig()
+ {
+ $config = new LiveChannelConfig(array('id' => 'live-1'));
+ $config->parseFromXml($this->config);
+
+ $this->assertEquals('live-1', $config->getId());
+ $this->assertEquals('xxx', $config->getDescription());
+ $this->assertEquals('enabled', $config->getStatus());
+ $this->assertEquals('hls', $config->getType());
+ $this->assertEquals(1000, $config->getFragDuration());
+ $this->assertEquals(5, $config->getFragCount());
+ $this->assertEquals('hello', $config->getPlayListName());
+
+ $xml = $config->serializeToXml();
+ $config2 = new LiveChannelConfig(array('id' => 'live-2'));
+ $config2->parseFromXml($xml);
+ $this->assertEquals('live-2', $config2->getId());
+ $this->assertEquals('xxx', $config2->getDescription());
+ $this->assertEquals('enabled', $config2->getStatus());
+ $this->assertEquals('hls', $config2->getType());
+ $this->assertEquals(1000, $config2->getFragDuration());
+ $this->assertEquals(5, $config2->getFragCount());
+ $this->assertEquals('hello', $config2->getPlayListName());
+ }
+
+ public function testInfo()
+ {
+ $info = new LiveChannelInfo();
+ $info->parseFromXml($this->info);
+
+ $this->assertEquals('live-1', $info->getId());
+ $this->assertEquals('xxx', $info->getDescription());
+ $this->assertEquals('enabled', $info->getStatus());
+ $this->assertEquals('2015-11-24T14:25:31.000Z', $info->getLastModified());
+ $pubs = $info->getPublishUrls();
+ $this->assertEquals(1, count($pubs));
+ $this->assertEquals('rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/213443245345', $pubs[0]);
+
+ $plays = $info->getPlayUrls();
+ $this->assertEquals(1, count($plays));
+ $this->assertEquals('http://bucket.oss-cn-hangzhou.aliyuncs.com/213443245345/播放列表.m3u8', $plays[0]);
+ }
+
+ public function testList()
+ {
+ $list = new LiveChannelListInfo();
+ $list->parseFromXml($this->list);
+
+ $this->assertEquals('xxx', $list->getPrefix());
+ $this->assertEquals('yyy', $list->getMarker());
+ $this->assertEquals(100, $list->getMaxKeys());
+ $this->assertEquals(false, $list->getIsTruncated());
+ $this->assertEquals('121312132', $list->getNextMarker());
+
+ $channels = $list->getChannelList();
+ $this->assertEquals(2, count($channels));
+
+ $chan1 = $channels[0];
+ $this->assertEquals('12123214323431', $chan1->getId());
+ $this->assertEquals('xxx', $chan1->getDescription());
+ $this->assertEquals('enabled', $chan1->getStatus());
+ $this->assertEquals('2015-11-24T14:25:31.000Z', $chan1->getLastModified());
+ $pubs = $chan1->getPublishUrls();
+ $this->assertEquals(1, count($pubs));
+ $this->assertEquals('rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/1', $pubs[0]);
+
+ $plays = $chan1->getPlayUrls();
+ $this->assertEquals(1, count($plays));
+ $this->assertEquals('http://bucket.oss-cn-hangzhou.aliyuncs.com/1/播放列表.m3u8', $plays[0]);
+
+ $chan2 = $channels[1];
+ $this->assertEquals('432423432423', $chan2->getId());
+ $this->assertEquals('yyy', $chan2->getDescription());
+ $this->assertEquals('enabled', $chan2->getStatus());
+ $this->assertEquals('2016-11-24T14:25:31.000Z', $chan2->getLastModified());
+ $pubs = $chan2->getPublishUrls();
+ $this->assertEquals(1, count($pubs));
+ $this->assertEquals('rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/2', $pubs[0]);
+
+ $plays = $chan2->getPlayUrls();
+ $this->assertEquals(1, count($plays));
+ $this->assertEquals('http://bucket.oss-cn-hangzhou.aliyuncs.com/2/播放列表.m3u8', $plays[0]);
+ }
+}