123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- <?php
- /**
- * 文件地址
- * @author solu
- */
- use Aws\S3\S3Client;
- class FileUrl extends Model {
- protected $tableName = 'file_url';
- protected $dbKey = 'dw_chat';
- const TMP_DIR = '/tmp/mee/';
- const TYPE_OTHER = 0; // 其他
- const TYPE_IMAGE = 1; // 图片
- const TYPE_VIDEO = 2; // 视频
- const TYPE_AUDIO = 3; // 音频
- private static $arrType = [
- self::TYPE_OTHER => '其他',
- 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];
- }
- }
|