Eyemargin.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. <?php
  2. namespace app\api\controller;
  3. use Limen\Redisun\Examples\HashModel;
  4. use Limen\Redisun\Examples\StringModel;
  5. use think\Db;
  6. use think\Cache;
  7. include_once '../vendor/aliyun/aliyun-php-sdk-core/Config.php';
  8. use Mts\Request\V20140618 as Mts;
  9. /**
  10. * 眼缘接口
  11. */
  12. class Eyemargin extends Common
  13. {
  14. protected $noNeedLogin = ['mpsvideo', 'getencoderesult'];
  15. protected $noNeedRight = '*';
  16. public function _initialize()
  17. {
  18. parent::_initialize();
  19. }
  20. /**
  21. * 发布眼缘
  22. */
  23. public function addFate() {
  24. $eye_type = $this->request->request('eye_type'); // 动态类型
  25. $content = $this->request->request('content'); // 内容
  26. if (!in_array($eye_type,[1,2]) || !$content) {
  27. $this->error(__('Invalid parameters'));
  28. }
  29. $str_arr = sensitive($content);
  30. if($str_arr['count'] > 0) {
  31. $this->error(__('发布内容存在敏感词汇:'.$str_arr['sensitiveWord'].' 请重新编辑后发布!'));
  32. }
  33. // 判断当前用户是否实名认证
  34. // $userAuthInfo = \app\common\model\UserAuth::userIsAuth($this->auth->id);
  35. // if($userAuthInfo['status'] == 0) $this->error($userAuthInfo['msg']);
  36. //限制视频数量
  37. $eyemargin_count = Db::name('eyemargin')->where(['user_id' => $this->auth->id])->count('id');
  38. if ($eyemargin_count >= 10) {
  39. $this->error('眼缘最多发布10个');
  40. }
  41. $data = [];
  42. $data["user_id"] = $this->auth->id;
  43. $data["eye_type"] = $eye_type;
  44. $data["content"] = $content;
  45. if($eye_type == 2) {
  46. $cover = $this->request->request('cover'); // 影集封面图
  47. $album = $this->request->request('album'); // 影集图片
  48. $music = $this->request->request('music'); // 背景音乐
  49. if(!$cover || !$album || !$music) {
  50. $this->error(__('Invalid parameters'));
  51. }
  52. $data['cover'] = $cover;
  53. $data['album'] = $album;
  54. $data['music'] = $music;
  55. } elseif($eye_type == 1) {
  56. $video = $this->request->request('video'); // 视频文件
  57. if(!$video) {
  58. $this->error(__('视频图片缺失!'));
  59. }
  60. $cover = $this->request->request('cover'); // 影集封面图
  61. $data['cover'] = $cover;
  62. // $video_cover = str_replace("https://","http://",$video);
  63. // $cover = 'uploads/video_cover/'.date('Ymd').date('His').rand(1000,9999).'.png';
  64. // getVideoCover($video_cover,2,$cover);
  65. // $full_cover = $_SERVER["REQUEST_SCHEME"]."://".$_SERVER["HTTP_HOST"].'/'.$cover;
  66. // $data['cover'] = $full_cover;
  67. $data['video'] = $video;
  68. //视频转码加logo
  69. $oss_input_object = substr($data['video'], strpos($data['video'], 'uploads'));
  70. $oss_output_object = str_replace('uploads', 'output', $oss_input_object);
  71. $result = $this->mpsvideo($oss_input_object, $oss_output_object);
  72. if (!$result) {
  73. $this->error('网络错误,请稍后重试');
  74. }
  75. $data['jobid'] = $result;
  76. }
  77. $eyemarginModel = new \app\common\model\Eyemargin();
  78. $data["createtime"] = time();
  79. // 判断是否是第一个视频
  80. $info = $eyemarginModel->where(['user_id'=>$this->auth->id,'status'=>['in',[0,1]]])->find();
  81. if(!$info) {
  82. $data['is_main'] = 1;
  83. $msg = "恭喜,视频已发布审核中!温馨提示:长按可以取消或者修改'推荐'短视频,推荐的视频会展示给同城好友哦";
  84. } else {
  85. $msg = "发布成功!请耐心等待审核!";
  86. }
  87. $res = $eyemarginModel->insertGetId($data);
  88. if($res) {
  89. $this->success($msg);
  90. } else {
  91. $this->error("网络错误,请稍后重试");
  92. }
  93. }
  94. /**
  95. * 当数据为空时
  96. * @param $is_goddess
  97. * @param $is_new
  98. * @param $redis_ids
  99. * @param $field
  100. * @param $user_id
  101. * @return false|mixed|\PDOStatement|string|\think\Collection
  102. */
  103. private function getFateInfo($redis_ids,$field,$user_id,&$common_where) {
  104. $redis_ids && $common_where['a.id'] = ['not in',implode(',',$redis_ids)];
  105. // 按照距离排序
  106. $where = [];
  107. $where = array_merge($where,$common_where);
  108. $a = \app\common\model\Eyemargin::getDistanceList($this->auth->lng,$this->auth->lat,$field,$where,$user_id);
  109. return $a;
  110. }
  111. /**
  112. * 获取眼缘视频/影集
  113. */
  114. public function getFate() {
  115. $is_city = $this->request->request('is_city'); // 是否同城:1=是,0=否
  116. $is_goddess = $this->request->request('is_goddess'); // 是否女神:1=是,0=否
  117. $is_new = $this->request->request('is_new'); // 是否新人:1=是,0=否
  118. $is_neal = $this->request->request('is_neal'); // 是否附近:1=是,0=否
  119. if (!in_array($is_city,[0,1]) && !in_array($is_goddess,[0,1]) && !in_array($is_new,[0,1]) && !in_array($is_neal,[0,1])) {
  120. $this->error(__('请选择展示tab!'));
  121. }
  122. $pageNum = $this->request->request('pageNum',10); // 每页显示条数
  123. $user_id = $this->auth->id;
  124. $user_id_redis = 'u_'.$user_id;
  125. $redis_ids = json_decode(Cache::get($user_id_redis),true);
  126. $time = time() - 30*86400;
  127. $common_where = [];
  128. // $common_where['u.avatar'] = ['like', 'https%'];
  129. if (!$is_city) {
  130. $common_where['a.is_main'] = 1;
  131. }
  132. $common_where['a.status'] = 1;
  133. !$is_goddess && $common_where['u.city'] = $this->auth->city;
  134. // $is_goddess && $common_where['u.is_goddess'] = 1;
  135. // $is_new && $common_where['u.createtime'] = ['gt',$time];
  136. /*if ($this->auth->gender == 1) {
  137. //男只能看女视频
  138. $common_where['u.gender'] = 0;
  139. // $common_where['u.wechat'] = ['neq', '']; //女生微信号必须审核通过
  140. } else {
  141. //女只能看男视频
  142. $common_where['u.gender'] = 1;
  143. }*/
  144. $field = "a.*,u.avatar,u.city_name,u.district_name,u.nickname,u.is_goddess,u.is_auth,vipStatus(u.vip_duetime) as is_vip,
  145. u.age,u.constellation,u.hobby_ids,u.profession,u.declaration,u.lng,u.lat,u.mobile,u.copy_mobile,u.wechat,u.gender,u.profession";
  146. $list = [];
  147. $a = $this->getFateInfo($redis_ids,$field,$user_id,$common_where);
  148. if(!$a) {
  149. Cache::rm($user_id_redis);
  150. unset($common_where['a.id']);
  151. $redis_ids = [];
  152. $a = $this->getFateInfo($redis_ids,$field,$user_id,$common_where);
  153. }
  154. // // 女神
  155. // $where = [];
  156. // $where['u.is_goddess'] = 1;
  157. // $where = array_merge($where,$common_where);
  158. // $b = \app\common\model\Eyemargin::getDistanceList($this->auth->lng,$this->auth->lat,$field,$where,$user_id);
  159. // // 喜好 期望对象
  160. // $expect = $this->auth->expect_ids;
  161. // $user_ids =\app\common\model\Expect::getTagsByExpect($expect);
  162. // if($user_ids) {
  163. // $where = [];
  164. // $where['u.id'] = ['in',implode(',',$user_ids)];
  165. // $where = array_merge($where,$common_where);
  166. // $c = \app\common\model\Eyemargin::getDistanceList($this->auth->lng,$this->auth->lat,$field,$where,$user_id);
  167. // } else {
  168. // $c = [];
  169. // }
  170. //
  171. // // 新人
  172. // $where = [];
  173. // $where['u.createtime'] = ['gt',$time];
  174. // $where = array_merge($where,$common_where);
  175. // $d = \app\common\model\Eyemargin::getDistanceList($this->auth->lng,$this->auth->lat,$field,$where,$user_id);
  176. // // 剩余
  177. //
  178. // // 三数组合并
  179. // $bcd = \app\common\model\Eyemargin::arrayMerge($b,$c,$d);
  180. //
  181. // $e = array_diff($a,$bcd);
  182. //
  183. // // 附近
  184. //
  185. // $num_a = floor(config("site.nearbyTheOne") * 0.01 * $pageNum);
  186. // $num_bcd = floor(config("site.nearbyTheTwo") * 0.01 * $pageNum);
  187. // $num_e = $pageNum - $num_a - $num_bcd;
  188. //
  189. // // 先做好去重
  190. // $a = array_slice($a,0,$pageNum);
  191. // $bcd = array_diff($bcd,$a);
  192. // $e = array_diff($e,array_merge($bcd,$a));
  193. //
  194. //
  195. // $count_a = count($a);
  196. // $count_e = count($e);
  197. // $count_bcd = count($bcd);
  198. // if($count_a <= ($num_a+$num_bcd+$num_e)) {
  199. // $list = $a;
  200. // }
  201. //
  202. // if($count_a >= $num_a && $count_bcd >= $num_bcd && $count_e >= $num_e) {
  203. // $list_a = array_slice($a,0,$num_a);
  204. // $list_bcd = array_slice($bcd,0,$num_bcd);
  205. // $list_e = array_slice($e,0,$num_e);
  206. // $list = \app\common\model\Eyemargin::arrayMerge($list_a,$list_bcd,$list_e);
  207. // }
  208. // // 10 = 10 =
  209. // if($count_a >= $num_a && $count_bcd >= $num_bcd && $count_e < $num_e) {
  210. //
  211. // $list_a = array_slice($a,0,$pageNum-$num_bcd - $count_e);
  212. // $list_bcd = array_slice($bcd,0,$num_bcd);
  213. // $list_e = $e;
  214. // $list = \app\common\model\Eyemargin::arrayMerge($list_a,$list_bcd,$list_e);
  215. // }
  216. // if($count_a >= $num_a && $count_bcd < $num_bcd && $count_e < $num_e) {
  217. // $list_a = array_slice($a,0,$pageNum-$count_bcd-$count_e);
  218. // $list_bcd = $bcd;
  219. // $list_e = $e;
  220. // $list = \app\common\model\Eyemargin::arrayMerge($list_a,$list_bcd,$list_e);
  221. // }
  222. // if($count_a >= $num_a && $count_bcd < $num_bcd && $count_e >= $num_e) {
  223. // $list_a = array_slice($a,0,$pageNum-$count_bcd-$num_e);
  224. // $list_bcd = $bcd;
  225. // $list_e = array_slice($e,0,$num_e);
  226. // $list = \app\common\model\Eyemargin::arrayMerge($list_a,$list_bcd,$list_e);
  227. // }
  228. //
  229. //
  230. $list = array_slice($a,0, $pageNum);
  231. if($list) {
  232. // 收集眼缘ID
  233. $ids = array_column($list, 'id');
  234. if($redis_ids) {
  235. $redis_ids = array_merge($redis_ids,$ids);
  236. } else {
  237. $redis_ids = $ids;
  238. }
  239. Cache::set($user_id_redis,json_encode($redis_ids));
  240. } else {
  241. Cache::rm($user_id_redis);
  242. }
  243. $this->success("获取成功!",$list);
  244. }
  245. /**
  246. * 判断当前用户是否已经把我加到黑名单
  247. */
  248. public function isBlackUser() {
  249. $user_id = $this->request->request('user_id'); // 用户ID
  250. if(!$user_id) $this->error("参数缺失!");
  251. $where = [];
  252. $where['user_id'] = $user_id;
  253. $where['black_user_id'] = $this->auth->id;
  254. $blackInfo = \app\common\model\UserBlacklist::where($where)->find();
  255. if($blackInfo) {
  256. $this->success("获取成功!",['is_black'=>1]);
  257. } else {
  258. $this->success("获取成功!",['is_black'=>0]);
  259. }
  260. }
  261. /**
  262. * 阿里云媒体处理视频
  263. * @param string $oss_input_object 输入文件(相对路径)
  264. * @param string $oss_output_object 输出文件(相对路径)
  265. * @throws \ClientException
  266. * @throws \ServerException
  267. */
  268. public function mpsvideo($oss_input_object = '', $oss_output_object = '')
  269. {
  270. $access_key_id = config('oss.secretId'); //AccessKey ID
  271. $access_key_secret = config('oss.secretKey'); //AccessKey Secret
  272. $mps_region_id = config('oss.mps_region_id');
  273. $pipeline_id = config('oss.pipeline_id'); //管道id
  274. $watermark_template_id = config('oss.watermark_template_id'); //水印模板id
  275. $template_id = config('oss.template_id');//'S00000001-200030'; //转码模板id
  276. $oss_location = config('oss.region');
  277. $oss_bucket = config('oss.bucket'); //bucket
  278. // $oss_input_object = 'uploads/xuanzhuan.mp4'; //输入文件
  279. // $oss_output_object = 'output/xuanzhuan.mp4'; //输出文件
  280. $image_watermark_object = 'logo.png'; //水印logo地址
  281. // $video_watermark_object = 'logo.mov';
  282. # DefaultAcsClient
  283. $clientProfile = \DefaultProfile::getProfile(
  284. $mps_region_id, # Region ID
  285. $access_key_id, # AccessKey ID
  286. $access_key_secret # AccessKey Secret
  287. );
  288. $client = new \DefaultAcsClient($clientProfile);
  289. # request
  290. $request = new Mts\SubmitJobsRequest();
  291. $request->setAcceptFormat('JSON');
  292. # Input
  293. $input = array('Location' => $oss_location,
  294. 'Bucket' => $oss_bucket,
  295. 'Object' => urlencode($oss_input_object));
  296. $request->setInput(json_encode($input));
  297. # Output
  298. $output = array('OutputObject' => urlencode($oss_output_object));
  299. # Ouput->TemplateId
  300. $output['TemplateId'] = $template_id;
  301. ## Image Watermark
  302. $image_watermark_input = array(
  303. 'Location' => $oss_location,
  304. 'Bucket' => $oss_bucket,
  305. 'Object' => urlencode($image_watermark_object)
  306. );
  307. $image_watermark = array(
  308. 'WaterMarkTemplateId' => $watermark_template_id,
  309. 'Type' => 'Image',
  310. 'InputFile' => $image_watermark_input,
  311. // 'ReferPos' => 'TopRight',
  312. // 'Width' => 0.05,
  313. 'Dx' => 100,
  314. 'Dy'=> 50
  315. );
  316. ## Text Watermark
  317. /* $text_config = array(
  318. 'Content' => '5rWL6K+V5paH5a2X5rC05Y2w',
  319. 'FontName' => 'SimSun',
  320. 'FontSize' => 16,
  321. 'FontColor' => 'Red',
  322. 'FontAlpha' => 0.5,
  323. 'Top' => 10,
  324. 'Left' => 10
  325. );
  326. $text_watermark = array(
  327. 'WaterMarkTemplateId' => $watermark_template_id,
  328. 'Type' => 'Text',
  329. 'TextWaterMark' => $text_config
  330. );*/
  331. ## Video Watermark
  332. /*$video_watermark_input = array (
  333. 'Location' => $oss_location,
  334. 'Bucket' => $oss_bucket,
  335. 'Object' => urlencode($video_watermark_object)
  336. );
  337. $video_watermark = array(
  338. 'WaterMarkTemplateId' => $watermark_template_id,
  339. 'Type' => 'Image',
  340. 'InputFile'=> $video_watermark_input,
  341. 'ReferPos' => 'BottomLeft',
  342. 'Height' => 240,
  343. 'Dx' => 0,
  344. 'Dy' => 0
  345. );*/
  346. # Output->Watermarks
  347. // $watermarks = array($image_watermark, $text_watermark, $video_watermark);
  348. $watermarks = array($image_watermark);
  349. $output['WaterMarks'] = $watermarks;
  350. # Outputs
  351. $outputs = array($output);
  352. $request->setOUtputs(json_encode($outputs));
  353. $request->setOutputBucket($oss_bucket);
  354. $request->setOutputLocation($oss_location);
  355. # PipelineId
  356. $request->setPipelineId($pipeline_id);
  357. # call api
  358. try {
  359. $response = $client->getAcsResponse($request);
  360. // print 'RequestId is:' . $response->{'RequestId'} . "\n";;
  361. if ($response->{'JobResultList'}->{'JobResult'}[0]->{'Success'}) {
  362. return $response->{'JobResultList'}->{'JobResult'}[0]->{'Job'}->{'JobId'};
  363. // print 'JobId is:' .
  364. // $response->{'JobResultList'}->{'JobResult'}[0]->{'Job'}->{'JobId'} . "\n";
  365. } else {
  366. return false;
  367. // print 'SubmitJobs Failed code:' .
  368. // $response->{'JobResultList'}->{'JobResult'}[0]->{'Code'} .
  369. // ' message:' .
  370. // $response->{'JobResultList'}->{'JobResult'}[0]->{'Message'} . "\n";
  371. }
  372. } catch(ServerException $e) {
  373. return false;
  374. // print 'Error: ' . $e->getErrorCode() . ' Message: ' . $e->getMessage() . "\n";
  375. } catch(ClientException $e) {
  376. return false;
  377. // print 'Error: ' . $e->getErrorCode() . ' Message: ' . $e->getMessage() . "\n";
  378. }
  379. }
  380. //阿里云查询视频转码结果
  381. public function getencoderesult()
  382. {
  383. set_time_limit(0);
  384. $where = array(
  385. 'eye_type' => 1,
  386. 'jobid' => ['neq', ''],
  387. 'encode_status' => 0,
  388. );
  389. $eyemargin = Db::name('eyemargin');
  390. $list = $eyemargin->where($where)->limit(100)->select();
  391. if (!$list) {
  392. echo 'mei shu ju';
  393. die;
  394. }
  395. //构建转码查询数据
  396. $data['Format'] = 'JSON';
  397. $data['Version'] = '2014-06-18';
  398. $data['AccessKeyId'] = config('oss.secretId');
  399. $data['SignatureMethod'] = 'HMAC-SHA1';
  400. $data['SignatureVersion'] = '1.0';
  401. $data['Action'] = 'QueryJobList';
  402. foreach ($list as &$v) {
  403. $data['Timestamp'] = str_replace('+00:00', 'Z', gmdate('c', time()));
  404. $data['SignatureNonce'] = md5(uniqid(mt_rand(), true));
  405. $data['JobIds'] = $v['jobid'];
  406. $data['Signature'] = $this->computeSignature($data, config('oss.secretKey'));
  407. $url = 'http://mts.cn-hangzhou.aliyuncs.com/?';
  408. foreach ($data as $apiParamKey => $apiParamValue) {
  409. $url .= "$apiParamKey=" . urlencode($apiParamValue) . '&';
  410. }
  411. $url = substr($url, 0, -1);
  412. $result = file_get_contents($url);
  413. $result = json_decode($result, true);
  414. $_data = [];
  415. if ($result['JobList']['Job'][0]['Percent'] == 100 && $result['JobList']['Job'][0]['State'] == 'TranscodeSuccess') {
  416. $_data['video'] = str_replace('uploads', 'output', $v['video']);
  417. $_data['encode_status'] = 1;
  418. $eyemargin->where(['id' => $v['id'], 'encode_status' => 0])->setField($_data);
  419. } elseif ($result['JobList']['Job'][0]['State'] == 'TranscodeFail') {
  420. $_data['encode_status'] = 2;
  421. $eyemargin->where(['id' => $v['id'], 'encode_status' => 0])->setField($_data);
  422. }
  423. }
  424. echo 'wan bi';
  425. die;
  426. }
  427. /**
  428. * @param $parameters
  429. * @param $accessKeySecret
  430. * @param $iSigner
  431. *
  432. * @return mixed
  433. */
  434. protected function computeSignature($parameters, $accessKeySecret)
  435. {
  436. ksort($parameters);
  437. $canonicalizedQueryString = '';
  438. foreach ($parameters as $key => $value) {
  439. $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
  440. }
  441. $stringToBeSigned = 'GET&%2F&' . $this->percentEncode(substr($canonicalizedQueryString, 1));
  442. return $this->signString($stringToBeSigned, $accessKeySecret . '&');
  443. }
  444. /**
  445. * @param $str
  446. *
  447. * @return string|string[]|null
  448. */
  449. protected function percentEncode($str)
  450. {
  451. $res = urlencode($str);
  452. $res = str_replace(array('+', '*'), array('%20', '%2A'), $res);
  453. $res = preg_replace('/%7E/', '~', $res);
  454. return $res;
  455. }
  456. public function signString($source, $accessSecret)
  457. {
  458. return base64_encode(hash_hmac('sha1', $source, $accessSecret, true));
  459. }
  460. }