Files
2024-02-12 22:54:20 -05:00

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);
}
}
}
}
}