diff --git a/example.jpg b/example.jpg new file mode 100644 index 00000000..ffd46a2f Binary files /dev/null and b/example.jpg differ diff --git a/samples/Image.php b/samples/Image.php new file mode 100644 index 00000000..e5edaae7 --- /dev/null +++ b/samples/Image.php @@ -0,0 +1,85 @@ +uploadFile($bucketName, $object, "example.jpg"); +//图片缩放 +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + 'x-oss-process' => "image/resize,m_fixed,h_100,w_100", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageResize",$download_file); + +// 图片裁剪 +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + 'x-oss-process' => "image/crop,w_100,h_100,x_100,y_100,r_1", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("iamgeCrop", $download_file); + +//图片旋转 +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + 'x-oss-process' => "image/rotate,90", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageRotate", $download_file); + +//图片锐化 +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + 'x-oss-process' => "image/sharpen,100", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageSharpen", $download_file); + +//图片水印 +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + 'x-oss-process' => "image/watermark,text_SGVsbG8g5Zu-54mH5pyN5YqhIQ", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageWatermark", $download_file); + +//图片格式转换 +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + 'x-oss-process' => "image/format,png", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageFormat", $download_file); + +//获取图片信息 +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + 'x-oss-process' => "image/info", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageInfo", $download_file); + + +/** + 生成一个带签名的可用于浏览器直接打开的url, URL的有效期是3600秒 + */ + $timeout = 3600; +$options = array( + 'x-oss-process' => "image/resize,m_lfit,h_100,w_100", + ); +$signedUrl = $ossClient->signUrl($bucketName, $object, $timeout, "GET", $options); +Common::println("rtmp url: \n" . $signedUrl); + +//最后删除上传的$object +$ossClient->deleteObject($bucketName, $object); + +function printImage($func, $imageFile) +{ + $array = getimagesize($imageFile); + Common::println("$func, image width: " . $array[0]); + Common::println("$func, image height: " . $array[1]); + Common::println("$func, image type: " . ($array[2] === 2 ? 'jpg' : 'png')); + Common::println("$func, image size: " . ceil(filesize($imageFile))); +} diff --git a/samples/LiveChannel.php b/samples/LiveChannel.php new file mode 100644 index 00000000..f36e7183 --- /dev/null +++ b/samples/LiveChannel.php @@ -0,0 +1,126 @@ + 'live channel test', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello' + )); +$info = $ossClient->putBucketLiveChannel($bucket, 'test_rtmp_live', $config); +Common::println("bucket $bucket liveChannel created:\n" . +"live channel name: ". $info->getName() . "\n" . +"live channel description: ". $info->getDescription() . "\n" . +"publishurls: ". $info->getPublishUrls()[0] . "\n" . +"playurls: ". $info->getPlayUrls()[0] . "\n"); + +/** + 对创建好的频道,可以使用listBucketLiveChannels来进行列举已达到管理的目的。 + prefix可以按照前缀过滤list出来的频道。 + max_keys表示迭代器内部一次list出来的频道的最大数量,这个值最大不能超过1000,不填写的话默认为100。 + */ +$list = $ossClient->listBucketLiveChannels($bucket); +Common::println("bucket $bucket listLiveChannel:\n" . +"list live channel prefix: ". $list->getPrefix() . "\n" . +"list live channel marker: ". $list->getMarker() . "\n" . +"list live channel maxkey: ". $list->getMaxKeys() . "\n" . +"list live channel IsTruncated: ". $list->getIsTruncated() . "\n" . +"list live channel getNextMarker: ". $list->getNextMarker() . "\n"); + +foreach($list->getChannelList() as $list) +{ + Common::println("bucket $bucket listLiveChannel:\n" . + "list live channel IsTruncated: ". $list->getName() . "\n" . + "list live channel Description: ". $list->getDescription() . "\n" . + "list live channel Status: ". $list->getStatus() . "\n" . + "list live channel getNextMarker: ". $list->getLastModified() . "\n"); +} +/** + 创建直播频道之后拿到推流用的play_url(rtmp推流的url,如果Bucket不是公共读写权限那么还需要带上签名,见下文示例)和推流用的publish_url(推流产生的m3u8文件的url) + */ +$play_url = $ossClient->signRtmpUrl($bucket, "test_rtmp_live", 3600, array('params' => array('playlistName' => 'playlist.m3u8'))); +Common::println("bucket $bucket rtmp url: \n" . $play_url); +$play_url = $ossClient->signRtmpUrl($bucket, "test_rtmp_live", 3600); +Common::println("bucket $bucket rtmp url: \n" . $play_url); + +/** + 创建好直播频道,如果想把这个频道禁用掉(断掉正在推的流或者不再允许向一个地址推流),应该使用putLiveChannelStatus接口,将频道的status改成“Disabled”,如果要将一个禁用状态的频道启用,那么也是调用这个接口,将status改成“Enabled” + */ +$resp = $ossClient->putLiveChannelStatus($bucket, "test_rtmp_live", "enabled"); + +/** + 创建好直播频道之后调用getLiveChannelInfo可以得到频道相关的信息 +*/ +$info = $ossClient->getLiveChannelInfo($bucket, 'test_rtmp_live'); +Common::println("bucket $bucket LiveChannelInfo:\n" . +"live channel info description: ". $info->getDescription() . "\n" . +"live channel info status: ". $info->getStatus() . "\n" . +"live channel info type: ". $info->getType() . "\n" . +"live channel info fragDuration: ". $info->getFragDuration() . "\n" . +"live channel info fragCount: ". $info->getFragCount() . "\n" . +"live channel info playListName: ". $info->getPlayListName() . "\n"); + +/** + 如果想查看一个频道历史推流记录,可以调用getLiveChannelHistory。目前最多可以看到10次推流的记录 + */ +$history = $ossClient->getLiveChannelHistory($bucket, "test_rtmp_live"); +if (count($history->getLiveRecordList()) != 0) +{ + foreach($history->getLiveRecordList() as $recordList) + { + Common::println("bucket $bucket liveChannelHistory:\n" . + "live channel history startTime: ". $recordList->getStartTime() . "\n" . + "live channel history endTime: ". $recordList->getEndTime() . "\n" . + "live channel history remoteAddr: ". $recordList->getRemoteAddr() . "\n"); + } +} + +/** + 对于正在推流的频道调用get_live_channel_stat可以获得流的状态信息。 + 如果频道正在推流,那么stat_result中的所有字段都有意义。 + 如果频道闲置或者处于“Disabled”状态,那么status为“Idle”或“Disabled”,其他字段无意义。 + */ +$status = $ossClient->getLiveChannelStatus($bucket, "test_rtmp_live"); +Common::println("bucket $bucket listLiveChannel:\n" . +"live channel status status: ". $status->getStatus() . "\n" . +"live channel status ConnectedTime: ". $status->getConnectedTime() . "\n" . +"live channel status VideoWidth: ". $status->getVideoWidth() . "\n" . +"live channel status VideoHeight: ". $status->getVideoHeight() . "\n" . +"live channel status VideoFrameRate: ". $status->getVideoFrameRate() . "\n" . +"live channel status VideoBandwidth: ". $status->getVideoBandwidth() . "\n" . +"live channel status VideoCodec: ". $status->getVideoCodec() . "\n" . +"live channel status AudioBandwidth: ". $status->getAudioBandwidth() . "\n" . +"live channel status AudioSampleRate: ". $status->getAudioSampleRate() . "\n" . +"live channel status AdioCodec: ". $status->getAudioCodec() . "\n"); + +/** + 如果希望利用直播推流产生的ts文件生成一个点播列表,可以使用postVodPlaylist方法。 + 指定起始时间为当前时间减去60秒,结束时间为当前时间,这意味着将生成一个长度为60秒的点播视频。 + 播放列表指定为“vod_playlist.m3u8”,也就是说这个接口调用成功之后会在OSS上生成一个名叫“vod_playlist.m3u8”的播放列表文件。 + */ +$current_time = time(); +$info = $ossClient->postVodPlaylist($bucket, + "test_rtmp_live", "vod_playlist.m3u8", + array('StartTime' => $current_time - 60, + 'EndTime' => $current_time) +); + +/** + 如果一个直播频道已经不打算再使用了,那么可以调用delete_live_channel来删除频道。 + */ +$info = $ossClient->deleteBucketLiveChannel($bucket, "test_rtmp_live"); diff --git a/src/OSS/Model/GetLiveChannelHistory.php b/src/OSS/Model/GetLiveChannelHistory.php new file mode 100644 index 00000000..6643444a --- /dev/null +++ b/src/OSS/Model/GetLiveChannelHistory.php @@ -0,0 +1,34 @@ +liveRecordList; + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + + if (isset($xml->LiveRecord)) { + foreach ($xml->LiveRecord as $record) { + $liveRecord = new LiveChannelHistory(); + $liveRecord->parseFromXmlNode($record); + $this->liveRecordList[] = $liveRecord; + } + } + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $liveRecordList = array(); +} diff --git a/src/OSS/Model/GetLiveChannelInfo.php b/src/OSS/Model/GetLiveChannelInfo.php new file mode 100644 index 00000000..0b5edfc4 --- /dev/null +++ b/src/OSS/Model/GetLiveChannelInfo.php @@ -0,0 +1,68 @@ +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); + + if (isset($xml->Target)) { + foreach ($xml->Target as $target) { + $this->type = strval($target->Type); + $this->fragDuration = strval($target->FragDuration); + $this->fragCount = strval($target->FragCount); + $this->playlistName = strval($target->PlaylistName); + } + } + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $description; + private $status; + private $type; + private $fragDuration; + private $fragCount; + private $playlistName; +} diff --git a/src/OSS/Model/GetLiveChannelStatus.php b/src/OSS/Model/GetLiveChannelStatus.php new file mode 100644 index 00000000..2ee7a68b --- /dev/null +++ b/src/OSS/Model/GetLiveChannelStatus.php @@ -0,0 +1,107 @@ +status; + } + + public function getConnectedTime() + { + return $this->connectedTime; + } + + public function getRemoteAddr() + { + return $this->remoteAddr; + } + + public function getVideoWidth() + { + return $this->videoWidth; + } + public function getVideoHeight() + { + return $this->videoHeight; + } + public function getVideoFrameRate() + { + return $this->videoFrameRate; + } + public function getVideoBandwidth() + { + return $this->videoBandwidth; + } + public function getVideoCodec() + { + return $this->videoCodec; + } + + public function getAudioBandwidth() + { + return $this->audioBandwidth; + } + public function getAudioSampleRate() + { + return $this->audioSampleRate; + } + public function getAudioCodec() + { + return $this->audioCodec; + } + + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + $this->status = strval($xml->Status); + $this->connectedTime = strval($xml->ConnectedTime); + $this->remoteAddr = strval($xml->RemoteAddr); + + if (isset($xml->Video)) { + foreach ($xml->Video as $video) { + $this->videoWidth = intval($video->Width); + $this->videoHeight = intval($video->Height); + $this->videoFrameRate = intval($video->FrameRate); + $this->videoBandwidth = intval($video->Bandwidth); + $this->videoCodec = strval($video->Codec); + } + } + + if (isset($xml->Video)) { + foreach ($xml->Audio as $audio) { + $this->audioBandwidth = intval($audio->Bandwidth); + $this->audioSampleRate = intval($audio->SampleRate); + $this->audioCodec = strval($audio->Codec); + } + } + + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $status; + private $connectedTime; + private $remoteAddr; + + private $videoWidth; + private $videoHeight; + private $videoFrameRate; + private $videoBandwidth; + private $videoCodec; + + private $audioBandwidth; + private $audioSampleRate; + private $audioCodec; + + +} diff --git a/src/OSS/Model/LiveChannelConfig.php b/src/OSS/Model/LiveChannelConfig.php new file mode 100644 index 00000000..b9e3582b --- /dev/null +++ b/src/OSS/Model/LiveChannelConfig.php @@ -0,0 +1,126 @@ +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 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(); + } + + private $description; + private $status = "enabled"; + private $type; + private $fragDuration = 5; + private $fragCount = 3; + private $playListName = "playlist.m3u8"; +} diff --git a/src/OSS/Model/LiveChannelHistory.php b/src/OSS/Model/LiveChannelHistory.php new file mode 100644 index 00000000..1c1fd4db --- /dev/null +++ b/src/OSS/Model/LiveChannelHistory.php @@ -0,0 +1,59 @@ +startTime; + } + + public function getEndTime() + { + return $this->endTime; + } + + public function getRemoteAddr() + { + return $this->remoteAddr; + } + + public function parseFromXmlNode($xml) + { + if (isset($xml->StartTime)) { + $this->startTime = strval($xml->StartTime); + } + + if (isset($xml->EndTime)) { + $this->endTime = strval($xml->EndTime); + } + + if (isset($xml->RemoteAddr)) { + $this->remoteAddr = strval($xml->RemoteAddr); + } + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + $this->parseFromXmlNode($xml); + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $startTime; + private $endTime; + private $remoteAddr; +} diff --git a/src/OSS/Model/LiveChannelInfo.php b/src/OSS/Model/LiveChannelInfo.php new file mode 100644 index 00000000..c63ec54d --- /dev/null +++ b/src/OSS/Model/LiveChannelInfo.php @@ -0,0 +1,107 @@ +name = $name; + $this->description = $description; + $this->publishUrls = array(); + $this->playUrls = array(); + } + + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = $name; + } + + 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->Name)) { + $this->name = strval($xml->Name); + } + + 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."); + } + + private $name; + private $description; + private $publishUrls; + private $playUrls; + private $status; + private $lastModified; +} diff --git a/src/OSS/Model/LiveChannelListInfo.php b/src/OSS/Model/LiveChannelListInfo.php new file mode 100644 index 00000000..108d2ace --- /dev/null +++ b/src/OSS/Model/LiveChannelListInfo.php @@ -0,0 +1,107 @@ +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."); + } + + private $bucketName; + private $prefix; + private $marker; + private $nextMarker; + private $maxKeys = 100; + private $isTruncated; + private $channelList = array(); +} diff --git a/src/OSS/OssClient.php b/src/OSS/OssClient.php index 25dbce52..ac7d5ddd 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,11 @@ use OSS\Result\ListPartsResult; use OSS\Result\PutSetDeleteResult; use OSS\Result\ExistResult; +use OSS\Result\PutLiveChannelResult; +use OSS\Result\GetLiveChannelHistoryResult; +use OSS\Result\GetLiveChannelInfoResult; +use OSS\Result\GetLiveChannelStatusResult; +use OSS\Result\ListLiveChannelResult; use OSS\Result\AppendResult; use OSS\Model\ObjectListInfo; use OSS\Result\UploadPartResult; @@ -464,7 +472,7 @@ public function addBucketCname($bucket, $cname, $options = NULL) $cnameConfig = new CnameConfig(); $cnameConfig->addCname($cname); $options[self::OSS_CONTENT] = $cnameConfig->serializeToXml(); - $options[self::OSS_CNAME_COMP] = 'add'; + $options[self::OSS_COMP] = 'add'; $response = $this->auth($options); $result = new PutSetDeleteResult($response); @@ -511,13 +519,244 @@ public function deleteBucketCname($bucket, $cname, $options = NULL) $cnameConfig = new CnameConfig(); $cnameConfig->addCname($cname); $options[self::OSS_CONTENT] = $cnameConfig->serializeToXml(); - $options[self::OSS_CNAME_COMP] = 'delete'; + $options[self::OSS_COMP] = 'delete'; $response = $this->auth($options); $result = new PutSetDeleteResult($response); return $result->getData(); } + /** + * 为指定Bucket创建LiveChannel + * + * @param string $bucket bucket名称 + * @param LiveChannelConfig $channelConfig + * @param channelName $channelName + * @param array $options + * @throws OssException + * @return LiveChannelInfo + */ + public function putBucketLiveChannel($bucket, $channelName, $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] = $channelName; + $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->setName($channelName); + $info->setDescription($channelConfig->getDescription()); + + return $info; + } + + /** + * 设置LiveChannel的status + * + * @param string $bucket bucket名称 + * @param string $channelName 操作的channelName + * @param string $channelStatus 为 enabled或disabled + * @param array $options + * @throws OssException + * @return null + */ + public function putLiveChannelStatus($bucket, $channelName, $channelStatus, $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] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_LIVE_CHANNEL_STATUS] = $channelStatus; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取LiveChannel信息 + * + * @param string $bucket bucket名称 + * @param string $channelName 指定的LiveChannel + * @param array $options + * @throws OssException + * @return GetLiveChannelInfo + */ + public function getLiveChannelInfo($bucket, $channelName, $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] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + + $response = $this->auth($options); + $result = new GetLiveChannelInfoResult($response); + return $result->getData(); + } + + /** + * 获取LiveChannel状态信息 + * + * @param string $bucket bucket名称 + * @param string $channelName 指定的LiveChannel + * @param array $options + * @throws OssException + * @return GetLiveChannelStatus + */ + public function getLiveChannelStatus($bucket, $channelName, $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] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_COMP] = 'stat'; + + $response = $this->auth($options); + $result = new GetLiveChannelStatusResult($response); + return $result->getData(); + } + + /** + *获取LiveChannel推流记录 + * + * @param string $bucket bucket名称 + * @param string $channelName 指定的LiveChannel + * @param array $options + * @throws OssException + * @return GetLiveChannelHistory + */ + public function getLiveChannelHistory($bucket, $channelName, $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] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_COMP] = 'history'; + + $response = $this->auth($options); + $result = new GetLiveChannelHistoryResult($response); + return $result->getData(); + } + + /** + *获取指定Bucket下的live channel列表 + * + * @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; + } + + /** + * 为指定LiveChannel生成播放列表 + * + * @param string $bucket bucket名称 + * @param string $channelName 指定的LiveChannel + * @param string $playlistName 指定生成的点播播放列表的名称,必须以“.m3u8”结尾 + * @param array $setTime + * @throws OssException + * @return null + */ + public function postVodPlaylist($bucket, $channelName, $playlistName, $setTime) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = $channelName . '/' . $playlistName; + $options[self::OSS_SUB_RESOURCE] = 'vod'; + $options[self::OSS_LIVE_CHANNEL_END_TIME] = $setTime['EndTime']; + $options[self::OSS_LIVE_CHANNEL_START_TIME] = $setTime['StartTime']; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 删除指定Bucket的LiveChannel + * + * @param string $bucket bucket名称 + * @param string $channelName + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketLiveChannel($bucket, $channelName, $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] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 生成带签名的推流地址 + * + * @param string $bucket bucket名称 + * @param string $channelName + * @param array $options + * @throws OssException + * @return 推流地址 + */ + public function signRtmpUrl($bucket, $channelName, $timeout, $options = NULL) + { + $this->precheckCommon($bucket, $channelName, $options, false); + $expires = time() + $timeout; + $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 . '/' . $channelName; + + $string_to_sign = $expires . "\n" . $cano_params . $resource; + $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->accessKeySecret, true)); + + $query_items[] = 'OSSAccessKeyId=' . rawurlencode($this->accessKeyId); + $query_items[] = 'Expires=' . rawurlencode($expires); + $query_items[] = 'Signature=' . rawurlencode($signature); + + return $proto . $hostname . '/live/' . $channelName . '?' . implode('&', $query_items); + } + /** * 检验跨域资源请求, 发送跨域请求之前会发送一个preflight请求(OPTIONS)并带上特定的来源域, * HTTP方法和header信息等给OSS以决定是否发送真正的请求。 OSS可以通过putBucketCors接口 @@ -1604,7 +1843,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); @@ -1701,7 +1940,11 @@ private function auth($options) // 生成 signable_resource $signable_resource = $this->generateSignableResource($options); $string_to_sign .= rawurldecode($signable_resource) . urldecode($signable_query_string); - $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->accessKeySecret, true)); + + //对?后面的要签名的string字母序排序 + $string_to_sign_ordered = $this->stringToSignSorted($string_to_sign); + + $signature = base64_encode(hash_hmac('sha1', $string_to_sign_ordered, $this->accessKeySecret, true)); $request->add_header('Authorization', 'OSS ' . $this->accessKeyId . ':' . $signature); if (isset($options[self::OSS_PREAUTH]) && (integer)$options[self::OSS_PREAUTH] > 0) { @@ -1740,7 +1983,7 @@ private function auth($options) $data = $this->auth($options); } } - + $this->redirects = 0; return $data; } @@ -1865,10 +2108,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; @@ -1876,7 +2119,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; } @@ -1929,7 +2172,11 @@ private function generateSignableQueryStringParam($options) 'response-expires', 'response-content-disposition', self::OSS_UPLOAD_ID, - self::OSS_CNAME_COMP, + self::OSS_COMP, + self::OSS_LIVE_CHANNEL_STATUS, + self::OSS_LIVE_CHANNEL_START_TIME, + self::OSS_LIVE_CHANNEL_END_TIME, + self::OSS_IMAGE_PROCESS, self::OSS_POSITION ); @@ -1991,6 +2238,27 @@ private function generateQueryString($options) return OssUtil::toQueryString($queryStringParams); } + private function stringToSignSorted($string_to_sign) + { + $queryStringSorted = ''; + $explodeResult = explode('?', $string_to_sign); + $index = count($explodeResult); + if ($index === 1) + return $string_to_sign; + + $queryStringParams = explode('&', $explodeResult[$index - 1]); + sort($queryStringParams); + + foreach($queryStringParams as $params) + { + $queryStringSorted .= $params . '&'; + } + + $queryStringSorted = substr($queryStringSorted, 0, -1); + + return $explodeResult[0] . '?' . $queryStringSorted; + } + /** * 初始化headers * @@ -2087,7 +2355,7 @@ public static function checkEnv() } /** - * 设置http库的请求超时时间,单位秒 + //* 设置http库的请求超时时间,单位秒 * * @param int $timeout */ @@ -2120,7 +2388,10 @@ public function setConnectTimeout($connectTimeout) const OSS_MAX_KEYS = 'max-keys'; const OSS_UPLOAD_ID = 'uploadId'; const OSS_PART_NUM = 'partNumber'; - const OSS_CNAME_COMP = 'comp'; + const OSS_COMP = 'comp'; + const OSS_LIVE_CHANNEL_STATUS = 'status'; + const OSS_LIVE_CHANNEL_START_TIME = 'startTime'; + const OSS_LIVE_CHANNEL_END_TIME = 'endTime'; const OSS_POSITION = 'position'; const OSS_MAX_KEYS_VALUE = 100; const OSS_MAX_OBJECT_GROUP_VALUE = OssUtil::OSS_MAX_OBJECT_GROUP_VALUE; @@ -2184,6 +2455,7 @@ public function setConnectTimeout($connectTimeout) const OSS_MULTI_DELETE = 'delete'; const OSS_OBJECT_COPY_SOURCE = 'x-oss-copy-source'; const OSS_OBJECT_COPY_SOURCE_RANGE = "x-oss-copy-source-range"; + const OSS_IMAGE_PROCESS = "x-oss-process"; //支持STS SecurityToken const OSS_SECURITY_TOKEN = "x-oss-security-token"; const OSS_ACL_TYPE_PRIVATE = 'private'; @@ -2227,4 +2499,4 @@ public function setConnectTimeout($connectTimeout) private $enableStsInUrl = false; private $timeout = 0; private $connectTimeout = 0; -} \ No newline at end of file +} 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/GetLiveChannelHistoryResult.php b/src/OSS/Result/GetLiveChannelHistoryResult.php new file mode 100644 index 00000000..202a6681 --- /dev/null +++ b/src/OSS/Result/GetLiveChannelHistoryResult.php @@ -0,0 +1,19 @@ +rawResponse->body; + $channelList = new GetLiveChannelHistory(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/src/OSS/Result/GetLiveChannelInfoResult.php b/src/OSS/Result/GetLiveChannelInfoResult.php new file mode 100644 index 00000000..d5a9005e --- /dev/null +++ b/src/OSS/Result/GetLiveChannelInfoResult.php @@ -0,0 +1,19 @@ +rawResponse->body; + $channelList = new GetLiveChannelInfo(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/src/OSS/Result/GetLiveChannelStatusResult.php b/src/OSS/Result/GetLiveChannelStatusResult.php new file mode 100644 index 00000000..6b8a60f5 --- /dev/null +++ b/src/OSS/Result/GetLiveChannelStatusResult.php @@ -0,0 +1,19 @@ +rawResponse->body; + $channelList = new GetLiveChannelStatus(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/src/OSS/Result/ListLiveChannelResult.php b/src/OSS/Result/ListLiveChannelResult.php new file mode 100644 index 00000000..1a6e2a41 --- /dev/null +++ b/src/OSS/Result/ListLiveChannelResult.php @@ -0,0 +1,16 @@ +rawResponse->body; + $channelList = new LiveChannelListInfo(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/src/OSS/Result/PutLiveChannelResult.php b/src/OSS/Result/PutLiveChannelResult.php new file mode 100644 index 00000000..dcac86b7 --- /dev/null +++ b/src/OSS/Result/PutLiveChannelResult.php @@ -0,0 +1,16 @@ +rawResponse->body; + $channel = new LiveChannelInfo(); + $channel->parseFromXml($content); + return $channel; + } +} diff --git a/tests/OSS/Tests/BucketLiveChannelTest.php b/tests/OSS/Tests/BucketLiveChannelTest.php new file mode 100644 index 00000000..1e10af05 --- /dev/null +++ b/tests/OSS/Tests/BucketLiveChannelTest.php @@ -0,0 +1,287 @@ +client = Common::getOssClient(); + $this->bucketName = 'php-sdk-test-rtmp-bucket-name-' . strval(rand(0, 10)); + $this->client->createBucket($this->bucketName); + Common::waitMetaSync(); + sleep(30); + } + + public function tearDown() + { + ////to delete created bucket + //1. delele live channel + $list = $this->client->listBucketLiveChannels($this->bucketName); + if (count($list->getChannelList()) != 0) + { + foreach($list->getChannelList() as $list) + { + $this->client->deleteBucketLiveChannel($this->bucketName, $list->getName()); + } + } + //2. delete exsited object + $prefix = 'live-test/'; + $delimiter = '/'; + $nextMarker = ''; + $maxkeys = 1000; + $options = array( + 'delimiter' => $delimiter, + 'prefix' => $prefix, + 'max-keys' => $maxkeys, + 'marker' => $nextMarker, + ); + + try { + $listObjectInfo = $this->client->listObjects($this->bucketName, $options); + } catch (OssException $e) { + printf($e->getMessage() . "\n"); + return; + } + + $objectList = $listObjectInfo->getObjectList(); // 文件列表 + if (!empty($objectList)) + { + foreach($objectList as $objectInfo) + $this->client->deleteObject($this->bucketName, $objectInfo->getKey()); + } + //3. delete the bucket + $this->client->deleteBucket($this->bucketName); + } + + public function testPutLiveChannel() + { + $config = new LiveChannelConfig(array( + 'description' => 'live channel 1', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $info = $this->client->putBucketLiveChannel($this->bucketName, 'live-1', $config); + $this->client->deleteBucketLiveChannel($this->bucketName, 'live-1'); + + $this->assertEquals('live-1', $info->getName()); + $this->assertEquals('live channel 1', $info->getDescription()); + $this->assertEquals(1, count($info->getPublishUrls())); + $this->assertEquals(1, count($info->getPlayUrls())); + } + + public function testPutLiveChannelWithDefaultParams() + { + $config = new LiveChannelConfig(array( + 'description' => 'live channel 1', + 'type' => 'HLS', + )); + $info = $this->client->putBucketLiveChannel($this->bucketName, 'live-1', $config); + $this->client->deleteBucketLiveChannel($this->bucketName, 'live-1'); + + $this->assertEquals('live-1', $info->getName()); + $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( + 'description' => 'live channel 1', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, 'live-1', $config); + + $config = new LiveChannelConfig(array( + 'description' => 'live channel 2', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, 'live-2', $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->getName()); + $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->getName()); + $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->getName()); + $this->assertEquals('live channel 2', $chan2->getDescription()); + $this->assertEquals(1, count($chan2->getPublishUrls())); + $this->assertEquals(1, count($chan2->getPlayUrls())); + + $this->client->deleteBucketLiveChannel($this->bucketName, 'live-1'); + $this->client->deleteBucketLiveChannel($this->bucketName, 'live-2'); + $list = $this->client->listBucketLiveChannels($this->bucketName, array( + 'prefix' => 'live-' + )); + $this->assertEquals(0, count($list->getChannelList())); + } + + public function testDeleteLiveChannel() + { + $channelName = 'live-to-delete'; + $config = new LiveChannelConfig(array( + 'description' => 'live channel to delete', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, $channelName, $config); + + $this->client->deleteBucketLiveChannel($this->bucketName, $channelName); + $list = $this->client->listBucketLiveChannels($this->bucketName, array( + 'prefix' => $channelName + )); + + $this->assertEquals(0, count($list->getChannelList())); + } + + public function testSignRtmpUrl() + { + $channelName = '90475'; + $bucket = 'douyu'; + $now = time(); + $url = $this->client->signRtmpUrl($bucket, $channelName, 900, array( + 'params' => array( + 'playlistName' => 'playlist.m3u8' + ) + )); + + $ret = parse_url($url); + $this->assertEquals('rtmp', $ret['scheme']); + parse_str($ret['query'], $query); + + $this->assertTrue(isset($query['OSSAccessKeyId'])); + $this->assertTrue(isset($query['Signature'])); + $this->assertTrue(intval($query['Expires']) - ($now + 900) < 3); + $this->assertEquals('playlist.m3u8', $query['playlistName']); + } + + public function testLiveChannelInfo() + { + $channelName = 'live-to-put-status'; + $config = new LiveChannelConfig(array( + 'description' => 'test live channel info', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, $channelName, $config); + + $info = $this->client->getLiveChannelInfo($this->bucketName, $channelName); + $this->assertEquals('test live channel info', $info->getDescription()); + $this->assertEquals('enabled', $info->getStatus()); + $this->assertEquals('HLS', $info->getType()); + $this->assertEquals(10, $info->getFragDuration()); + $this->assertEquals(5, $info->getFragCount()); + $this->assertEquals('playlist.m3u8', $info->getPlayListName()); + + $this->client->deleteBucketLiveChannel($this->bucketName, $channelName); + $list = $this->client->listBucketLiveChannels($this->bucketName, array( + 'prefix' => $channelName + )); + $this->assertEquals(0, count($list->getChannelList())); + } + + public function testPutLiveChannelStatus() + { + $channelName = 'live-to-put-status'; + $config = new LiveChannelConfig(array( + 'description' => 'test live channel info', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, $channelName, $config); + + $info = $this->client->getLiveChannelInfo($this->bucketName, $channelName); + $this->assertEquals('test live channel info', $info->getDescription()); + $this->assertEquals('enabled', $info->getStatus()); + $this->assertEquals('HLS', $info->getType()); + $this->assertEquals(10, $info->getFragDuration()); + $this->assertEquals(5, $info->getFragCount()); + $this->assertEquals('playlist.m3u8', $info->getPlayListName()); + $status = $this->client->getLiveChannelStatus($this->bucketName, $channelName); + $this->assertEquals('Idle', $status->getStatus()); + + + $resp = $this->client->putLiveChannelStatus($this->bucketName, $channelName, "disabled"); + $info = $this->client->getLiveChannelInfo($this->bucketName, $channelName); + $this->assertEquals('test live channel info', $info->getDescription()); + $this->assertEquals('disabled', $info->getStatus()); + $this->assertEquals('HLS', $info->getType()); + $this->assertEquals(10, $info->getFragDuration()); + $this->assertEquals(5, $info->getFragCount()); + $this->assertEquals('playlist.m3u8', $info->getPlayListName()); + + $status = $this->client->getLiveChannelStatus($this->bucketName, $channelName); + //getLiveChannelInfo + $this->assertEquals('Disabled', $status->getStatus()); + + $this->client->deleteBucketLiveChannel($this->bucketName, $channelName); + $list = $this->client->listBucketLiveChannels($this->bucketName, array( + 'prefix' => $channelName + )); + $this->assertEquals(0, count($list->getChannelList())); + + } + public function testLiveChannelHistory() + { + $channelName = 'live-test-history'; + $config = new LiveChannelConfig(array( + 'description' => 'test live channel info', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, $channelName, $config); + + $history = $this->client->getLiveChannelHistory($this->bucketName, $channelName); + $this->assertEquals(0, count($history->getLiveRecordList())); + } +} diff --git a/tests/OSS/Tests/Common.php b/tests/OSS/Tests/Common.php index 454f2f04..e6f37574 100644 --- a/tests/OSS/Tests/Common.php +++ b/tests/OSS/Tests/Common.php @@ -64,7 +64,7 @@ public static function createBucket() public static function waitMetaSync() { if (getenv('TRAVIS')) { - sleep(30); + sleep(60); } } } diff --git a/tests/OSS/Tests/ContentTypeTest.php b/tests/OSS/Tests/ContentTypeTest.php index 8fe0d241..3a3249fe 100644 --- a/tests/OSS/Tests/ContentTypeTest.php +++ b/tests/OSS/Tests/ContentTypeTest.php @@ -41,7 +41,7 @@ public function testByFileName() $file = '/tmp/x.json'; $object = 'test/y'; - $this->runCmd('dd if=/dev/random of=' . $file . ' bs=1024 count=100'); + $this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100'); $client->multiuploadFile($bucket, $object, $file, array('partSize' => 100)); $type = $this->getContentType($bucket, $object); @@ -80,7 +80,7 @@ public function testByObjectKey() $file = '/tmp/x.mp3'; $object = 'test/y.json'; - $this->runCmd('dd if=/dev/random of=' . $file . ' bs=1024 count=100'); + $this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100'); $client->multiuploadFile($bucket, $object, $file, array('partSize' => 100)); $type = $this->getContentType($bucket, $object); @@ -89,7 +89,7 @@ public function testByObjectKey() $file = '/tmp/x.none'; $object = 'test/y.json'; - $this->runCmd('dd if=/dev/random of=' . $file . ' bs=1024 count=100'); + $this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100'); $client->multiuploadFile($bucket, $object, $file, array('partSize' => 100)); $type = $this->getContentType($bucket, $object); @@ -123,7 +123,7 @@ public function testByUser() $file = '/tmp/x.json'; $object = 'test/y'; - $this->runCmd('dd if=/dev/random of=' . $file . ' bs=1024 count=100'); + $this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100'); $client->multiuploadFile($bucket, $object, $file, array( 'partSize' => 100, diff --git a/tests/OSS/Tests/LiveChannelXmlTest.php b/tests/OSS/Tests/LiveChannelXmlTest.php new file mode 100644 index 00000000..531c59a1 --- /dev/null +++ b/tests/OSS/Tests/LiveChannelXmlTest.php @@ -0,0 +1,250 @@ + + + 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; + + private $status = << + + Live + 2016-10-20T14:25:31.000Z + 10.1.2.4:47745 + + + +BBBB; + + private $history = << + + + 2013-11-24T14:25:31.000Z + 2013-11-24T15:25:31.000Z + 10.101.194.148:56861 + + + 2014-11-24T14:25:31.000Z + 2014-11-24T15:25:31.000Z + 10.101.194.148:56862 + + + 2015-11-24T14:25:31.000Z + 2015-11-24T15:25:31.000Z + 10.101.194.148:56863 + + +BBBB; + + public function testLiveChannelStatus() + { + $stat = new GetLiveChannelStatus(); + $stat->parseFromXml($this->status); + + $this->assertEquals('Live', $stat->getStatus()); + $this->assertEquals('2016-10-20T14:25:31.000Z', $stat->getConnectedTime()); + $this->assertEquals('10.1.2.4:47745', $stat->getRemoteAddr()); + + $this->assertEquals(1280, $stat->getVideoWidth()); + $this->assertEquals(536, $stat->getVideoHeight()); + $this->assertEquals(24, $stat->getVideoFrameRate()); + $this->assertEquals(72513, $stat->getVideoBandwidth()); + $this->assertEquals('H264', $stat->getVideoCodec()); + $this->assertEquals(6519, $stat->getAudioBandwidth()); + $this->assertEquals(44100, $stat->getAudioSampleRate()); + $this->assertEquals('AAC', $stat->getAudioCodec()); + + } + + public function testLiveChannelHistory() + { + $history = new GetLiveChannelHistory(); + $history->parseFromXml($this->history); + + $recordList = $history->getLiveRecordList(); + $this->assertEquals(3, count($recordList)); + + $list0 = $recordList[0]; + $this->assertEquals('2013-11-24T14:25:31.000Z', $list0->getStartTime()); + $this->assertEquals('2013-11-24T15:25:31.000Z', $list0->getEndTime()); + $this->assertEquals('10.101.194.148:56861', $list0->getRemoteAddr()); + + $list1 = $recordList[1]; + $this->assertEquals('2014-11-24T14:25:31.000Z', $list1->getStartTime()); + $this->assertEquals('2014-11-24T15:25:31.000Z', $list1->getEndTime()); + $this->assertEquals('10.101.194.148:56862', $list1->getRemoteAddr()); + + $list2 = $recordList[2]; + $this->assertEquals('2015-11-24T14:25:31.000Z', $list2->getStartTime()); + $this->assertEquals('2015-11-24T15:25:31.000Z', $list2->getEndTime()); + $this->assertEquals('10.101.194.148:56863', $list2->getRemoteAddr()); + + } + + public function testLiveChannelConfig() + { + $config = new LiveChannelConfig(array('name' => 'live-1')); + $config->parseFromXml($this->config); + + $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('name' => 'live-2')); + $config2->parseFromXml($xml); + $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 testLiveChannelInfo() + { + $info = new LiveChannelInfo(array('name' => 'live-1')); + $info->parseFromXml($this->info); + + $this->assertEquals('live-1', $info->getName()); + $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 testLiveChannelList() + { + $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->getName()); + $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->getName()); + $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]); + } + +} diff --git a/tests/OSS/Tests/OssClientImageTest.php b/tests/OSS/Tests/OssClientImageTest.php new file mode 100644 index 00000000..73c5f2fd --- /dev/null +++ b/tests/OSS/Tests/OssClientImageTest.php @@ -0,0 +1,108 @@ +client = Common::getOssClient(); + $this->bucketName = 'php-sdk-test-bucket-image-' . strval(rand(0, 10)); + $this->client->createBucket($this->bucketName); + Common::waitMetaSync(); + sleep(30); + $this->local_file = "example.jpg"; + $this->object = "oss-example.jpg"; + $this->download_file = "image.jpg"; + + $this->client->uploadFile($this->bucketName, $this->object, $this->local_file); + } + + public function tearDown() + { + $this->client->deleteObject($this->bucketName, $this->object); + $this->client->deleteBucket($this->bucketName); + } + + public function testImageResize() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + 'x-oss-process' => "image/resize,m_fixed,h_100,w_100", ); + $this->check($options, 100, 100, 3587, 'jpg'); + } + + public function testImageCrop() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + 'x-oss-process' => "image/crop,w_100,h_100,x_100,y_100,r_1", ); + $this->check($options, 100, 100, 2281, 'jpg'); + } + + public function testImageRotate() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + 'x-oss-process' => "image/rotate,90", ); + $this->check($options, 267, 400, 21509, 'jpg'); + } + + public function testImageSharpen() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + 'x-oss-process' => "image/sharpen,100", ); + $this->check($options, 400, 267, 24183, 'jpg'); + } + + public function testImageWatermark() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + 'x-oss-process' => "image/watermark,text_SGVsbG8g5Zu-54mH5pyN5YqhIQ", ); + $this->check($options, 400, 267, 26953, 'jpg'); + } + + public function testImageFormat() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + 'x-oss-process' => "image/format,png", ); + $this->check($options, 400, 267, 160733, 'png'); + } + + public function testImageTofile() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + 'x-oss-process' => "image/resize,m_fixed,w_100,h_100", ); + $this->check($options, 100, 100, 3587, 'jpg'); + } + + private function check($options, $width, $height, $size, $type) + { + $this->client->getObject($this->bucketName, $this->object, $options); + $array = getimagesize($this->download_file); + $this->assertEquals($width, $array[0]); + $this->assertEquals($height, $array[1]); + $this->assertEquals($type === 'jpg' ? 2 : 3, $array[2]);//2 <=> jpg + $this->assertEquals($size, ceil(filesize($this->download_file))); + } +} diff --git a/tests/OSS/Tests/TestOssClientBase.php b/tests/OSS/Tests/TestOssClientBase.php index 12b81a26..80e6bfbb 100644 --- a/tests/OSS/Tests/TestOssClientBase.php +++ b/tests/OSS/Tests/TestOssClientBase.php @@ -27,6 +27,7 @@ public function setUp() public function tearDown() { + sleep(60); if (!$this->ossClient->doesBucketExist($this->bucket)) { return; }