mirror of
https://github.com/Bigherollc/wticreatorstudio.git
synced 2026-07-14 09:01:42 -04:00
608 lines
24 KiB
PHP
608 lines
24 KiB
PHP
<?php
|
|
|
|
namespace Modules\StudioPlus\Services;
|
|
|
|
use \FFMpeg\FFMpeg;
|
|
use \FFMpeg\FFProbe;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\File;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
use Modules\StudioPlus\Entities\StudioPlusVideo;
|
|
use Modules\StudioPlus\Jobs\ProcessVideo;
|
|
use Modules\StudioPlus\Jobs\StoreVideo;
|
|
use Symfony\Component\Process\Process;
|
|
use Modules\StudioPlus\Entities\StudioPlusThumbnail;
|
|
|
|
class UploadService
|
|
{
|
|
protected $watermark_service;
|
|
protected $video_resolutions_service;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->watermark_service = new WatermarkService();
|
|
$this->video_resolutions_service = new VideoResolutionsService();
|
|
}
|
|
|
|
public function handleUpload(Request $request)
|
|
{
|
|
$file = $request->file('video');
|
|
$filename = $file->getClientOriginalName();
|
|
$token = $request->token;
|
|
|
|
if ($request->has('mode') && $request->mode == 'create') {
|
|
$mode = 'create';
|
|
$id = auth()->id();
|
|
} else {
|
|
$mode = 'update';
|
|
$id = $request->id;
|
|
}
|
|
|
|
if ($id) {
|
|
if ($request->has('tempPath')) {
|
|
$temp_path = $request->tempPath;
|
|
} else {
|
|
$temp_path = $this->getTempLocalStoragePath($id, $token, $mode);
|
|
}
|
|
|
|
if ($temp_path) {
|
|
Storage::deleteDirectory($temp_path);
|
|
Storage::put("$temp_path/filename.dat", $filename);
|
|
Storage::put("$temp_path/path.dat", $temp_path);
|
|
$temp_filename = 'video.mp4';
|
|
$video_local_url = Storage::putFileAs($temp_path, $file, $temp_filename);
|
|
$resolution = $this->getVideoResolution(storage_path("app/$video_local_url"));
|
|
|
|
if ($this->isResolutionAllowed($resolution)) {
|
|
VideoService::copyAndRescale(storage_path("app/$temp_path/$temp_filename"), storage_path("app/$temp_path/video.mp4"));
|
|
|
|
$ffmpeg = FFMpeg::create();
|
|
$video = $ffmpeg->open(storage_path("app/{$video_local_url}"));
|
|
|
|
$ffprobe = FFProbe::create(get_ffprobe_config());
|
|
$code_ac = $ffprobe->format(storage_path("app/{$video_local_url}"))->get('duration');
|
|
|
|
// $thumbnails_storage_path = "$temp_path/thumbnails";
|
|
// if (! Storage::exists($thumbnails_storage_path)) {
|
|
// Storage::makeDirectory($thumbnails_storage_path);
|
|
// }
|
|
|
|
// $thumbnails = [];
|
|
// $timeFrameInSeconds = 2;
|
|
// for ($i = 0; $i < 3; $i++) {
|
|
// if ($timeFrameInSeconds < round($code_ac, PHP_ROUND_HALF_DOWN)) {
|
|
// $thumbnail_filename = Str::random(10).'.jpg';
|
|
// $thumbnail_path = asset("storage/app/$temp_path/thumbnails/$thumbnail_filename");
|
|
|
|
// $video->frame(\FFMpeg\Coordinate\TimeCode::fromSeconds($timeFrameInSeconds))
|
|
// ->save(storage_path("app/$temp_path/thumbnails/$thumbnail_filename"));
|
|
|
|
// $thumbnails[] = [
|
|
// 'id' => $thumbnail_filename,
|
|
// 'thumbnail_url' => $thumbnail_path,
|
|
// 'filename' => $thumbnail_filename,
|
|
// 'is_active' => $i === 0,
|
|
// ];
|
|
|
|
// $timeFrameInSeconds += 2;
|
|
// }
|
|
// }
|
|
|
|
// if ($mode == 'update') {
|
|
// $studio_plus_video = StudioPlusVideo::find($id);
|
|
// $current_thumbnails = $studio_plus_video->thumbnails->where('is_uploaded',1)->toArray();
|
|
// $thumbnails = array_merge($thumbnails, $current_thumbnails);
|
|
// }
|
|
|
|
return [
|
|
'temp_path' => $temp_path,
|
|
'url' => asset('storage/app/'.$video_local_url),
|
|
//'thumbnails' => $thumbnails,
|
|
];
|
|
} else {
|
|
return 'invalid-resolution';
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function handleUploadThumbnail(Request $request)
|
|
{
|
|
$file = $request->file('thumbnail');
|
|
$filename = $file->getClientOriginalName();
|
|
$exploded_filename = explode('.', $filename);
|
|
$ext = $exploded_filename[count($exploded_filename) - 1];
|
|
$id = auth()->id();
|
|
$mode = 'create';
|
|
|
|
if ($id) {
|
|
if ($request->has('tempPath')) {
|
|
$temp_path = $request->tempPath;
|
|
} else {
|
|
$temp_path = $this->getTempLocalStoragePath($id, $mode);
|
|
}
|
|
|
|
if ($temp_path) {
|
|
$ext = 'png';
|
|
if($request->has('type') && $request->type == 'short'){
|
|
$temp_filename = "000-is-uploaded-short.$ext";
|
|
} else {
|
|
$temp_filename = "000-is-uploaded.$ext";
|
|
}
|
|
Storage::delete("$temp_path/thumbnails/$temp_filename");
|
|
$thumbnail_local_url = Storage::putFileAs("$temp_path/thumbnails", $file, $temp_filename);
|
|
$thumbnails = Storage::allFiles("$temp_path/thumbnails");
|
|
|
|
$ret = [];
|
|
$i = 0;
|
|
foreach ($thumbnails as $thumbnail) {
|
|
$thumbnail_filename = basename($thumbnail);
|
|
$thumbnail_path = asset("storage/app/$temp_path/thumbnails/$thumbnail_filename");
|
|
|
|
$ret[] = [
|
|
'key' => Str::random(),
|
|
'id' => $thumbnail_filename,
|
|
'thumbnail_url' => $thumbnail_path,
|
|
'filename' => $thumbnail_filename,
|
|
'is_short' => str_contains($thumbnail_filename, 'is-uploaded-short') ? true : false,
|
|
'is_uploaded' => str_contains($thumbnail_filename, 'is-uploaded') ? true : false,
|
|
];
|
|
|
|
$i++;
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function processVideo($id, $mode = 'update')
|
|
{
|
|
ProcessVideo::dispatch($id, $mode);
|
|
}
|
|
|
|
public function asyncStoreVideo($id)
|
|
{
|
|
StoreVideo::dispatch($id);
|
|
}
|
|
|
|
public function updateVideo($id, $mode = 'update')
|
|
{
|
|
$video = StudioPlusVideo::find($id);
|
|
|
|
if ($video) {
|
|
$video->upload_status = StudioPlusVideo::UPLOAD_STATUS_PROCESSING;
|
|
$video->update();
|
|
|
|
$temp_path = $this->getTempUploadStoragePath($id);
|
|
//$result_path = storage_path("app/$temp_path/result.mp4");
|
|
Storage::delete("$temp_path/result.mp4");
|
|
//$is_short = Storage::exists("$temp_path/short.dat");
|
|
Storage::copy("$temp_path/video.mp4", "$temp_path/result.mp4");
|
|
|
|
if (Storage::exists("$temp_path/result.mp4")) {
|
|
Storage::put("$temp_path/processed.dat", 'Video processed.');
|
|
$this->storeVideo($id, $mode);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function updateVideox($id, $mode = 'update')
|
|
{
|
|
$studio_plus_video = StudioPlusVideo::find($id);
|
|
$temp_path = $this->getTempUploadStoragePath($id);
|
|
|
|
if ($studio_plus_video) {
|
|
//$studio_plus_video->upload_status = StudioPlusVideo::UPLOAD_STATUS_PROCESSING;
|
|
//$studio_plus_video->update();
|
|
|
|
Log::info('Processing video '.$studio_plus_video->id);
|
|
}
|
|
|
|
$globalSetting = $studio_plus_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('Copied outro');
|
|
|
|
Log::info('intro outro paths');
|
|
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);
|
|
Log::info('Copied intro');*/
|
|
|
|
// Copy watermark
|
|
$watermark = storage_path('app/CreatorStudio/watermark-transparent.png');
|
|
|
|
$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");
|
|
|
|
$is_short = Storage::exists("$temp_path/short.dat");
|
|
|
|
try {
|
|
/*Storage::copy("$temp_path/video.mp4", "$temp_path/result.mp4");
|
|
Log::info('Copied video as result for short');
|
|
|
|
if ($is_short) {
|
|
Storage::copy("$temp_path/video.mp4", "$temp_path/result.mp4");
|
|
Log::info('Copied video as result for short');
|
|
}
|
|
else {
|
|
Log::info('Merging videos');
|
|
|
|
$this->concat(
|
|
$introOutputPath,
|
|
$video,
|
|
$resultPath,
|
|
$outroOutputPath
|
|
);
|
|
Log::info('Merged videos');
|
|
}*/
|
|
|
|
|
|
if ($is_short) {
|
|
Storage::copy("$temp_path/video.mp4", "$temp_path/result.mp4");
|
|
} else {
|
|
$this->watermark_service->addWatermark($studio_plus_video, $result_path);
|
|
}
|
|
} catch(\Exception $ex) {
|
|
Log::error('Exception processing video');
|
|
Log::error($ex);
|
|
}
|
|
|
|
if (Storage::exists("$temp_path/result.mp4")) {
|
|
Storage::put("$temp_path/processed.dat", 'Added intro and outro videos.');
|
|
StoreVideo::dispatch($id, $mode);
|
|
}
|
|
}
|
|
|
|
public function storeVideo($id, $mode = 'update')
|
|
{
|
|
|
|
$video = StudioPlusVideo::find($id);
|
|
|
|
if ($video) {
|
|
$gcp = new GoogleCloudPlatform();
|
|
|
|
$temp_path = $this->getTempUploadStoragePath($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");
|
|
|
|
$ffprobe = FFProbe::create(get_ffprobe_config());
|
|
$code_ac = $ffprobe->format($original_video_path)->get('duration');
|
|
|
|
$original_video_filename = 'O'.Carbon::now()->format('YmdHis').Str::random().'.mp4';
|
|
$original_video_object_name = $gcp->getGoogleStoragePath($video)."/$original_video_filename";
|
|
$gcp->uploadFileToGCP($original_video_path, $original_video_object_name, $video->videoType->vertical_video ? $video->title : $video->asin);
|
|
|
|
$result_path = storage_path("app/$temp_path/result.mp4");
|
|
$filename = 'P'.Carbon::now()->format('YmdHis').Str::random().'.mp4';
|
|
$object_name = $gcp->getGoogleStoragePath($video)."/$filename";
|
|
$gcp->uploadFileToGCP($result_path, $object_name, $video->videoType->vertical_video ? $video->title : $video->asin);
|
|
|
|
|
|
$gcp_storage_path = $gcp->getGoogleStoragePath($video);
|
|
// $thumbnails = Storage::allFiles("$temp_path/thumbnails");
|
|
|
|
// $has_active_thumbnail = false;
|
|
// if ($mode == 'update') {
|
|
// $video->thumbnails()->where('is_uploaded',0)->delete();
|
|
// $has_active_thumbnail = $video->thumbnails()->where('is_active',1)->first();
|
|
// }
|
|
|
|
|
|
// $i = 0;
|
|
// foreach ($thumbnails as $thumbnail) {
|
|
// $thumbnail_filename = basename($thumbnail);
|
|
// $thumbnail_nfilename = Carbon::now()->format('YmdHis').Str::random().$thumbnail_filename;
|
|
// $thumbnail_path = "$gcp_storage_path/thumbnails/$thumbnail_nfilename";
|
|
// $gcp->uploadFileToGCP(storage_path("app/$temp_path/thumbnails/$thumbnail_filename"), $thumbnail_path);
|
|
|
|
// if ($video->thumbnail_id) {
|
|
// $is_active = $video->thumbnail_id == $thumbnail_filename;
|
|
// } else {
|
|
// $is_active = $i === 0;
|
|
// }
|
|
|
|
// $video->thumbnails()->create([
|
|
// 'thumbnail_url' => "$thumbnail_path",
|
|
// 'filename' => $thumbnail_nfilename,
|
|
// 'is_active' => $has_active_thumbnail ? 0 : $is_active,
|
|
// 'is_uploaded' => str_contains($thumbnail_filename, 'is-uploaded') ? true : false,
|
|
// ]);
|
|
|
|
// $i++;
|
|
// }
|
|
|
|
/*$total_reviews = 0;
|
|
$product_details = (new AmazonProductService())->getProductDetails($video->asin);
|
|
|
|
if ($product_details) {
|
|
$total_reviews = $product_details['amazon_total_reviews'];
|
|
}*/
|
|
|
|
$video->update([
|
|
'original_video_url' => $original_video_object_name,
|
|
'video_url' => $object_name,
|
|
'video_duration' => round($code_ac, PHP_ROUND_HALF_UP),
|
|
'upload_status' => StudioPlusVideo::UPLOAD_STATUS_PENDING,
|
|
]);
|
|
|
|
Storage::put("$temp_path/stored.dat", 'Video and thumbnails has been uploaded.');
|
|
Storage::deleteDirectory(Storage::get("$temp_path/temp_path.dat"));
|
|
Storage::deleteDirectory($temp_path);
|
|
|
|
return true;
|
|
} else {
|
|
sleep(5);
|
|
StoreVideo::dispatch($id);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function createVideo($request, $studio_plus_channel)
|
|
{
|
|
$gcp = new GoogleCloudPlatform();
|
|
$id = auth()->id();
|
|
$token = $request->token;
|
|
//$temp_path = $this->getTempLocalStoragePath($id, $token, 'create');
|
|
$temp_path = $request->tempPath;
|
|
|
|
if ($temp_path) {
|
|
if ($request->has('is_short') && $request->is_short) {
|
|
Storage::put("$temp_path/short.dat", 'Short Video');
|
|
}
|
|
|
|
Storage::put("$temp_path/thumbnail.dat", $request->thumbnail_id);
|
|
$filename = Storage::get("$temp_path/filename.dat");
|
|
$filename = str_replace(' ', '', $filename);
|
|
$exploded_filename = explode('.', $filename);
|
|
$title = collect(Arr::except($exploded_filename, array_key_last($exploded_filename)))->join(' ');
|
|
|
|
$video_local_url = "storage/app/$temp_path/video.mp4";
|
|
$params = $request->except('_token');
|
|
$params['original_video_url'] = $video_local_url;
|
|
$params['video_url'] = $video_local_url;
|
|
|
|
$video = $gcp->storeNewVideo(
|
|
$studio_plus_channel,
|
|
$title,
|
|
$filename,
|
|
$params
|
|
);
|
|
|
|
// $thumbnails = Storage::allFiles("$temp_path/thumbnails");
|
|
|
|
// $i = 0;
|
|
// foreach ($thumbnails as $thumbnail) {
|
|
// $thumbnail_filename = basename($thumbnail);
|
|
// $thumbnail_path = "app/$temp_path/thumbnails/$thumbnail_filename";
|
|
|
|
// if ($request->has('thumbnail_id')) {
|
|
// $is_active = $request->thumbnail_id == $thumbnail_filename;
|
|
// } else {
|
|
// $is_active = $i === 0;
|
|
// }
|
|
|
|
// $video->thumbnails()->create([
|
|
// 'thumbnail_url' => "$thumbnail_path",
|
|
// 'filename' => $thumbnail_filename,
|
|
// 'is_active' => $is_active,
|
|
// 'is_short' => str_contains($thumbnail_filename, 'is-uploaded-short') ? true : false,
|
|
// 'is_uploaded' => str_contains($thumbnail_filename, 'is-uploaded') ? true : false,
|
|
// ]);
|
|
|
|
// $i++;
|
|
// }
|
|
|
|
Storage::put("$temp_path/temp_path.dat", $temp_path);
|
|
|
|
$video_upload_path = $this->getTempUploadStoragePath($video->id);
|
|
File::copyDirectory(storage_path("app/$temp_path"), storage_path("app/$video_upload_path"));
|
|
|
|
if ($video) {
|
|
$video_upload_temp_path = "storage/app/$video_upload_path/video.mp4";
|
|
$video->original_video_url = $video_upload_temp_path;
|
|
$video->video_url = $video_upload_temp_path;
|
|
$video->studio_plus_asin_id = !$video->videoType->vertical_video ? $request->studio_plus_asin_id : null;
|
|
$video->save();
|
|
}
|
|
|
|
return $video;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function handleUpdateThumbnail($id, $file)
|
|
{
|
|
$video = StudioPlusVideo::find($id);
|
|
|
|
if ($video) {
|
|
$gcp = new GoogleCloudPlatform();
|
|
|
|
$filename = $file->getClientOriginalName();
|
|
$exploded_filename = explode('.', $filename);
|
|
$ext = $exploded_filename[count($exploded_filename) - 1];
|
|
$nfilename = Carbon::now()->format('YmdHis').Str::random().$filename;
|
|
|
|
$full_path = '/uploads/users/'.auth()->id()."/videos/{$video->id}/thumbnails/$nfilename";
|
|
|
|
$gcp->uploadFileToGCP($file, $full_path);
|
|
|
|
$video->thumbnails()->update([
|
|
'is_active' => false,
|
|
'is_uploaded' => false,
|
|
]);
|
|
|
|
$thumbnail = $video->thumbnails()->create([
|
|
'filename' => $filename,
|
|
'thumbnail_url' => $full_path,
|
|
'is_active' => true,
|
|
'is_short' => str_contains($filename, 'is-uploaded-short') ? true : false,
|
|
'is_uploaded' => true,
|
|
]);
|
|
|
|
return $thumbnail;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function getTempLocalStoragePath($id, $token = 'default', $mode = 'update')
|
|
{
|
|
if ($mode == 'create') {
|
|
$stamp = Carbon::now()->format('YmdHis');
|
|
$uid = $stamp.Str::random();
|
|
|
|
$path = "CreatorStudio/temp/user/$id/$token/$uid";
|
|
|
|
return $path;
|
|
} else {
|
|
$video = StudioPlusVideo::find($id);
|
|
|
|
if ($video) {
|
|
return "CreatorStudio/temp/videos/$id";
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function getTempUploadStoragePath($id)
|
|
{
|
|
$video = StudioPlusVideo::find($id);
|
|
|
|
if ($video) {
|
|
return "CreatorStudio/temp/upload/$id";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
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 getVideoResolution($video_path)
|
|
{
|
|
Log::info('Getting Video Resolution:');
|
|
Log::info($video_path);
|
|
$process = new Process(['ffprobe', '-v', 'error', '-select_streams', 'v:0', '-show_entries', 'stream=width,height', '-of', 'json', $video_path]);
|
|
$process->run();
|
|
|
|
if ($process->isSuccessful()) {
|
|
$output = json_decode($process->getOutput(), true);
|
|
Log::info('GetVideoResolution Success.');
|
|
Log::info($output);
|
|
|
|
return $output['streams'][0];
|
|
} else {
|
|
Log::info($process->getOutput());
|
|
Log::info('GetVideoResolution Failed.');
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function watermarked($video_path, $watermark_path, $output_video_path)
|
|
{
|
|
`ffmpeg -i "$video_path" -i "$watermark_path" -filter_complex "overlay=10:10:enable='between(t\\,0\\,3)'" "$output_video_path"`;
|
|
}
|
|
|
|
public function getVideoDuration($video)
|
|
{
|
|
$ffprobe = FFProbe::create(get_ffprobe_config());
|
|
$duration = $ffprobe
|
|
->streams($video)
|
|
->videos()
|
|
->first()
|
|
->get('duration');
|
|
|
|
return $duration;
|
|
}
|
|
|
|
public function addWatermark($video, $watermark, $output)
|
|
{
|
|
$output_stage_1 = str_replace('result', 'result-1', $output);
|
|
$output_stage_2 = str_replace('result', 'result-2', $output);
|
|
$output_stage_3 = str_replace('result', 'result-3', $output);
|
|
$this->addStartingWatermark($video, $watermark, $output_stage_1);
|
|
$this->addEndingWatermark($output_stage_1, $watermark, $output_stage_2);
|
|
$this->addTextWatermark($output_stage_2, 'WTI Creator Studio', $output_stage_3);
|
|
}
|
|
|
|
public function addStartingWatermark($video, $watermark, $output)
|
|
{
|
|
`ffmpeg -i "$video" -i "$watermark" -filter_complex "overlay=10:10:enable='between(t\\,0\\,3)'" "$output"`;
|
|
}
|
|
|
|
public function addEndingWatermark($video, $watermark, $output)
|
|
{
|
|
$duration = $this->getVideoDuration($video);
|
|
|
|
if ($duration) {
|
|
$duration = ceil($duration);
|
|
$start = $duration - 3;
|
|
$end = $duration;
|
|
`ffmpeg -i "$video" -i "$watermark" -filter_complex "overlay=10:10:enable='between(t\\,$start\\,$end)'" "$output"`;
|
|
}
|
|
}
|
|
|
|
public function addTextWatermark($video, $watermark, $output)
|
|
{
|
|
$font = storage_path('app/CreatorStudio/sample.ttf');
|
|
$font = str_replace('\\', '/', $font);
|
|
Log::info($font);
|
|
$font = 'D\:/Works/wticreatorstudio/storage/app/CreatorStudio/sample.ttf';
|
|
`ffmpeg -i "$video" -vf "drawtext=fontfile='$font':text='$watermark':fontcolor=white:fontsize=48:box=1:[email protected]:boxborderw=20:x=(w-text_w)/2:y=(h-text_h)/2:enable='between(t\\,5\\,10)'" "$output"`;
|
|
}
|
|
|
|
protected function isResolutionAllowed($resolution)
|
|
{
|
|
$allowed_resolutions = $this->video_resolutions_service->getActive();
|
|
|
|
foreach ($allowed_resolutions as $item) {
|
|
if ($item->width == $resolution['width'] && $item->height == $resolution['height']) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|