'其他', self::TYPE_IMAGE => '图片', self::TYPE_VIDEO => '视频', self::TYPE_AUDIO => '音频', ]; public static function getAllType() { return self::$arrType; } /** * @param $tmpPath * @param $filename * @param $mimeType * @param $forever * @return mixed|null * @throws Exception */ public function getFileUrl($tmpPath, $filename, $mimeType, $forever = false) { // 控制频率 $objLock = new Lock('file_upload', 300, 50); $uid = User::getUserId(); $objLock->lock($uid); if (!file_exists($tmpPath)) { throw new Exception('file not exists', CODE_PARAM_ERROR); } $md5 = md5_file($tmpPath); $row = $this->objTable->getRow(['id' => $md5]); if ($row['forever'] || (strtotime($row['update_time'])+20*86400 > time())) { return $row['url']; } $ext = pathinfo($filename, PATHINFO_EXTENSION); $type = self::getType($mimeType); $filename = self::getFileName($md5, $tmpPath, $type, $ext); $url = self::s3PutObject($tmpPath, $filename, $mimeType, $forever); if ($url) { $this->objTable->replaceObject([ 'id' => $md5, 'url' => $url, 'type' => $type, 'update_time' => date('Y-m-d H:i:s'), 'forever' => $forever ? 1 : 0, ]); } $objLock->unlock($uid); return $url; } private static function getFileName($md5, $path, $type, $ext = '') { if ($type == self::TYPE_IMAGE) { if (!class_exists('Imagick')) { $len = filesize($path); $arr = getimagesize($path); $str = sprintf('%s_%s_%s', $md5, "size{$arr[0]}x{$arr[1]}", "len{$len}"); } else { list($color, $width, $height, $len) = self::getImageMainColor($path); $str = sprintf('%s_%s_%s_%s', $md5, "size{$width}x{$height}", "len{$len}", $color); } } else { $len = filesize($path); $str = sprintf('%s_%s', $md5, "len{$len}"); } $ext && $str .= ".{$ext}"; return $str; } /** * 获取类型 * @author solu * @param $mineType * @return int */ public static function getType($mineType) { if (false !== strpos($mineType, 'image')) { return self::TYPE_IMAGE; } elseif (false !== strpos($mineType, 'video')) { return self::TYPE_VIDEO; } elseif (false !== strpos($mineType, 'audio')) { return self::TYPE_AUDIO; } return self::TYPE_OTHER; } /** * 上传文件 * @author solu * @param $path * @param $name * @param $mime * @param $forever * @return string * @throws Exception */ private static function s3PutObject($path, $name, $mime, $forever = false) { $s3 = new S3Client([ 'version' => 'latest', 'region' => 'ap-northeast-1', 'scheme' => 'http', 'credentials' => [ 'key' => AWS_ACCESS_KEY, 'secret' => AWS_SECRET_KEY, ], ]); $bucket = $forever ? BUCKET_MEE : BUCKET_MEE_TMP; $option = [ 'Bucket' => $bucket, 'Key' => $name, 'CacheControl' => 'max-age=8640000', // 前端缓存100天 'Body' => fopen($path, 'r'), 'ACL' => 'public-read', 'ContentType' => $mime, ]; $result = $s3->putObject($option); $url = $result->get('ObjectURL'); if (!$url) { throw new Exception('upload to s3 error', CODE_NORMAL_ERROR); } return self::_fixUrl($url, $forever); } /** * 转换url * @author solu * @param $url * @param $forever * @return string */ private static function _fixUrl($url, $forever = false) { $cdn = $forever ? CDN_HOST : CDN_HOST_TMP; if (strpos($url, $cdn) === false) { $pos = strrpos($url, '/') + 1; $path = substr($url, $pos); return sprintf('https://%s/%s', $cdn, $path); } return $url; } /** * 视频封面图 * @author solu * @param $filePath * @param $filename * @return mixed|null * @throws Exception */ public function getVideoCover($filePath, $filename) { $info = pathinfo($filename); $imageName = $info['filename'] . '.jpg'; $imagePath = self::TMP_DIR . $imageName; if (!file_exists(self::TMP_DIR)) { mkdir(self::TMP_DIR, 0777, true); } exec("ffmpeg -ss 00:00:00 -i '{$filePath}' -y -f image2 -vframes 1 {$imagePath} 1>/dev/null 2>/dev/null"); if(!filesize($imagePath)) { return null; } $url = $this->getFileUrl($imagePath, $imageName, 'image/jpeg'); unlink($imagePath); return $url; } /** * 获取图片主色调 * @author solu * @param $path * @return array */ public static function getImageMainColor($path) { $color = ''; $width = 0; $height = 0; $len = 0; if (!class_exists('Imagick')) { return []; } try { $image = new \Imagick($path); //$file 图片存储地址或者url地址 $width = $image->getImageWidth(); $height = $image->getImageHeight(); $len = $image->getImageLength(); $image->quantizeImage(1, \Imagick::COLORSPACE_RGB, 0, false, false); //获取到只剩1个颜色值, 也可以多取几个 $image->uniqueImageColors(); $iter = $image->getPixelIterator(); $iter->resetIterator(); $row = $iter->getNextIteratorRow(); $row = $row[0]; $arrColor = $row->getColor(); $color = sprintf("%02x%02x%02x", $arrColor['r'], $arrColor['g'], $arrColor['b']); } catch (Exception $e) {} return [$color, $width, $height, $len]; } }