From e462abf6d660e41d2170c52caf45704008de58e9 Mon Sep 17 00:00:00 2001 From: Yassine Doghri Date: Tue, 7 Dec 2021 16:58:12 +0000 Subject: [PATCH] feat(video-clips): replace hardcoded colors with config's theme colors --- .../MediaClipper/Config/MediaClipper.php | 20 ++++++ app/Libraries/MediaClipper/VideoClip.php | 67 ++++++++++++------ app/Libraries/MediaClipper/quotes.png | Bin 4247 -> 2822 bytes app/Resources/icons/clapperboard.svg | 6 ++ modules/Admin/Config/Routes.php | 16 +++-- ...ontroller.php => VideoClipsController.php} | 30 ++++++-- .../Admin/Language/en/EpisodeNavigation.php | 4 +- .../Admin/Language/fr/EpisodeNavigation.php | 3 + themes/cp_admin/episode/_sidebar.php | 6 +- themes/cp_admin/episode/video_clips_list.php | 13 ++++ .../{video_clips.php => video_clips_new.php} | 16 +++-- 11 files changed, 143 insertions(+), 38 deletions(-) create mode 100644 app/Resources/icons/clapperboard.svg rename modules/Admin/Controllers/{ClipsController.php => VideoClipsController.php} (71%) create mode 100644 themes/cp_admin/episode/video_clips_list.php rename themes/cp_admin/episode/{video_clips.php => video_clips_new.php} (73%) diff --git a/app/Libraries/MediaClipper/Config/MediaClipper.php b/app/Libraries/MediaClipper/Config/MediaClipper.php index 52702da6..c4571851 100644 --- a/app/Libraries/MediaClipper/Config/MediaClipper.php +++ b/app/Libraries/MediaClipper/Config/MediaClipper.php @@ -203,4 +203,24 @@ class MediaClipper extends BaseConfig ], ], ]; + + /** + * @var array> + */ + public array $themes = [ + 'pine' => [ + 'background' => [0, 86, 74], + 'text' => [255, 255, 255], + // subtitle hex color is BGR (Blue, Green, Red), + 'subtitles' => 'FFFFFF', + // quotes image MUST BE black + 'quotes' => [0, 148, 134], + 'episodeNumberingBg' => [0, 61, 11], + 'episodeNumberingText' => [255, 255, 255], + 'progressbar' => '009486', + 'timestampBg' => '00564A', + 'timestampText' => 'FFFFFF', + 'soundwaves' => 'F2FAF9', + ], + ]; } diff --git a/app/Libraries/MediaClipper/VideoClip.php b/app/Libraries/MediaClipper/VideoClip.php index 9be8e42f..909bd13e 100644 --- a/app/Libraries/MediaClipper/VideoClip.php +++ b/app/Libraries/MediaClipper/VideoClip.php @@ -44,32 +44,46 @@ class VideoClip protected ?string $episodeNumbering = null; - /** - * @var array - */ - protected array $dimensions = []; - /** * @var 'landscape'|'portrait'|'squared' */ protected string $format = 'landscape'; + /** + * @var array + */ + protected array $dimensions = []; + + /** + * @var 'pine'|'crimson'|'lake'|'amber'|'jacaranda'|'onyx' + */ + protected string $theme = 'pine'; + + /** + * @var array + */ + protected array $colors = []; + /** * @param 'landscape'|'portrait'|'squared' $format + * @param 'pine'|'crimson'|'lake'|'amber'|'jacaranda'|'onyx' $theme */ public function __construct( protected Episode $episode, protected float $start, protected float $end, string $format, + string $theme, ) { $this->duration = $end - $start; $this->format = $format; $this->episodeNumbering = $this->episodeNumbering($this->episode->number, $this->episode->season_number); $this->dimensions = config('MediaClipper') ->formats[$format]; + $this->colors = config('MediaClipper') + ->themes[$theme]; - helper('media'); + helper(['media']); $this->audioInput = media_path($this->episode->audio_file_path); $this->episodeCoverPath = media_path($this->episode->cover->path); @@ -118,7 +132,7 @@ class VideoClip { // @phpstan-ignore $filters = [ - "[0:a]aformat=channel_layouts=mono,showwaves=s={$this->dimensions['soundwaves']['width']}x{$this->dimensions['soundwaves']['height']}:mode=cline:rate=10:colors=white,format=yuva420p[waves]", + "[0:a]aformat=channel_layouts=mono,showwaves=s={$this->dimensions['soundwaves']['width']}x{$this->dimensions['soundwaves']['height']}:mode=cline:rate=10:colors=0xFFFFFF,format=yuva420p[waves]", "[waves]scale={$this->dimensions['width']}:{$this->dimensions['height']}:flags=neighbor[resizedwaves]", '[resizedwaves][3:v][4:v][5:v]threshold[cleanwaves]', '[cleanwaves][2:v]alphamerge[waves_t]', @@ -128,11 +142,11 @@ class VideoClip "[waves_t3]scale={$this->dimensions['soundwaves']['rescaleWidth']}:{$this->dimensions['soundwaves']['rescaleHeight']}[waves_final]", "[1:v][waves_final]overlay=x={$this->dimensions['soundwaves']['x']}:y={$this->dimensions['soundwaves']['y']}:shortest=1,drawtext=fontfile=" . $this->getFont( 'timestamp' - ) . ":text='%{pts\:gmtime\:{$this->start}\:%H\\\\\\\\\\:%M\\\\\\\\\\:%S\}':x={$this->dimensions['timestamp']['x']}:y={$this->dimensions['timestamp']['y']}:fontsize={$this->dimensions['timestamp']['fontsize']}:fontcolor=white:box=1:boxcolor=0x00564A:boxborderw={$this->dimensions['timestamp']['padding']}[v3]", - "color=c=0x009486:s={$this->dimensions['width']}x{$this->dimensions['progressbar']['height']}[progressbar]", + ) . ":text='%{pts\:gmtime\:{$this->start}\:%H\\\\\\\\\\:%M\\\\\\\\\\:%S\}':x={$this->dimensions['timestamp']['x']}:y={$this->dimensions['timestamp']['y']}:fontsize={$this->dimensions['timestamp']['fontsize']}:fontcolor=0x{$this->colors['timestampText']}:box=1:boxcolor=0x{$this->colors['timestampBg']}:boxborderw={$this->dimensions['timestamp']['padding']},format=yuv420p,colormatrix=bt601:bt2020[v3]", + "color=c=0x{$this->colors['progressbar']}:s={$this->dimensions['width']}x{$this->dimensions['progressbar']['height']}[progressbar]", "[v3][progressbar]overlay=-w+(w/{$this->duration})*t:0:shortest=1:format=rgb,subtitles={$this->subtitlesClipOutput}:fontsdir=" . config( 'MediaClipper' - )->fontsFolder . ":force_style='Fontname=" . self::FONTS['subtitles'] . ",Alignment=5,Fontsize={$this->dimensions['subtitles']['fontsize']},BorderStyle=1,Outline=0,Shadow=0,MarginL={$this->dimensions['subtitles']['marginL']},MarginR={$this->dimensions['subtitles']['marginR']},MarginV={$this->dimensions['subtitles']['marginV']}'[outv]", + )->fontsFolder . ":force_style='Fontname=" . self::FONTS['subtitles'] . ",Alignment=5,Fontsize={$this->dimensions['subtitles']['fontsize']},PrimaryColour=&H{$this->colors['subtitles']}&,BorderStyle=1,Outline=0,Shadow=0,MarginL={$this->dimensions['subtitles']['marginL']},MarginR={$this->dimensions['subtitles']['marginR']},MarginV={$this->dimensions['subtitles']['marginV']}',format=yuv420p,colormatrix=bt601:bt2020[outv]", ]; $videoClipCmd = [ @@ -142,12 +156,13 @@ class VideoClip "-loop 1 -framerate 30 -i {$this->dimensions['soundwaves']['mask']}", "-f lavfi -i color=gray:{$this->dimensions['width']}x{$this->dimensions['height']}", "-f lavfi -i color=black:{$this->dimensions['width']}x{$this->dimensions['height']}", - "-f lavfi -i color=white:{$this->dimensions['width']}x{$this->dimensions['height']}", + "-f lavfi -i color=0x{$this->colors['soundwaves']}:{$this->dimensions['width']}x{$this->dimensions['height']}", '-filter_complex "' . implode(';', $filters) . '"', '-map "[outv]"', '-map 0:a', '-acodec copy', '-vcodec libx264', + '-pix_fmt yuv420p', "{$this->videoClipOutput}", ]; @@ -184,7 +199,7 @@ class VideoClip private function generateVideoClipBg(): bool { - $background = $this->generateColouredBg($this->dimensions['width'], $this->dimensions['height']); + $background = $this->generateBackground($this->dimensions['width'], $this->dimensions['height']); if ($background === null) { return false; @@ -265,6 +280,8 @@ class VideoClip $this->episodeNumbering, $this->getFont('episodeNumbering'), $this->dimensions['episodeNumbering']['fontsize'], + $this->colors['episodeNumberingText'], + $this->colors['episodeNumberingBg'], $this->dimensions['episodeNumbering']['paddingX'], $this->dimensions['episodeNumbering']['paddingY'], ); @@ -289,6 +306,8 @@ class VideoClip return false; } + imagefilter($quotes, IMG_FILTER_COLORIZE, ...$this->colors['quotes']); + $scaledQuotes = $this->scaleImage( $quotes, $this->dimensions['quotes']['width'], @@ -319,7 +338,7 @@ class VideoClip return config('MediaClipper')->fontsFolder . self::FONTS[$name]; } - private function generateColouredBg(int $width, int $height): ?GdImage + private function generateBackground(int $width, int $height): ?GdImage { $background = imagecreatetruecolor($width, $height); @@ -327,7 +346,7 @@ class VideoClip return null; } - $coloredBackground = imagecolorallocate($background, 0, 86, 74); + $coloredBackground = imagecolorallocate($background, ...$this->colors['background']); if ($coloredBackground === false) { return null; @@ -450,9 +469,9 @@ class VideoClip int $paragraphIndent = 0, ): bool { // Allocate A Color For The Text - $white = imagecolorallocate($image, 255, 255, 255); + $textColor = imagecolorallocate($image, ...$this->colors['text']); - if ($white === false) { + if ($textColor === false) { return false; } @@ -470,7 +489,7 @@ class VideoClip 0, $x + ($paragraphIndent * ($i === 0 ? 1 : 0)), $y + $fontsize + ($leading * $i), - $white, + $textColor, $fontPath, $line ); @@ -510,6 +529,10 @@ class VideoClip ]; } + /** + * @param int[] $boxTextColor + * @param int[] $boxBgColor + */ private function addTextWithBox( GdImage $image, int $x, @@ -517,14 +540,16 @@ class VideoClip string $text, string $fontPath, int $fontsize, + array $boxTextColor, + array $boxBgColor, int $paddingX = 0, int $paddingY = 0, ): bool { // Create some colors - $white = imagecolorallocate($image, 255, 255, 255); - $bgColor = imagecolorallocate($image, 0, 61, 11); + $textColor = imagecolorallocate($image, ...$boxTextColor); + $bgColor = imagecolorallocate($image, ...$boxBgColor); - if ($white === false || $bgColor === false) { + if ($textColor === false || $bgColor === false) { return false; } @@ -540,7 +565,7 @@ class VideoClip $y2 = $y + $bbox['height'] + ($paddingY * 2); imagefilledrectangle($image, $x, $y, $x2, $y2, $bgColor); - imagettftext($image, $fontsize, 0, $x1, $y1, $white, $fontPath, $text); + imagettftext($image, $fontsize, 0, $x1, $y1, $textColor, $fontPath, $text); return true; } diff --git a/app/Libraries/MediaClipper/quotes.png b/app/Libraries/MediaClipper/quotes.png index 2c65242817398e386b3c512453968dc34e2db5ec..41f22cacf9d154f9629ab61c9f60fe516fcd4367 100644 GIT binary patch delta 2615 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 Ef>OKk3jhEB diff --git a/app/Resources/icons/clapperboard.svg b/app/Resources/icons/clapperboard.svg new file mode 100644 index 00000000..c5d7d121 --- /dev/null +++ b/app/Resources/icons/clapperboard.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/modules/Admin/Config/Routes.php b/modules/Admin/Config/Routes.php index 469859db..59233f61 100644 --- a/modules/Admin/Config/Routes.php +++ b/modules/Admin/Config/Routes.php @@ -352,15 +352,23 @@ $routes->group( ); $routes->get( 'video-clips', - 'ClipsController::videoClips/$1/$2', + 'VideoClipsController::list/$1/$2', [ - 'as' => 'video-clips', + 'as' => 'video-clips-list', + 'filter' => 'permission:podcast_episodes-edit', + ], + ); + $routes->get( + 'video-clips/new', + 'VideoClipsController::generate/$1/$2', + [ + 'as' => 'video-clips-generate', 'filter' => 'permission:podcast_episodes-edit', ], ); $routes->post( - 'video-clips', - 'ClipsController::generateVideoClip/$1/$2', + 'video-clips/new', + 'VideoClipsController::attemptGenerate/$1/$2', [ 'as' => 'video-clips-generate', 'filter' => 'permission:podcast_episodes-edit', diff --git a/modules/Admin/Controllers/ClipsController.php b/modules/Admin/Controllers/VideoClipsController.php similarity index 71% rename from modules/Admin/Controllers/ClipsController.php rename to modules/Admin/Controllers/VideoClipsController.php index cfb9eb4d..3520e286 100644 --- a/modules/Admin/Controllers/ClipsController.php +++ b/modules/Admin/Controllers/VideoClipsController.php @@ -18,7 +18,7 @@ use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\HTTP\RedirectResponse; use MediaClipper\VideoClip; -class ClipsController extends BaseController +class VideoClipsController extends BaseController { protected Podcast $podcast; @@ -55,7 +55,21 @@ class ClipsController extends BaseController return $this->{$method}(...$params); } - public function videoClips(): string + public function list(): string + { + $data = [ + 'podcast' => $this->podcast, + 'episode' => $this->episode, + ]; + + replace_breadcrumb_params([ + 0 => $this->podcast->title, + 1 => $this->episode->title, + ]); + return view('episode/video_clips_list', $data); + } + + public function generate(): string { helper('form'); @@ -66,18 +80,19 @@ class ClipsController extends BaseController replace_breadcrumb_params([ 0 => $this->podcast->title, - 1 => $this->episode->slug, + 1 => $this->episode->title, ]); - return view('episode/video_clips', $data); + return view('episode/video_clips_new', $data); } - public function generateVideoClip(): RedirectResponse + public function attemptGenerate(): RedirectResponse { // TODO: add end_time greater than start_time, with minimum ? $rules = [ - 'format' => 'required|in_list[landscape,portrait,squared]', 'start_time' => 'required|numeric', 'end_time' => 'required|numeric|differs[start_time]', + 'format' => 'required|in_list[' . implode(',', array_keys(config('MediaClipper')->formats)) . ']', + 'theme' => 'required|in_list[' . implode(',', array_keys(config('Colors')->themes)) . ']', ]; if (! $this->validate($rules)) { @@ -92,10 +107,11 @@ class ClipsController extends BaseController (float) $this->request->getPost('start_time'), (float) $this->request->getPost('end_time',), $this->request->getPost('format'), + $this->request->getPost('theme'), ); $clipper->generate(); - return redirect()->route('video-clips', [$this->podcast->id, $this->episode->id])->with( + return redirect()->route('video-clips-generate', [$this->podcast->id, $this->episode->id])->with( 'message', lang('Settings.images.regenerationSuccess') ); diff --git a/modules/Admin/Language/en/EpisodeNavigation.php b/modules/Admin/Language/en/EpisodeNavigation.php index c7f7dba3..8e2df5be 100644 --- a/modules/Admin/Language/en/EpisodeNavigation.php +++ b/modules/Admin/Language/en/EpisodeNavigation.php @@ -15,6 +15,8 @@ return [ 'episode-edit' => 'Edit episode', 'episode-persons-manage' => 'Manage persons', 'embed-add' => 'Embeddable player', + 'clips' => 'Clips', 'soundbites-edit' => 'Soundbites', - 'video-clips' => 'Video clips', + 'video-clips-list' => 'Video clips', + 'video-clips-generate' => 'New video clip', ]; diff --git a/modules/Admin/Language/fr/EpisodeNavigation.php b/modules/Admin/Language/fr/EpisodeNavigation.php index d85c74d2..288b9203 100644 --- a/modules/Admin/Language/fr/EpisodeNavigation.php +++ b/modules/Admin/Language/fr/EpisodeNavigation.php @@ -15,5 +15,8 @@ return [ 'episode-edit' => 'Modifier l’épisode', 'episode-persons-manage' => 'Gestion des intervenants', 'embed' => 'Lecteur intégré', + 'clips' => 'Extraits', 'soundbites-edit' => 'Extraits sonores', + 'video-clips-list' => 'Extraits video', + 'video-clips-generate' => 'Nouvel extrait video', ]; diff --git a/themes/cp_admin/episode/_sidebar.php b/themes/cp_admin/episode/_sidebar.php index 32332db0..9fbcf493 100644 --- a/themes/cp_admin/episode/_sidebar.php +++ b/themes/cp_admin/episode/_sidebar.php @@ -3,7 +3,11 @@ $podcastNavigation = [ 'dashboard' => [ 'icon' => 'dashboard', - 'items' => ['episode-view', 'episode-edit', 'episode-persons-manage', 'embed-add', 'soundbites-edit', 'video-clips'], + 'items' => ['episode-view', 'episode-edit', 'episode-persons-manage', 'embed-add'], + ], + 'clips' => [ + 'icon' => 'clapperboard', + 'items' => ['video-clips-list', 'video-clips-generate', 'soundbites-edit'], ], ]; ?> diff --git a/themes/cp_admin/episode/video_clips_list.php b/themes/cp_admin/episode/video_clips_list.php new file mode 100644 index 00000000..f357a622 --- /dev/null +++ b/themes/cp_admin/episode/video_clips_list.php @@ -0,0 +1,13 @@ +extend('_layout') ?> + +section('title') ?> + +endSection() ?> + +section('pageTitle') ?> + +endSection() ?> + +section('content') ?> + +endSection() ?> diff --git a/themes/cp_admin/episode/video_clips.php b/themes/cp_admin/episode/video_clips_new.php similarity index 73% rename from themes/cp_admin/episode/video_clips.php rename to themes/cp_admin/episode/video_clips_new.php index 314b060c..abcb48b2 100644 --- a/themes/cp_admin/episode/video_clips.php +++ b/themes/cp_admin/episode/video_clips_new.php @@ -28,23 +28,31 @@ +
+ themes as $themeName => $color): ?> + + +
+ - -