mirror of
https://github.com/Bigherollc/wticreatorstudio.git
synced 2026-07-14 00:02:05 -04:00
371 lines
16 KiB
PHP
371 lines
16 KiB
PHP
<?php
|
|
|
|
namespace Modules\StudioPlus\Services;
|
|
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Facades\File;
|
|
use Modules\StudioPlus\Entities\StudioPlusVideo;
|
|
use \FFMpeg\FFMpeg;
|
|
use \FFMpeg\FFProbe;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Str;
|
|
use Modules\StudioPlus\Jobs\ProcessVideo;
|
|
use Modules\StudioPlus\Jobs\ReuploadVideo;
|
|
use Modules\StudioPlus\Repositories\ContentWatermarksRepository;
|
|
|
|
class VideoProcessingService
|
|
{
|
|
protected $watermark_service;
|
|
protected $upload_service;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->watermark_service = new WatermarkService();
|
|
$this->upload_service = new UploadService();
|
|
}
|
|
|
|
public function reprocess($id)
|
|
{
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Searching the video #' . $id);
|
|
$video = StudioPlusVideo::find($id);
|
|
|
|
if ($video) {
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Video found.');
|
|
$reprocess = true;
|
|
$meta = $video->meta()->where('name', 'is_old')->first();
|
|
|
|
if ($meta && $meta->value === 'true') {
|
|
$reprocess = false;
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Skipping reprocessing. Archived video detected.');
|
|
}
|
|
|
|
if ($reprocess) {
|
|
if (str_contains($video->video_url, 'temp')) {
|
|
$temp_path = $this->getTempUploadStoragePath($id);
|
|
|
|
if ($temp_path) {
|
|
if (!Storage::exists("$temp_path/video.mp4")) {
|
|
//$this->copyVideoToUploadStorage($video);
|
|
}
|
|
|
|
if (Storage::exists("$temp_path/video.mp4")) {
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Uploaded video found.');
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Reprocessing video #' . $id . ' from local.');
|
|
$this->upload_service->updateVideo($id);
|
|
$this->reprocessCloud($id);
|
|
Log::channel('reprocessing')->info('[#'. $id . '] Reprocessing completed.');
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$this->reprocessCloud($id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public function reprocessCloud($id)
|
|
{
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Processing in local server.');
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Reprocessing video #' . $id . ' from cloud.');
|
|
$video = StudioPlusVideo::find($id);
|
|
|
|
if ($video) {
|
|
$video->upload_status = StudioPlusVideo::UPLOAD_STATUS_PROCESSING;
|
|
$video->update();
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Updated video status to processing.');
|
|
|
|
$temp_path = $this->getTempLocalStoragePath($id);
|
|
Storage::deleteDirectory($temp_path);
|
|
Storage::put("$temp_path/reprocessing.dat", $id);
|
|
|
|
if ($video->is_short) {
|
|
Storage::put("$temp_path/short.dat", 'Short Video');
|
|
}
|
|
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Downloading video from cloud.');
|
|
(new GCPService)->download($video, storage_path("app/$temp_path"));
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Download completed.');
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Copying video for processing.');
|
|
Storage::copy("$temp_path/{$video->filename}", "$temp_path/video.mp4");
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Copied successfully.');
|
|
$video_path = storage_path("app/$temp_path/video.mp4");
|
|
$result_path = storage_path("app/$temp_path/result.mp4");
|
|
Storage::delete("$temp_path/result.mp4");
|
|
$is_short = Storage::exists("$temp_path/short.dat");
|
|
|
|
if ($is_short) {
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Video detected as type shorts.');
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Copying video without processing as an output.');
|
|
Storage::copy("$temp_path/video.mp4", "$temp_path/result.mp4");
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Copied successfully.');
|
|
}
|
|
else {
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Adding watermarks. (See watermarking logs)');
|
|
$this->watermark_service->addWatermark($video, $result_path, true);
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Watermarks application completed.');
|
|
}
|
|
|
|
Storage::put("$temp_path/processed.dat", 'Video processed.');
|
|
$this->store($id);
|
|
}
|
|
}
|
|
|
|
public function reprocessCloudx($id)
|
|
{
|
|
Log::info('Searching the video with id ' . $id);
|
|
$video = StudioPlusVideo::find($id);
|
|
$studio_plus_video = $video;
|
|
|
|
if ($video) {
|
|
Log::info('Video found');
|
|
|
|
$video->upload_status = StudioPlusVideo::UPLOAD_STATUS_PROCESSING;
|
|
$video->update();
|
|
|
|
$temp_path = $this->getTempLocalStoragePath($id);
|
|
Storage::deleteDirectory($temp_path);
|
|
Storage::put("$temp_path/reprocessing.dat", $id);
|
|
|
|
if ($video->is_short) {
|
|
Storage::put("$temp_path/short.dat", 'Short Video');
|
|
}
|
|
|
|
Log::info('Downloading video to temp path');
|
|
$file = (new GCPService)->download($video, storage_path("app/$temp_path"));
|
|
Log::info('Copying file');
|
|
Storage::copy("$temp_path/{$video->filename}", "$temp_path/video.mp4");
|
|
|
|
$globalSetting = $video->globalSetting;
|
|
|
|
/*if ($globalSetting) {
|
|
$introLocalPath = storage_path('app/public/' . $globalSetting->details['intro']);
|
|
$outroLocalPath = storage_path('app/public/' . $globalSetting->details['outro']);
|
|
$outroOutputPath = storage_path("app/$temp_path/outro.mp4");
|
|
|
|
Storage::delete("$temp_path/outro.mp4");
|
|
VideoService::copyAndRescale($outroLocalPath, $outroOutputPath);
|
|
|
|
Log::info('copying outro');
|
|
Log::info($introLocalPath);
|
|
Log::info($outroLocalPath);
|
|
}
|
|
else {
|
|
$introLocalPath = module_path('StudioPlus') . "/Storage/default.ts";
|
|
Log::info('no global setting');
|
|
}
|
|
|
|
$introOutputPath = storage_path("app/$temp_path/intro.mp4");
|
|
|
|
Storage::delete("$temp_path/intro.mp4");
|
|
VideoService::copyAndRescale($introLocalPath, $introOutputPath);*/
|
|
|
|
$video = storage_path("app/$temp_path/video.mp4");
|
|
//$outroOutputPath = isset($outroOutputPath) ? $outroOutputPath : $introOutputPath;
|
|
|
|
$resultPath = storage_path("app/$temp_path/result.mp4");
|
|
$result_path = $resultPath;
|
|
Storage::delete("$temp_path/result.mp4");
|
|
|
|
try {
|
|
//Storage::copy("$temp_path/video.mp4", "$temp_path/result.mp4");
|
|
|
|
$is_short = Storage::exists("$temp_path/short.dat");
|
|
|
|
/*if ($is_short) {
|
|
Storage::copy("$temp_path/video.mp4", "$temp_path/result.mp4");
|
|
}
|
|
else {
|
|
$this->concat(
|
|
$introOutputPath,
|
|
$video,
|
|
$resultPath,
|
|
$outroOutputPath
|
|
);
|
|
}*/
|
|
|
|
if ($is_short) {
|
|
Storage::copy("$temp_path/video.mp4", "$temp_path/result.mp4");
|
|
}
|
|
else {
|
|
$this->watermark_service->addWatermark($studio_plus_video, $result_path, true);
|
|
}
|
|
}
|
|
catch(\Exception $ex) {
|
|
Log::info($ex);
|
|
}
|
|
|
|
Storage::put("$temp_path/processed.dat", 'Added intro and outro videos.');
|
|
|
|
ReuploadVideo::dispatch($id);
|
|
}
|
|
}
|
|
|
|
public function copyVideoToUploadStorage($video)
|
|
{
|
|
$temp_path = str_replace('storage/app/', '', $video->video_url);
|
|
$temp_path = str_replace('/video.mp4', '', $temp_path);
|
|
$video_upload_path = $this->getTempUploadStoragePath($video->id);
|
|
File::copyDirectory(storage_path("app/$temp_path"), storage_path("app/$video_upload_path"));
|
|
}
|
|
|
|
public function store($id)
|
|
{
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Storing video #' . $id . ' to cloud.');
|
|
$video = StudioPlusVideo::find($id);
|
|
|
|
if ($video) {
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Video found.');
|
|
$gcp = new GoogleCloudPlatform();
|
|
$temp_path = $this->getTempLocalStoragePath($id);
|
|
$is_processed = Storage::exists("$temp_path/processed.dat");
|
|
$is_stored = Storage::exists("$temp_path/stored.dat");
|
|
|
|
if ($is_processed && !$is_stored) {
|
|
$original_video_path = storage_path("app/$temp_path/video.mp4");
|
|
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Fetching video duration.');
|
|
$ffprobe = FFProbe::create(get_ffprobe_config());
|
|
$code_ac = $ffprobe->format($original_video_path)->get('duration');
|
|
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Generating object name for cloud storage.');
|
|
$result_path = storage_path("app/$temp_path/result.mp4");
|
|
$filename = 'P' . Carbon::now()->format('YmdHis') . Str::random() . ".mp4";
|
|
$object_name = $gcp->getGoogleStoragePath($video) . "/$filename";
|
|
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Uploading video to cloud.');
|
|
$gcp->uploadFileToGCP($result_path, $object_name);
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Upload completed.');
|
|
|
|
$video->update([
|
|
'video_url' => $object_name,
|
|
'video_duration' => round($code_ac, PHP_ROUND_HALF_UP),
|
|
'upload_status' => StudioPlusVideo::UPLOAD_STATUS_COMPLETE
|
|
]);
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Updated video status to complete.');
|
|
|
|
Storage::put("$temp_path/stored.dat", 'Video has been uploaded.');
|
|
Storage::deleteDirectory($temp_path);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function getUnprocessedVideos()
|
|
{
|
|
$videos = StudioPlusVideo::where('upload_status', StudioPlusVideo::UPLOAD_STATUS_PROCESSING)->latest('id')->take(10)->get();
|
|
|
|
return $videos;
|
|
}
|
|
|
|
public function concat(string $intro, string $pathToVideo, string $pathToOutput, string $outro = ''): void
|
|
{
|
|
$newOutro = $outro ?: $intro;
|
|
`ffmpeg -i "$intro" -i "$pathToVideo" -i "$newOutro" -filter_complex "[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:-1:-1,setsar=1,fps=30,format=yuv420p[v0];[1:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:-1:-1,setsar=1,fps=30,format=yuv420p[v1];[2:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:-1:-1,setsar=1,fps=30,format=yuv420p[v2];[v0][0:a][v1][1:a][v2][2:a]concat=n=3:v=1:a=1[v][a]" -map "[v]" -map "[a]" -c:v libx264 -c:a aac -movflags +faststart "$pathToOutput"`;
|
|
}
|
|
|
|
public function getTempLocalStoragePath($id)
|
|
{
|
|
return "CreatorStudio/temp/reprocess/videos/$id";
|
|
}
|
|
|
|
public function getTempUploadStoragePath($id)
|
|
{
|
|
$video = StudioPlusVideo::find($id);
|
|
|
|
if ($video) {
|
|
return "CreatorStudio/temp/upload/$id";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function watermarked($video_path, $watermark_path, $output_video_path)
|
|
{
|
|
`ffmpeg -i "$video_path" -i "$watermark_path" -filter_complex "[1][0]scale2ref=oh*mdar:ih*0.2[logo][video];[video][logo]overlay:enable=between(t\,0\,3)" "$output_video_path"`;
|
|
}
|
|
|
|
public function processInNewServer($id, $user_id)
|
|
{
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Processing in new server.');
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Searching the video #' . $id);
|
|
$video = StudioPlusVideo::find($id);
|
|
|
|
if ($video) {
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Video found.');
|
|
$reprocess = true;
|
|
$meta = $video->meta()->where('name', 'is_old')->first();
|
|
|
|
if ($meta && $meta->value === 'true') {
|
|
$reprocess = false;
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Skipping reprocessing. Archived video detected.');
|
|
}
|
|
|
|
if ($reprocess) {
|
|
$watermarks_repository = new ContentWatermarksRepository();
|
|
$watermarks = $watermarks_repository->getActive()->toArray();
|
|
|
|
$response = Http::withHeaders([
|
|
'Authorization' => 'Bearer ooVeuWUlukjmsHSc26yVqlVT4BG7Ii9P'
|
|
])
|
|
->withoutVerifying()
|
|
->get('https://wtisv.com/api/studio/get-token');
|
|
|
|
if ($response->successful()) {
|
|
$data = $response->json();
|
|
$token = $data['token'];
|
|
|
|
Log::channel('tracing')->info($data);
|
|
|
|
$response = Http::withHeaders([
|
|
'Authorization' => "Bearer $token"
|
|
])
|
|
->withoutVerifying()
|
|
->post('https://wtisv.com/api/studio/video/process', [
|
|
'user_id' => $user_id,
|
|
'video_id' => $video->id,
|
|
'video_url' => $video->getRawOriginal('original_video_url'),
|
|
'video_types' => $video->types,
|
|
'is_short' => $video->is_short,
|
|
'watermarks' => $watermarks,
|
|
'origin' => 'https://wticreatorstudio.com',
|
|
]);
|
|
|
|
Log::channel('tracing')->info($response);
|
|
|
|
if ($response->successful()) {
|
|
$data = $response->json();
|
|
Log::channel('tracing')->info($response);
|
|
$result = $data['result'];
|
|
|
|
Log::channel('reprocessing')->info('[#' . $id . '] Result');
|
|
Log::channel('reprocessing')->info($result);
|
|
|
|
$video->update([
|
|
'video_url' => $result['video_url'],
|
|
'video_duration' => $result['video_duration'],
|
|
'upload_status' => $result['upload_status']
|
|
]);
|
|
|
|
if ($result['is_temp']) {
|
|
Storage::deleteDirectory($result['temp_video_path']);
|
|
}
|
|
}
|
|
else {
|
|
Log::channel('reprocessing')->info($response);
|
|
}
|
|
}
|
|
else {
|
|
Log::channel('reprocessing')->info($response);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|