| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066 |
- <?php
- /**
- * 视频api.
- *
- * @author ningque
- * @date 2020-02-18 11:12:58
- */
- declare(strict_types=1);
- namespace Modules\Api\Controllers;
- use App\Jobs\RecordSearchJob;
- use App\Constants\AdConstrant;
- use App\Constants\CommonConstant;
- use App\Constants\VideoConstant;
- use App\Jobs\VideoViewedJob;
- use App\Model\Mongo\UserRelationModel;
- use App\Model\TypeModel;
- use App\Model\UserBuyVideoModel;
- use App\Model\VideoModel;
- use App\Repositories\ConfigRepoistory;
- use App\Repositories\RelationRepository;
- use App\Repositories\UserRepository;
- use App\Repositories\Utils\M3u8CacheRepository;
- use App\Repositories\VideoRepository;
- use Carbon\Carbon;
- use Hyperf\Validation\Contract\ValidatorFactoryInterface;
- use Modules\Api\Services\VideoService;
- use Psr\SimpleCache\CacheInterface;
- class VideoController extends BaseController
- {
- /**
- * 视频列表
- *
- * @param VideoService $videoService
- * @param ValidatorFactoryInterface $validatorFactory
- * @return void
- */
- public function list(VideoService $videoService, ValidatorFactoryInterface $validatorFactory)
- {
- $inputData = $this->getJsonData();
- $rules = [
- 'category_id' => 'required|int',
- 'page' => 'nullable|int',
- 'page_size' => 'nullable|int',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $page = $inputData['page'] ?? 1;
- $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE;
- if ($pageSize > 100) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $page = format_page($page);
- $pageSize = intval($pageSize);
- if ($pageSize <= 0) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $videoService = make(VideoService::class);
- $arrAds = $videoService->getAdList(AdConstrant::VIDEO_LIST);
- $adStep = 1;
- $configRepo = make(ConfigRepoistory::class);
- $stepDelimiter = intval($configRepo->get('ad_delimiter_num', 'sys', 10)); // 间隔视频几个出现视频.
- $videoRepo = make(VideoRepository::class);
- $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'comment', 'watch', 'resolution', 'duration'];
- $arrData = $result = VideoModel::query()
- ->with(['type:type.id as type_id,type.title'])
- ->where(['status' => 1, 'category_id' => $inputData['category_id']])
- ->orderByDesc('online_at')
- ->orderByDesc('created_at')
- ->paginate($pageSize, $columns, 'page', $page)->toArray();
- $arrData['data'] = [];
- if (!empty($result['data'])) {
- foreach ($result['data'] as $k => $v) {
- $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
- $arrData['data'][] = [
- 'type' => 'v',
- 'video' => $v,
- ];
- if ($k != 0 && $adStep % $stepDelimiter == 0 && !empty($arrAds)) {
- $tmpArrPlay = $videoRepo->getRandAdFromAds($arrAds);
- $tmpArrPlay['cover'] = !empty($tmpArrPlay['cover']) ? M3u8CacheRepository::getImageUrl($tmpArrPlay['cover']) : '';
- unset($tmpArrPlay['id']);
- $arrData['data'][] = [
- 'type' => 'a',
- 'video' => $tmpArrPlay,
- ];
- }
- $adStep++;
- }
- }
- return json_success($arrData);
- }
- /**
- * 首页数据
- * @return mixed
- */
- public function home()
- {
- $videoRepo = make(VideoRepository::class);
- $relationRepo = make(RelationRepository::class);
- $userCode = $this->getUserId();
- $userInfo = make(UserRepository::class)->getUserInfoFromCache($userCode);
- $userType = null;
- if (isset($userInfo['is_vip']) && $userInfo['is_vip'] == 'n') {
- $userType = 'no_vip';
- }
- $maxPondNum = $videoRepo->getMaxPondNum($userType);
- if ($maxPondNum <= 0) {
- // 容错,如果系统里没有任何首页非会员视频
- $userType = null;
- $maxPondNum = $videoRepo->getMaxPondNum($userType);
- }
- $maxNum = $maxPondNum - 1;
- if ($maxNum < 0) {
- $maxNum = 0;
- }
- // $videoRepo->clearHomeVideoGroup($groupStep); // 本地开发测试,永远清理桶缓存.
- $groupStep = strval(rand(0, $maxNum));
- // $cacheKey = VideoConstant::HOME_GROUP_CACHE_KEY_PREFIX . $groupStep;
- // if ($userType == 'no_vip') {
- // $cacheKey = VideoConstant::HOME_NOVIP_GROUP_CACHE_KEY_PREFIX . $groupStep;
- // }
- // $cacheRepo = make(CacheInterface::class);
- // $arrVideos = $cacheRepo->get($cacheKey, []);
- $arrVideos = $videoRepo->makeOneGroup($groupStep, $userType);
- if (!empty($arrVideos)) {
- foreach ($arrVideos as $k => &$v) {
- if ($v['type'] == 'v') {
- $v['video']['mu'] = '';
- // $v['video']['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['video']['mu'], $userCode, $v['video']['id'], 'video');
- $v['video']['cover'] = M3u8CacheRepository::getImageUrl($v['video']['cover']);
- if (!empty($v['video']['user'])) {
- $v['video']['user']['avatar'] = !empty($v['video']['user']['avatar']) ? M3u8CacheRepository::getImageUrl($v['video']['user']['avatar']) : '';
- }
- // 优化,前端每个视频单独请求详情.
- // if (!empty($v['video']['user'])) {
- // $v['video']['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($this->getUserId(), $v['video']['user']['code']);
- // }
- // $v['video']['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['video']['id']);
- } elseif ($v['type'] == 'a') {
- if (!empty($v['video']['cover'])) {
- $v['video']['cover'] = M3u8CacheRepository::getImageUrl($v['video']['cover']);
- }
- if (!empty($v['video']['link'])) {
- $v['video']['link'] = M3u8CacheRepository::getLinkUrl($v['video']['link'], ['user_code' => $userCode]);
- }
- if (!empty($v['video']['play'])) {
- $v['video']['play'] = M3u8CacheRepository::getVideoInnerUrl($v['video']['play'], $userCode, $v['video']['id'], 'ad');
- }
- unset($v['video']['id']);
- }
- }
- }
- return json_success($arrVideos);
- }
- /**
- * 视频详情
- * @return mixed
- */
- public function info(
- VideoService $videoService,
- ValidatorFactoryInterface $validatorFactory
- ) {
- $inputData = $this->getJsonData();
- $rules = [
- 'video_id' => 'required|int'
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $userCode = $this->getUserId();
- $result = $videoService->info($inputData['video_id'], $userCode);
- return json_success($result);
- }
- /**
- * 首页关注视频
- * @return mixed
- */
- public function recommend(ValidatorFactoryInterface $validatorFactory)
- {
- $inputData = $this->getJsonData();
- $rules = [
- 'page' => 'nullable|int',
- 'page_size' => 'nullable|int',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $page = $inputData['page'] ?? 1;
- $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE;
- if ($pageSize > 100) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $page = format_page($page);
- $pageSize = intval($pageSize);
- if ($pageSize <= 0) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $videoService = make(VideoService::class);
- $arrAds = $videoService->getAdList(AdConstrant::VIDEO_HOME);
- // $arrAds = [];
- $adStep = 1;
- $configRepo = make(ConfigRepoistory::class);
- $stepDelimiter = intval($configRepo->get('ad_delimiter_num', 'sys', 10)); // 间隔视频几个出现视频.
- $videoRepo = make(VideoRepository::class);
- $relationRepo = make(RelationRepository::class);
- $userCode = $this->getUserId();
- $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'mu', 'comment', 'watch', 'resolution', 'duration'];
- //查找100个关注的code
- $relation = make(UserRelationModel::class)->db()
- ->find(
- ['from_user_id' => $this->getUserId()],
- ['limit' => 100]
- );
- $arrData = [];
- $arrUserIds = [];
- $arrRelation = $relation->toArray();
- if ($arrRelation) {
- foreach ($arrRelation as $v) {
- $arrUserIds[] = $v['to_user_id'];
- }
- $arrData = $result = VideoModel::query()
- ->with(['category:type.id as type_id,type.title','user'])
- ->whereIn('uid', $arrUserIds)
- ->where(['status' => 1])
- //->orderByRaw("field(uid," . $id_str . ")")
- ->orderByDesc('online_at')
- ->orderByDesc('created_at')
- ->paginate($pageSize, $columns, 'page', $page)->toArray();
- $arrData['data'] = [];
- if (!empty($result['data'])) {
- foreach ($result['data'] as $k => $v) {
- $v['mu'] = ''; // 列表干掉m3u8地址.
- // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video');
- $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
- if (!empty($v['user'])) {
- $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']);
- // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']);
- }
- // $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']);
- if (!empty($v['category'])) {
- foreach ($v['category'] as $ck => $t) {
- unset($v['category'][$ck]['pivot']);
- }
- }
- $arrData['data'][] = [
- 'type' => 'v',
- 'video' => $v,
- ];
- if ($k != 0 && $adStep % $stepDelimiter == 0 && !empty($arrAds)) {
- $tmpArrPlay = $videoRepo->getRandAdFromAds($arrAds);
- $tmpArrPlay['cover'] = !empty($tmpArrPlay['cover']) ? M3u8CacheRepository::getImageUrl($tmpArrPlay['cover']) : '';
- if (!empty($tmpArrPlay['link'])) {
- $tmpArrPlay['link'] = M3u8CacheRepository::getLinkUrl($tmpArrPlay['link'], ['user_code' => $userCode]);
- }
- if (!empty($tmpArrPlay['play'])) {
- $tmpArrPlay['play'] = M3u8CacheRepository::getVideoInnerUrl($tmpArrPlay['play'], $userCode, $tmpArrPlay['id'], 'ad');
- }
- unset($tmpArrPlay['id']);
- $arrData['data'][] = [
- 'type' => 'a',
- 'video' => $tmpArrPlay,
- ];
- }
- $adStep++;
- }
- }
- }
- return json_success($arrData);
- }
- /**
- * 搜索口味
- * @return mixed
- */
- public function searchTag(ValidatorFactoryInterface $validatorFactory)
- {
- $inputData = $this->getJsonData();
- $rules = [
- 'keywords' => 'required|string|max:64',
- 'page' => 'nullable|int',
- 'page_size' => 'nullable|int',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $userCode = $this->getUserId();
- $defaultPageSize = 10;
- $page = !empty($inputData['page']) ? intval($inputData['page']) : 1;
- $pageSize = !empty($inputData['page_size']) ? intval($inputData['page_size']) : $defaultPageSize;
- if ($pageSize > 100) {
- return json_fail('参数错误');
- }
- $page = format_page($page);
- if ($pageSize <= 0) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $columns = ['id', 'title', 'cover', 'description'];
- $data = TypeModel::query()
- ->withCount('video')
- ->where('title', 'like', '%' . $inputData['keywords'] . '%')
- ->paginate($pageSize, $columns, 'page', $page);
- $data = $data->toArray();
-
- if (!empty($data['data'])) {
- foreach ($data['data'] as &$v) {
- $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
- unset($v['created_at'], $v['updated_at']);
- }
- }
- // 异步记录搜索记录.
- $jobParams = [
- 'event_name' => 'tag',
- 'user_code' => $userCode,
- 'keywords' => data_get($inputData, 'keywords', ''),
- 'module' => 'video',
- ];
- dispatch_job(new RecordSearchJob($jobParams));
- return json_success($data);
- }
- /**
- * 搜索关键词推荐
- * @return mixed
- */
- public function searchTagHot()
- {
- $data = make(CacheInterface::class)->remember(
- 'hot_tags',
- 60 * 60,
- function () {
- $arrData = [];
- $result = TypeModel::query()->where(['is_hot' => 1, 'status' => 1])
- ->withCount('upvideo')
- ->orderByDesc('sort')
- ->take(10)
- ->get(['id', 'title', 'cover']);
- // $result = TypeModel::query()
- // ->select(['id','title', 'cover'])
- // ->where('status', 1)
- // ->withCount('video')
- // ->withCount('upvideo')
- // ->orderByDesc('sort')
- // ->get();
- if ($result->count() > 0) {
- $result = $result->toArray();
- foreach ($result as $k => $v) {
- $arrData[] = [
- 'id' => $v['id'],
- 'title' => $v['title'],
- 'cover' => M3u8CacheRepository::getImageUrl($v['cover']),
- 'video_count' => !empty($v['upvideo_count']) ? intval($v['upvideo_count']) : 0, //特殊处理,取上架的视频数量,不用app发新版,
- ];
- }
- }
- return $arrData;
- }
- );
- return json_success($data);
- }
- /**
- * 搜索视频
- * @return mixed
- */
- public function searchVideo(ValidatorFactoryInterface $validatorFactory)
- {
- $inputData = $this->getJsonData();
- $rules = [
- 'keywords' => 'required|string|max:64',
- 'page' => 'nullable|int',
- 'page_size' => 'nullable|int',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $page = $inputData['page'] ?? 1;
- $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE;
- if ($pageSize > 100) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $page = format_page($page);
- $pageSize = intval($pageSize);
- if ($pageSize <= 0) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $videoService = make(VideoService::class);
- // $arrAds = $videoService->getAdList(AdConstrant::VIDEO_HOME);
- $arrAds = [];
- $adStep = 1;
- $configRepo = make(ConfigRepoistory::class);
- $stepDelimiter = intval($configRepo->get('ad_delimiter_num', 'sys', 10)); // 间隔视频几个出现视频.
- $cacheRepo = make(CacheInterface::class);
- $cacheTimes = 2 * 60 * 60;
- $cacheKey = 'search:video_pages_'. $pageSize .':'. $page. '_' . data_get($inputData, 'keywords', '');
- $videoRepo = make(VideoRepository::class);
- $relationRepo = make(RelationRepository::class);
- $userCode = $this->getUserId();
- $cacheData = $cacheRepo->get($cacheKey, []);
- $arrData = [];
- if (empty($cacheData)) {
- $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'comment', 'mu', 'watch', 'resolution', 'duration'];
- $ret = VideoModel::query()
- ->with(['category:type.id as type_id,type.title','user'])
- ->where('status', 1)
- ->where('title', 'like', '%'. $inputData['keywords'] .'%')
- ->orderByDesc('online_at')
- ->orderByDesc('created_at')
- ->paginate($pageSize, $columns, 'page', $page);
- if ($ret->isNotEmpty()) {
- $result = $ret->toArray();
- if (!empty($result['data'])) {
- $arrData = $result;
- $cacheRepo->set($cacheKey, $arrData, $cacheTimes);
- }
- }
- } else {
- $arrData = $cacheData;
- }
- $arrData['data'] = [];
- if (!empty($cacheData['data'])) {
- foreach ($cacheData['data'] as $k => $v) {
- $v['mu'] = ''; // 列表干掉m3u8地址.
- // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video');
- $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
- if (!empty($v['user'])) {
- $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']);
- // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']);
- }
- // $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']);
- if (!empty($v['category'])) {
- foreach ($v['category'] as $ck => $t) {
- unset($v['category'][$ck]['pivot']);
- }
- }
- $arrData['data'][] = [
- 'type' => 'v',
- 'video' => $v,
- ];
- if ($k != 0 && $adStep % $stepDelimiter == 0 && !empty($arrAds)) {
- $tmpArrPlay = $videoRepo->getRandAdFromAds($arrAds);
- $tmpArrPlay['cover'] = !empty($tmpArrPlay['cover']) ? M3u8CacheRepository::getImageUrl($tmpArrPlay['cover']) : '';
- if (!empty($tmpArrPlay['play'])) {
- $tmpArrPlay['play'] = M3u8CacheRepository::getVideoInnerUrl($tmpArrPlay['play'], $userCode, $tmpArrPlay['id'], 'ad');
- }
- unset($tmpArrPlay['id']);
- $arrData['data'][] = [
- 'type' => 'a',
- 'video' => $tmpArrPlay,
- ];
- }
- $adStep++;
- }
- }
- // 异步记录搜索记录.
- $playerTypeName = 'short';
- $jobParams = [
- 'event_name' => 'video_'. $playerTypeName,
- 'user_code' => $userCode,
- 'keywords' => data_get($inputData, 'keywords', ''),
- 'module' => 'video',
- ];
- dispatch_job(new RecordSearchJob($jobParams));
- return json_success($arrData);
- }
- /**
- * 搜索视频
- * @return mixed
- */
- public function searchHot(ValidatorFactoryInterface $validatorFactory)
- {
- $inputData = $this->getJsonData();
- $rules = [
- 'keywords' => 'required|string',
- 'page' => 'nullable|int',
- 'page_size' => 'nullable|int',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $page = $inputData['page'] ?? 1;
- $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE;
- if ($pageSize > 100) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $page = format_page($page);
- $pageSize = intval($pageSize);
- if ($pageSize <= 0) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $relationRepo = make(RelationRepository::class);
- $cacheRepo = make(CacheInterface::class);
- $cacheTimes = 2 * 60 * 60;
- $cacheKey = 'search:video_pages_'. $pageSize .':'. $page. '_' . data_get($inputData, 'keywords', '');
- $userCode = $this->getUserId();
- $cacheData = $cacheRepo->get($cacheKey, []);
- $result = [];
- if (empty($cacheData)) {
- $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'mu', 'comment', 'watch', 'resolution', 'duration'];
- $ret = VideoModel::query()
- ->select()
- ->with(['category:type.id as type_id,type.title','user'])
- ->where('title', 'like', '%'. $inputData['keywords'] .'%')
- ->where('status', 1)
- ->orderByDesc('online_at')
- ->orderByDesc('created_at')
- ->paginate($pageSize, $columns, 'page', $page);
- if ($ret->isNotEmpty()) {
- $result = $ret->toArray();
- $cacheRepo->set($cacheKey, $result, $cacheTimes);
- }
- }
- if (!empty($result['data'])) {
- foreach ($result['data'] as $k => $v) {
- $v['mu'] = ''; // 列表干掉m3u8地址.
- // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video');
- $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
- if (!empty($result[$k]['user'])) {
- $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']);
- // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']);
- }
- // $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']);
- if (!empty($v['category'])) {
- foreach ($v['category'] as $ck => $t) {
- unset($v['category'][$ck]['pivot']);
- }
- }
- }
- }
- // 异步记录搜索记录.
- $playerTypeName = 'short';
- $jobParams = [
- 'event_name' => 'video_'. $playerTypeName,
- 'user_code' => $userCode,
- 'keywords' => data_get($inputData, 'keywords', ''),
- 'module' => 'video',
- ];
- dispatch_job(new RecordSearchJob($jobParams));
- return json_success($result);
- }
- /**
- * 搜索视频推荐
- * @return mixed
- */
- public function searchVideoHot()
- {
- $userCode = $this->getUserId();
- $relationRepo = make(RelationRepository::class);
- $result = make(CacheInterface::class)->remember(
- 'hot_video',
- 60 * 60,
- function () use ($relationRepo) {
- $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'mu', 'comment', 'watch', 'resolution', 'duration'];
- $arrData = [];
- $result = VideoModel::query()
- ->with(['category:type.id as type_id,type.title','user'])
- ->where('status', 1)
- ->orderByDesc('like')
- ->limit(200)
- ->get($columns)->toArray();
- foreach ($result as $k => $v) {
- // $result[$k]['mu'] = M3u8CacheRepository::getVideoUrl($result[$k]['mu']);
- // $v['is_my_like'] = false;
- if (!empty($v['category'])) {
- foreach ($v['category'] as $ck => $t) {
- unset($v['category'][$ck]['pivot']);
- }
- }
- $arrData[$k] = [
- 'type' => 'v',
- 'video' => $v,
- ];
- }
- unset($result);
- return $arrData;
- }
- );
- if (!empty($result)) {
- foreach ($result as &$v) {
- if ($v['type'] == 'v') {
- $v['video']['mu'] = ''; // 列表干掉m3u8地址.
- $v['video']['cover'] = M3u8CacheRepository::getImageUrl($v['video']['cover']);
- if (!empty($v['video']['user'])) {
- $v['video']['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['video']['user']['avatar']);
- // $v['user']['is_focus'] = false;
- }
- // $v['video']['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['video']['mu'], $userCode, $v['video']['id'], 'video');
- // if (!empty($v['video']['user'])) {
- // $v['video']['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['video']['user']['code']);
- // }
- // $v['video']['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['video']['id']);
- }
- }
- }
- return json_success($result);
- }
- /**
- * 搜索视频通过标签
- * @return mixed
- */
- public function getVideoByType(ValidatorFactoryInterface $validatorFactory)
- {
- $inputData = $this->getJsonData();
- $rules = [
- 'type_id' => 'required|int',
- 'page' => 'nullable|int',
- 'page_size' => 'nullable|int',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $page = $inputData['page'] ?? 1;
- $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE;
- if ($pageSize > 100) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $page = format_page($page);
- $pageSize = intval($pageSize);
- if ($pageSize <= 0) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- // $videoService = make(VideoService::class);
- // $arrAds = $videoService->getAdList(AdConstrant::VIDEO_HOME);
- $arrAds = [];
- $adStep = 0;
- $configRepo = make(ConfigRepoistory::class);
- $stepDelimiter = intval($configRepo->get('ad_delimiter_num', 'sys', 10)); // 间隔视频几个出现视频.
- $videoRepo = make(VideoRepository::class);
- $relationRepo = make(RelationRepository::class);
- $userCode = $this->getUserId();
- $cacheRepo = make(CacheInterface::class);
- $cacheTimes = 2 * 60 * 60;
- $cacheKey = 'search:video_by_tag_pages_'. $pageSize .':'. $page. '_' . data_get($inputData, 'keywords', '');
- $cacheData = $cacheRepo->get($cacheKey, []);
- $arrData = $result = [];
- if (empty($cacheData)) {
- $columns = ['video.id','video.title', 'video.cover', 'video.mu', 'video.like', 'video.uid', 'video.comment', 'video.watch','video.resolution', 'video.duration'];
- $ret = VideoModel::query()
- ->leftJoin('type_video as tv', 'video.id', '=', 'tv.video_id')
- ->with(['category:type.id as type_id,type.title','user'])
- ->where('tv.type_id', $inputData['type_id'])
- ->where('video.status', 1)
- ->orderByDesc('video.online_at')
- ->paginate($pageSize, $columns, 'page', $page);
- if ($ret->isNotEmpty()) {
- $arrData = $result = $ret->toArray();
- $cacheRepo->set($cacheKey, $result, $cacheTimes);
- }
- } else {
- $arrData = $cacheData;
- }
- $arrData['data'] = [];
- if (!empty($result['data'])) {
- foreach ($result['data'] as $k => $v) {
- $v['mu'] = '';
- // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video');
- $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
- if (!empty($v['user'])) {
- $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']);
- // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']);
- }
- // $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']);
- if (!empty($v['category'])) {
- foreach ($v['category'] as $ck => $t) {
- unset($v['category'][$ck]['pivot']);
- }
- }
- $arrData['data'][] = [
- 'type' => 'v',
- 'video' => $v,
- ];
- if ($k != 0 && $adStep % $stepDelimiter == 0 && !empty($arrAds)) {
- $tmpArrPlay = $videoRepo->getRandAdFromAds($arrAds);
- $tmpArrPlay['cover'] = !empty($tmpArrPlay['cover']) ? M3u8CacheRepository::getImageUrl($tmpArrPlay['cover']) : '';
- if (!empty($tmpArrPlay['link'])) {
- $tmpArrPlay['link'] = M3u8CacheRepository::getLinkUrl($tmpArrPlay['link'], ['user_code' => $userCode]);
- }
- if (!empty($tmpArrPlay['play'])) {
- $tmpArrPlay['play'] = M3u8CacheRepository::getVideoInnerUrl($tmpArrPlay['play'], $userCode, $tmpArrPlay['id'], 'ad');
- }
- unset($tmpArrPlay['id']);
- $arrData['data'][] = [
- 'type' => 'a',
- 'video' => $tmpArrPlay,
- ];
- }
- $adStep++;
- }
- }
- return json_success($arrData);
- }
- /**
- * 搜索视频通过用户code
- * @return mixed
- */
- public function userVideoList(ValidatorFactoryInterface $validatorFactory)
- {
- $inputData = $this->getJsonData();
- $rules = [
- 'code' => 'required|string',
- 'page' => 'nullable|int',
- 'page_size' => 'nullable|int',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $page = $inputData['page'] ?? 1;
- $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE;
- $pageSize = intval($pageSize);
- if ($pageSize > 100) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $page = format_page($page);
- if ($pageSize <= 0) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $userCode = $this->getUserId();
- $relationRepo = make(RelationRepository::class);
- $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'comment', 'mu', 'watch', 'resolution', 'duration'];
- $result = VideoModel::query()
- ->with(['category:type.id as type_id,type.title','user'])
- ->where('uid', $inputData['code'])
- ->where('status', 1)
- ->orderByDesc('online_at')
- ->orderByDesc('created_at')
- ->paginate(
- $pageSize,
- $columns,
- 'page',
- $page
- )->toArray();
- if (!empty($result['data'])) {
- foreach ($result['data'] as $k => &$v) {
- $v['mu'] = ''; // 列表干掉m3u8地址.
- // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video');
- $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
- if (!empty($v['user'])) {
- $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']);
- // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']);
- }
- // $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']);
- if (!empty($v['category'])) {
- foreach ($v['category'] as $ck => $t) {
- unset($v['category'][$ck]['pivot']);
- }
- }
- }
- }
- return json_success($result);
- }
- /**
- * 推送已观看的视频.
- * @param ValidatorFactoryInterface $validatorFactory
- * @return mixed
- */
- public function pushViewed(ValidatorFactoryInterface $validatorFactory)
- {
- $inputData = $this->getJsonData();
- $rules = [
- 'ids' => 'required',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $userCode = $this->getUserId();
- $date = Carbon::now()->toDateString();
- $arrIds = [];
- $ids = $inputData['ids'];
- if (is_string($ids)) {
- $arrIds = explode(',', $ids);
- $arrIds = array_unique($arrIds);
- $arrIds = array_filter($arrIds);
- } else {
- $arrIds = $ids;
- }
- $count = count($arrIds);
- if ($count > 100) {
- return json_fail('too many id');
- }
- $userInfo = make(UserRepository::class)->getUserInfoData($userCode);
- // 今日剩余观影次数
- $videoSurplus = isset($userInfo['video_surplus']) ? $userInfo['video_surplus'] : 0;
- $oldSurplus = $videoSurplus;
- if ($userInfo['is_vip'] == 'y') {
- $videoSurplus = 999999;
- } else {
- // 这里只是初略计算,真实计算考异步job完成后才能计算出来.
- $videoSurplus = $videoSurplus - $count;
- $oldSurplus = $videoSurplus;
- }
- $isNegativeSurplus = false; // 是否是负数.
- if ($videoSurplus < 0) {
- // 容错.
- $videoSurplus = 0;
- $isNegativeSurplus = true;
- }
- $jobParams = [];
- if (!empty($arrIds)) {
- $absSurplus = abs($oldSurplus);
- foreach ($arrIds as $k => $vid) {
- if ($isNegativeSurplus && $k == $absSurplus) {
- break;
- }
- $jobParams[] = [
- 'date' => $date,
- 'user_id' => $userInfo['id'],
- 'user_code' => $userInfo['code'],
- 'video_id' => $vid,
- ];
- }
- // 异步处理.
- if (!empty($jobParams)) {
- dispatch_job(new VideoViewedJob($jobParams));
- }
- }
- $resultData = [
- 'video_surplus' => $videoSurplus,
- ];
- return json_success($resultData);
- }
- // 购买视频
- public function buy()
- {
- $validatorFactory = make(ValidatorFactoryInterface::class);
- $videoService = make(VideoService::class);
- $inputData = $this->getJsonData();
- $rules = [
- 'video_id' => 'required|int'
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $userCode = $this->getUserId();
- $videoId = intval(data_get($inputData, 'video_id', 0));
- $videoObj = $videoService->buyVideo($userCode, $videoId);
- $playMu = M3u8CacheRepository::getVideoInnerUrl($videoObj->mu, $userCode, $videoObj->id, 'video');
- $result = [
- 'video_id' => $videoId,
- 'mu' => $playMu,
- ];
- return json_success($result);
- }
- // 我已购买的视频
- public function myBoughtPages()
- {
- $validatorFactory = make(ValidatorFactoryInterface::class);
- $inputData = $this->getJsonData();
- $rules = [
- 'page' => 'nullable|int',
- 'page_size' => 'nullable|int',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $page = $inputData['page'] ?? 1;
- $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE;
- if ($pageSize > 100) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $page = format_page($page);
- $pageSize = intval($pageSize);
- if ($pageSize <= 0) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $userCode = $this->getUserId();
- $user = make(UserRepository::class)->getUserInfoData($userCode);
- $videoColumns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'mu', 'comment', 'watch', 'resolution', 'duration', 'status', 'check'];
- $strVideoColumns = implode(',', $videoColumns);
- $lists = UserBuyVideoModel::query()->with(['video:'. $strVideoColumns, 'video.user'])
- ->where(['user_id' => $user['id']])
- ->whereHas('video', function ($q) {
- $q->where(['status' => 1])->with(['user']);
- })
- ->orderBy('id', 'DESC')
- ->paginate($pageSize, ['*'], 'page', $page);
- $lists = $lists->toArray();
- if (!empty($lists['data'])) {
- foreach ($lists['data'] as $k => $item) {
- $v = $item['video'];
- $v['user'] = $item['video']['user'] ?? null;
- $v['mu'] = ''; // 列表干掉m3u8地址.
- // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video');
- $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
- if (!empty($v['user'])) {
- $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']);
- // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']);
- unset($v['user']['id']);
- }
- // $item['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $videoObj->id);
- if (!empty($v['category'])) {
- foreach ($v['category'] as $ck => $t) {
- unset($v['category'][$ck]['pivot']);
- }
- } else {
- $v['category'] = null;
- }
- unset($v['status'], $v['check']);
- $v['buy_at'] = $item['created_at']; // 购买时间.
- $lists['data'][$k] = $v;
- }
- }
- return json_success($lists);
- }
- /**
- * 最新视频分页.
- * @return mixed
- * @throws \Psr\SimpleCache\InvalidArgumentException
- */
- public function lastestPages()
- {
- $userCode = $this->getUserId();
- $validatorFactory = make(ValidatorFactoryInterface::class);
- $inputData = $this->getJsonData();
- $rules = [
- 'page' => 'nullable|int',
- 'page_size' => 'nullable|int',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $page = $inputData['page'] ?? 1;
- $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE;
- if ($pageSize > 100) {
- $pageSize = CommonConstant::PAGE_SIZE;
- }
- $page = format_page($page);
- $pageSize = intval($pageSize);
- $videoRepo = make(VideoRepository::class);
- // 不让前端随意传,写死10
- $pageSize = VideoConstant::LASTEST_PAGE_SIZE;
- $arrData = [];
- $lists = $videoRepo->lastestPages($page, $pageSize);
- if (!empty($lists['data'])) {
- $relationRepo = make(RelationRepository::class);
- $videoService = make(VideoService::class);
- $arrAds = $videoService->getAdList(AdConstrant::VIDEO_HOME);
- $adStep = 1;
- $configRepo = make(ConfigRepoistory::class);
- $stepDelimiter = intval($configRepo->get('ad_delimiter_num', 'sys', 10)); // 间隔视频几个出现视频.
- foreach ($lists['data'] as $k => $v) {
- $v['mu'] = ''; // 列表干掉m3u8地址.
- // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video');
- $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
- if (!empty($v['user'])) {
- $v['user']['avatar'] = !empty($v['user']['avatar']) ? M3u8CacheRepository::getImageUrl($v['user']['avatar']) : '';
- }
- if (!empty($v['user'])) {
- $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']);
- }
- $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']);
- unset($v['status'], $v['check']);
- $arrData[] = [
- 'type' => 'v',
- 'video' => $v,
- ];
- if ($k != 0 && $adStep % $stepDelimiter == 0 && !empty($arrAds)) {
- $tmpArrPlay = $videoRepo->getRandAdFromAds($arrAds);
- $tmpArrPlay['cover'] = !empty($tmpArrPlay['cover']) ? M3u8CacheRepository::getImageUrl($tmpArrPlay['cover']) : '';
- if (!empty($tmpArrPlay['link'])) {
- $tmpArrPlay['link'] = M3u8CacheRepository::getLinkUrl($tmpArrPlay['link'], ['user_code' => $userCode]);
- }
- if (!empty($tmpArrPlay['play'])) {
- $tmpArrPlay['play'] = M3u8CacheRepository::getVideoInnerUrl($tmpArrPlay['play'], $userCode, $tmpArrPlay['id'], 'ad');
- }
- unset($tmpArrPlay['id']);
- $arrData[] = [
- 'type' => 'a',
- 'video' => $tmpArrPlay,
- ];
- }
- $adStep++;
- }
- $lists['data'] = $arrData;
- }
- return json_success($lists);
- }
- }
|