storageClient = new StorageClient([ 'keyFile' => json_decode(file_get_contents(module_path('StudioPlus', 'google-cloud-platform.json')), true) ]); $this->bucketName = Config::get('studioplus.bucket_name'); $this->googleApiEndpoint = Config::get('studioplus.google_api_endpoint'); } public function storeNewVideo(StudioPlusChannel $studioPlusChannel, string $title, string $fileName, array $params = []) { $params['title'] = $title; $params['filename'] = $fileName; if (!isset($params['amazon_total_reviews'])) { $params['amazon_total_reviews'] = 0; } if((boolean)$params['video_type']['need_asin']){ $video = StudioPlusVideo::where('asin', $params['asin'])->first(); if ($video) { if(!(boolean)$params['video_type']['need_job_request']){ $params['status'] = StudioPlusVideo::STATUS_EDITED; } if (isset($params['description'])) { $params['description'] = "*DUPLICATE ASIN* " . $params['description']; } else { $params['description'] = "*DUPLICATE ASIN* "; } } } if(permissionCheck('job_board.creator.index') && auth()->user()->role->type == 'staff') { $badges = auth()->user()->staff->badges != null ? (array) json_decode(auth()->user()->staff->badges) : []; //for 1st 10 badge only if(in_array(1, $badges) && $params['studio_plus_video_type_id'] == 1){ $params['status'] = StudioPlusVideo::STATUS_EDITED; } } return $studioPlusChannel->videos()->create($params); } public function uploadFileToGCP(string $pathToFile, string $objectName, string $fileName = null) { $bucket = $this->storageClient->bucket($this->bucketName); if (!$file = fopen($pathToFile, 'r')) { \Log::info('Unable to open file for uploading'); } else { try { $bucket->upload( $file, [ 'name' => $objectName, 'metadata' => [ 'contentDisposition' => $fileName != null ? 'attachment; filename="'.preg_replace('/[^a-zA-Z0-9_.]/', '_', $fileName).'.mp4"' : 'attachment', ], ] ); \Log::info('Video Uploaded Successfully to GCP with filename: '.$fileName); } catch (\GoogleException $ex ) { \Log::error('Upload failed, trying to upload again ....'); $resumeUri = $bucket->getResumeUri(); \Log::error('Resume Url:'. $resumeUri); $object = $bucket->resume($resumeUri); } } } public function getGoogleStoragePath(StudioPlusVideo $studioPlusVideo): string { return "uploads/users/" . $studioPlusVideo->channel->user_id . "/videos/{$studioPlusVideo->id}"; } private function getLocalStoragePath(StudioPlusVideo $studioPlusVideo): string { return "StudioPlus/" . $studioPlusVideo->channel->user_id . "/videos/" . $studioPlusVideo->id; } public function handleUploadVideox(Request $request, StudioPlusChannel $studioPlusChannel): StudioPlusVideo { $fileName = $request->file('video')->getClientOriginalName(); $fileName = str_replace(' ', '', $fileName); $explodedFileName = explode('.', $fileName); $title = collect(Arr::except($explodedFileName, array_key_last($explodedFileName)))->join(' '); $upload = $this->storeNewVideo( $studioPlusChannel, $title, $fileName ); $gcpStoragePath = $this->getGoogleStoragePath($upload); $objectName = "$gcpStoragePath/$fileName"; $this->uploadFileToGCP($request->file('video')->path(), $objectName); $upload->original_video_url = $objectName; $upload->video_url = $objectName; $localStoragePath = $this->getLocalStoragePath($upload); $videoLocalUrl = Storage::putFileAs($localStoragePath, $request->file('video'), $fileName); VideoService::copyAndRescale(storage_path("app/$localStoragePath/$fileName"), storage_path("app/$localStoragePath/video.mp4")); $ffmpeg = FFMpeg::create(); $video = $ffmpeg->open(storage_path("app/{$videoLocalUrl}")); $ffprobe = FFProbe::create(get_ffprobe_config()); $codeAc = $ffprobe->format(storage_path("app/{$videoLocalUrl}"))->get('duration'); $upload->video_duration = round($codeAc, PHP_ROUND_HALF_UP); $upload->save(); $timeFrameInSeconds = 2; for ($i = 0; $i < 3; $i++) { if ($timeFrameInSeconds < round($codeAc, PHP_ROUND_HALF_DOWN)) { $thumbnailFilename = Str::random(10) . ".jpg"; $thumbnailFilePath = "$gcpStoragePath/thumbnails/$thumbnailFilename"; $video->frame(\FFMpeg\Coordinate\TimeCode::fromSeconds($timeFrameInSeconds)) ->save(storage_path("app/$localStoragePath/$thumbnailFilename")); $this->uploadFileToGCP(storage_path("app/$localStoragePath/$thumbnailFilename"), $thumbnailFilePath); Storage::delete("$localStoragePath/$thumbnailFilename"); $upload->thumbnails()->create([ 'thumbnail_url' => "$thumbnailFilePath", 'filename' => $thumbnailFilename, 'is_active' => $i === 0 ]); $timeFrameInSeconds += 2; } } Storage::delete($videoLocalUrl); return $upload->load('thumbnails'); } public function handleUploadVideo(Request $request, StudioPlusChannel $studioPlusChannel): StudioPlusVideo { $fileName = $request->file('video')->getClientOriginalName(); $fileName = str_replace(' ', '', $fileName); $explodedFileName = explode('.', $fileName); $title = collect(Arr::except($explodedFileName, array_key_last($explodedFileName)))->join(' '); $upload = $this->storeNewVideo( $studioPlusChannel, $title, $fileName ); $gcpStoragePath = $this->getGoogleStoragePath($upload); $objectName = "$gcpStoragePath/$fileName"; $this->uploadFileToGCP($request->file('video')->path(), $objectName); $upload->original_video_url = $objectName; $upload->video_url = $objectName; $localStoragePath = $this->getLocalStoragePath($upload); $videoLocalUrl = Storage::putFileAs($localStoragePath, $request->file('video'), $fileName); VideoService::copyAndRescale(storage_path("app/$localStoragePath/$fileName"), storage_path("app/$localStoragePath/video.mp4")); $ffmpeg = FFMpeg::create(); $video = $ffmpeg->open(storage_path("app/{$videoLocalUrl}")); $ffprobe = FFProbe::create(get_ffprobe_config()); $codeAc = $ffprobe->format(storage_path("app/{$videoLocalUrl}"))->get('duration'); $upload->video_duration = round($codeAc, PHP_ROUND_HALF_UP); $upload->save(); $timeFrameInSeconds = 2; for ($i = 0; $i < 3; $i++) { if ($timeFrameInSeconds < round($codeAc, PHP_ROUND_HALF_DOWN)) { $thumbnailFilename = Str::random(10) . ".jpg"; $thumbnailFilePath = "$gcpStoragePath/thumbnails/$thumbnailFilename"; $video->frame(\FFMpeg\Coordinate\TimeCode::fromSeconds($timeFrameInSeconds)) ->save(storage_path("app/$localStoragePath/$thumbnailFilename")); $this->uploadFileToGCP(storage_path("app/$localStoragePath/$thumbnailFilename"), $thumbnailFilePath); Storage::delete("$localStoragePath/$thumbnailFilename"); $upload->thumbnails()->create([ 'thumbnail_url' => "$thumbnailFilePath", 'filename' => $thumbnailFilename, 'is_active' => $i === 0 ]); $timeFrameInSeconds += 2; } } Storage::delete($videoLocalUrl); return $upload->load('thumbnails'); } public function handleUploadThumbnail(Request $request, StudioPlusChannel $studioPlusChannel, StudioPlusVideo $studioPlusVideo) { $fileName = $request->file('thumbnail')->getClientOriginalName(); $fullPath = "/uploads/users/" . auth()->id() . "/videos/{$studioPlusVideo->id}/thumbnails/$fileName"; $this->uploadFileToGCP($request->file('thumbnail'), $fullPath); if($request->has('type') && $request->type == 'short'){ $uploadedThumbnail = $studioPlusVideo->thumbnails()->where('is_uploaded', 1)->where('is_short', 1)->first(); } else { $uploadedThumbnail = $studioPlusVideo->thumbnails()->where('is_uploaded', 1)->first(); } if ($uploadedThumbnail) { $uploadedThumbnail->update([ 'filename' => $fileName, 'thumbnail_url' => "$fullPath", 'is_short' => $request->has('type') ? true : false, 'is_uploaded' => true ]); } else { $studioPlusVideo->thumbnails()->create([ 'filename' => $fileName, 'thumbnail_url' => "$fullPath", 'is_short' => $request->has('type') ? true : false, 'is_uploaded' => true ]); } } public function updateVideo(StudioPlusVideo $studioPlusVideo) { $localStoragePath = $this->getLocalStoragePath($studioPlusVideo); Storage::makeDirectory('CreatorStudio'); $globalSetting = $studioPlusVideo->globalSetting; if ($globalSetting) { $introLocalPath = storage_path('app/public/' . $globalSetting->details['intro']); $outroLocalPath = storage_path('app/public/' . $globalSetting->details['outro']); $outroOutputPath = storage_path("app/CreatorStudio/outro.mp4"); Storage::delete('CreatorStudio/outro.mp4'); VideoService::copyAndRescale($outroLocalPath, $outroOutputPath); } else { $introLocalPath = module_path('StudioPlus') . "/Storage/default.ts"; } $introOutputPath = storage_path("app/CreatorStudio/intro.mp4"); Storage::delete('CreatorStudio/intro.mp4'); VideoService::copyAndRescale($introLocalPath, $introOutputPath); $resultPath = storage_path("app/$localStoragePath/video.mp4"); $video = (new GCPService)->download($studioPlusVideo, public_path('CreatorStudio')); $outroOutputPath = isset($outroOutputPath) ? $outroOutputPath : $introOutputPath; VideoService::concat( $introOutputPath, $video, $resultPath, $outroOutputPath ); $newFileName = Str::random() . ".mp4"; $objectName = $this->getGoogleStoragePath($studioPlusVideo) . "/$newFileName"; $this->uploadFileToGCP($resultPath, $objectName, $studioPlusVideo->videoType->vertical_video ? $studioPlusVideo->title : $studioPlusVideo->asin); if (File::exists($video)) { File::delete($video); } Storage::delete("$localStoragePath/video.mp4"); $studioPlusVideo->update([ 'video_url' => $objectName, 'upload_status' => StudioPlusVideo::UPLOAD_STATUS_COMPLETE ]); } public function updateVideoMetaData(string $objectName, string $fileName): void { $bucket = $this->storageClient->bucket($this->bucketName); $object = $bucket->object($objectName); $object->update([ 'contentDisposition' => 'attachment; filename="'.preg_replace('/[^a-zA-Z0-9_.]/', '_', $fileName).'.mp4"', ]); } }