<?php /** * 七牛API */ abstract class Qiniu { private static $ak = ''; private static $sk = ''; /** * 安全的base64编码 */ private static function safeBase64Encode($str) { $find = array("+", "/"); $replace = array("-", "_"); return str_replace($find, $replace, base64_encode($str)); } /** * 安全的base64解码 */ private static function safeBase64Decode($str) { $find = array("-", "_"); $replace = array("+", "/"); return base64_decode(str_replace($find, $replace, $str)); } private static function hmac_sha1($str, $key) { return hash_hmac("sha1", $str, $key, true); } /** * 管理凭证 * @param $url 要上传的URL * @param $body POST时的内容 */ private static function getAccessToken($url, $body = array()) { $urlInfo = parse_url($url); $signingStr = $urlInfo['path']; if(!empty($urlInfo['query'])) { $signingStr .= '?' . $urlInfo['query']; } $signingStr .= "\n"; if(!empty($body)) { $signingStr .= http_build_query($body); } $sign = self::safeBase64Encode(self::hmac_sha1($signingStr, self::$sk)); $accessToken = self::$ak . ":" . $sign; return $accessToken; } /** * 上传文件(非视频)凭证 */ public static function getUploadFileToken($scope, $extTime = 43200, $returnUrl = '', $callbackUrl = '') { $policy = array(); $policy['scope'] = $scope; $policy['deadline'] = time() + $extTime; $body = array(); $body['key'] = '$(key)'; $body['name'] = '$(fname)'; $body['size'] = '$(fsize)'; $body['mime'] = '$(mimeType)'; $body['suffix'] = '$(suffix)'; $body['hash'] = '$(etag)'; $body['width'] = '$(imageInfo.width)'; $body['height'] = '$(imageInfo.height)'; if(!empty($returnUrl)) { $body['exif'] = '$(exif)'; $body['imageInfo'] = '$(imageInfo)'; $body['imageAve'] = '$(imageAve)'; } if(!empty($callbackUrl)) { $body['exif'] = '$(exif)'; $body['imageInfo'] = '$(imageInfo)'; $body['imageAve'] = '$(imageAve)'; $policy['callbackUrl'] = $callbackUrl; $policy['callbackBody'] = json_encode($body); } else { $policy['returnUrl'] = $returnUrl; $policy['returnBody'] = json_encode($body); } $putPolicy = self::safeBase64Encode(json_encode($policy)); $sign = self::safeBase64Encode(self::hmac_sha1($putPolicy, self::$sk)); $uploadToken = self::$ak . ':' . $sign . ':' . $putPolicy; return $uploadToken; } /** * 视频上传凭证 * markPos位置: * NorthWest | North | NorthEast * West | Center | East * SouthWest | South | SouthEast */ public static function getUploadMediaToken($scope, $extTime = 43200, $notifyUrl, $mark = '', $markPos = 'NorthEast') { $policy = array(); $policy['scope'] = $scope; $policy['deadline'] = time() + $extTime; $ops = array(); if(!empty($mark)) { $ops[] = 'avthumb/mp4/wmImage/' . self::safeBase64Encode($mark) . '/Gravity/' . $markPos; //转码成MP4 $ops[] = 'avthumb/m3u8/preset/video_1000k/wmImage/' . self::safeBase64Encode($mark) . '/Gravity/' . $markPos; //转码成M3U8 } else { $ops[] = 'avthumb/mp4'; $ops[] = 'avthumb/m3u8/preset/video_1000k'; } $policy['persistentOps'] = implode(';', $ops); $policy['persistentNotifyUrl'] = $notifyUrl; $putPolicy = self::safeBase64Encode(json_encode($policy)); $sign = self::safeBase64Encode(self::hmac_sha1($putPolicy, self::$sk)); $uploadToken = self::$ak . ':' . $sign . ':' . $putPolicy; return $uploadToken; } /** * 下载凭证(私有空间时使用) */ public static function getDownloadToken($url, $extTime = 43200) { $e = 'e=' . (time() + $extTime); if(preg_match('/\?/ism', $url)) { $url .= '&' . $e; } else { $url .= '?' . $e; } $sign = self::safeBase64Encode(self::hmac_sha1($url, self::$sk)); $downloadToken = self::$ak . ":" . $sign; //$realDownloadUrl = $url . '&token=' . $downloadToken; return $e . '&token=' . $downloadToken; } /** * 查询处理状态 */ public static function getPersistentInfo($persistentID) { $url = 'http://api.qiniu.com/status/get/prefop?id=' . $persistentID; $html = Http::request(array('url' => $url)); $json = json_decode($html['html'], true); if(empty($json['code'])) { return array(); } else { return $json; } } /** * 触发式音视频转换 * 水印:avthumb/wmImage/safeBase64Encode(image url)/Gravity/位置 * 位置: * NorthWest | North | NorthEast * West | Center | East * SouthWest | South | SouthEast */ public static function convertMedia($scope, $key, $notifyUrl, $mark = '', $markPos = 'NorthEast') { $url = "http://api.qiniu.com/pfop/"; $ops = array(); if(!empty($mark)) { $ops[] = 'avthumb/mp4/wmImage/' . self::safeBase64Encode($mark) . '/Gravity/' . $markPos; //转码成MP4 $ops[] = 'avthumb/m3u8/preset/video_1000k/wmImage/' . self::safeBase64Encode($mark) . '/Gravity/' . $markPos; //转码成M3U8 } else { $ops[] = 'avthumb/mp4'; $ops[] = 'avthumb/m3u8/preset/video_1000k'; } $data = array(); $data['bucket'] = $scope; $data['key'] = $key; $data['fops'] = implode(';', $ops); $data['notifyURL'] = $notifyUrl; $accessToken = self::getAccessToken($url, $data); $header = array(); $header[] = 'Authorization: QBox ' . $accessToken; $html = Http::request(array('url' => $url, 'data' => $data, 'httpheader' => $header)); $json = json_decode($html['html'], true); if(empty($json['persistentId'])) { return ''; } else { return $json['persistentId']; } } /** * 视频截图 * 截图:vframe/(jpg|png)/offset/秒数/w/宽/h/高/rotate/旋转(空|90|180|270|auto) */ public static function getVideoImage($scope, $key, $notifyUrl, $second, $width, $height, $rotate = '') { $url = "http://api.qiniu.com/pfop/"; $data = array(); $data['bucket'] = $scope; $data['key'] = $key; $data['fops'] = sprintf('vframe/jpg/offset/%s/w/%s/h/%s', $second, $width, $height); if(!empty($rotate)) { $data['fops'] .= $data['fops'] . '/rotate/' . $rotate; } $data['notifyURL'] = $notifyUrl; $accessToken = self::getAccessToken($url, $data); $header = array(); $header[] = 'Authorization: QBox ' . $accessToken; $html = Http::request(array('url' => $url, 'data' => $data, 'httpheader' => $header)); //http://api.qiniu.com/status/get/prefop?id=53b05821c868fc3b200498ba $json = json_decode($html['html'], true); if(empty($json['persistentId'])) { return ''; } else { return $json['persistentId']; } } /** * 得到音视频信息 */ public static function getMediaInfo($scope, $key, $private = false, $extTime = 3600) { if(preg_match('/\?/ism', $url)) { $url = 'http://' . $scope . '.qiniudn.com/' . $key . '&avinfo'; } else { $url = 'http://' . $scope . '.qiniudn.com/' . $key . '?avinfo'; } if($private) { $url .= '&' . self::getDownloadToken($url, $extTime); } $html = Http::request(array('url' => $url)); $json = json_decode($html['html'], true); if(empty($json['streams'])) { return array(); } else { return $json; } } /** * 得到图片信息 */ public static function getImageInfo($scope, $key, $private = false, $extTime = 120) { $url = 'http://' . $scope . '.qiniudn.com/' . $key . '?imageInfo'; if($private) { $url .= '&' . self::getDownloadToken($url, $extTime); } $html = Http::request(array('url' => $url)); $json = json_decode($html['html'], true); if(empty($json['format'])) { return array(); } else { return $json; } } /** * 得到图片Exif */ public static function getImageExif($scope, $key, $private = false, $extTime = 120) { $url = 'http://' . $scope . '.qiniudn.com/' . $key . '?exif'; if($private) { $url .= '&' . self::getDownloadToken($url, $extTime); } $html = Http::request(array('url' => $url)); $json = json_decode($html['html'], true); if(empty($json['error'])) { return $json; } else { return array(); } } /** * 得到图片主颜色(RGB值) */ public static function getImageRGB($scope, $key, $private = false) { $url = 'http://' . $scope . '.qiniudn.com/' . $key . '?imageAve'; if($private) { $url .= '&' . self::getDownloadToken($url); } $html = Http::request(array('url' => $url)); $json = json_decode($html['html'], true); if(empty($json['RGB'])) { return ''; } else { return $json['RGB']; } } /** * 得到缩略图片地址 * @param $imageParam * array('width' => 100, * 'height' => 100, * 'format' => '', * 'crop_type' => 'Center', * 'crop_width' => '', * 'crop_height' => '', * 'rotate' => '', * 'blur' => '3x5', * 'mark_url' => '', * 'mark_type' => '', * 'mark_dissolve' => '') * 参数说明: * width,height 当某一项为0时,以另一个为主 * format 指定输出格式:空为原图格式,jpg,gif,png,webp * crop_type 是否进行裁剪,如果要进行裁剪,则width和height不能为0 * crop_type取值: * NorthWest | North | NorthEast * West | Center | East * SouthWest | South | SouthEast * * crop_width,crop_height 当需要进行裁剪时,必需填写此两个值 * rotate 旋转,取值:1-360 * blur 高斯模糊,取值:1-50 */ public static function getImageZoomUrl($scope, $key, $imageParam = array(), $private = false, $extTime = 43200) { $url = 'http://' . $scope . '.qiniudn.com/' . $key . '?imageMogr2/auto-orient/strip/thumbnail'; if(isset($imageParam['width']) && !empty($imageParam['width'])) { //正比例缩放 $url .= '/' . $imageParam['width'] . 'x'; } if(isset($imageParam['height']) && !empty($imageParam['height'])) { //正比例缩放 if(substr($url, strlen($url) - 1, 1) == 'x') { $url .= $imageParam['height']; } else { $url .= '/x' . $imageParam['height']; } } if(isset($imageParam['format']) && !empty($imageParam['format'])) { //设置输出格式 $url .= '/format/' . $imageParam['format']; //如果输出为jpg格式,则设置渐进显示模式 if($imageParam['format'] == 'jpg') { $url .= '/interlace/1'; } } if(isset($imageParam['rotate']) && !empty($imageParam['rotate'])) { //设置旋转 $url .= '/rotate/' . $imageParam['rotate']; } if(isset($imageParam['blur']) && !empty($imageParam['blur'])) { //设置模糊 $url .= '/blur/' . $imageParam['blur']; } if(isset($imageParam['crop_type']) && !empty($imageParam['crop_type'])) { //设置裁剪模式 $url .= '/gravity/' . $imageParam['crop_type'] . '/crop'; if(isset($imageParam['crop_width']) && !empty($imageParam['crop_width'])) { //正比例缩放 $url .= '/' . $imageParam['crop_width'] . 'x'; } if(isset($imageParam['crop_height']) && !empty($imageParam['crop_height'])) { //正比例缩放 if(substr($url, strlen($url) - 1, 1) == 'x') { $url .= $imageParam['crop_height']; } else { $url .= '/x' . $imageParam['crop_height']; } } } if(isset($imageParam['mark_url']) && !empty($imageParam['mark_url'])) { //打水印 $url .= '|watermark/1/image/' . self::safeBase64Encode($imageParam['mark_url']); if(isset($imageParam['mark_dissolve']) && !empty($imageParam['mark_dissolve'])) { //透明度 $url .= '/dissolve/' . $imageParam['mark_dissolve']; } if(isset($imageParam['mark_type']) && !empty($imageParam['mark_type'])) { //水印位置 $url .= '/gravity/' . $imageParam['mark_type']; } } if($private) { $url .= '&' . self::getDownloadToken($url, $extTime); } return $url; } /** * 得到链接 */ public static function getUrl($scope, $key, $private = false, $extTime = 43200) { $url = 'http://' . $scope . '.qiniudn.com/' . $key; if($private) { $url .= '?' . self::getDownloadToken($url, $extTime); } return $url; } /** * 抓取资源 */ public static function fetchUrl($scope, $key, $url) { $fileName = self::safeBase64Encode($scope . ':' . $key); $fetchUrl = self::safeBase64Encode($url); $url = 'http://iovip.qbox.me/fetch/' . $fetchUrl . '/to/' . $fileName; $accessToken = self::getAccessToken($url); $header = array(); $header[] = 'Authorization: QBox ' . $accessToken; $html = Http::request(array('url' => $url, 'httpheader' => $header, 'timeout' => 60)); $json = json_decode($html['html'], true); if(empty($json)) { return true; } else { return false; } } /** * 删除资源 */ public static function delKey($scope, $key) { $fileName = self::safeBase64Encode($scope . ':' . $key); $url = 'http://rs.qiniu.com/delete/' . $fileName; $accessToken = self::getAccessToken($url); $header = array(); $header[] = 'Authorization: QBox ' . $accessToken; $html = Http::request(array('url' => $url, 'httpheader' => $header, 'timeout' => 60)); $json = json_decode($html['html'], true); if(empty($json)) { return true; } else { return false; } } /** * 移动资源 */ public static function moveKey($scopeSrc, $keySrc, $scopeDest, $keyDest) { $keySrc = self::safeBase64Encode($scopeSrc . ':' . $keySrc); $keyDest = self::safeBase64Encode($scopeDest . ':' . $keyDest); $url = 'http://rs.qiniu.com/move/' . $keySrc . '/' . $keyDest; $accessToken = self::getAccessToken($url); $header = array(); $header[] = 'Authorization: QBox ' . $accessToken; $html = Http::request(array('url' => $url, 'httpheader' => $header, 'timeout' => 60)); $json = json_decode($html['html'], true); if(empty($json)) { return true; } else { return false; } } /** * 复制资源 */ public static function copyKey($scopeSrc, $keySrc, $scopeDest, $keyDest) { $keySrc = self::safeBase64Encode($scopeSrc . ':' . $keySrc); $keyDest = self::safeBase64Encode($scopeDest . ':' . $keyDest); $url = 'http://rs.qiniu.com/copy/' . $keySrc . '/' . $keyDest; $accessToken = self::getAccessToken($url); $header = array(); $header[] = 'Authorization: QBox ' . $accessToken; $html = Http::request(array('url' => $url, 'httpheader' => $header, 'timeout' => 60)); $json = json_decode($html['html'], true); if(empty($json)) { return true; } else { return false; } } /** * 上传文件(直传) */ public static function uploadFile($scope, $key, $fileName, $extTime = 86400, $notifyUrl = '') { $data = array(); if(empty($notifyUrl)) { $data['token'] = self::getUploadFileToken($scope, $extTime); } else { $data['token'] = self::getUploadMediaToken($scope, $extTime, $notifyUrl); } $data['filename'] = basename($fileName); $data['file'] = '@' . $fileName; $data['key'] = $key; $data['upload_file'] = true; $html = Http::request(array('url' => 'http://up.qiniu.com', 'data' => $data, 'timeout' => 5 * 60)); print_r($html); $json = json_decode($html['html'], true); if(empty($json['key'])) { return array(); } else { if(empty($notifyUrl)) { $json['name'] = basename($fileName); return $json; } else { return array('persistentId' => $json['persistentId']); } } } /** * 文件上传(分片) */ public static function uploadFileSplit($scope, $key, $file, $extTime = 86400, $notifyUrl = '') { $fileSize = 0; $ctxInfo = array(); $host = 'http://up.qiniu.com'; $header = array(); if(empty($notifyUrl)) { $header[] = 'Authorization: UpToken ' . self::getUploadFileToken($scope, $extTime); } else { $header[] = 'Authorization: UpToken ' . self::getUploadMediaToken($scope, $extTime, $notifyUrl); } $fp = fopen($file, 'rb'); while(!feof($fp)) { $data = fread($fp, 4194304); //4194304为4M的字节数 4 * 1024 * 1024 $fileSize += strlen($data); $url = $host . '/mkblk/' . strlen($data); $html = Http::request(array('url' => $url, 'data' => $data, 'timeout' => 5 * 60, 'httpheader' => $header)); $json = json_decode($html['html'], true); if(empty($json['crc32'])) { return array(); } else { $ctxInfo[] = $json['ctx']; $host = $json['host']; } } $ctxData = implode(',', $ctxInfo); $url = $host . '/mkfile/' . $fileSize . '/key/' . self::safeBase64Encode($key); $html = Http::request(array('url' => $url, 'data' => $ctxData, 'timeout' => 5 * 60, 'httpheader' => $header)); $json = json_decode($html['html'], true); if(empty($json['key'])) { return array(); } else { if(empty($notifyUrl)) { return $json; } else { return array('persistentId' => $json['persistentId']); } } } } ?>