diff --git a/app/Libraries/MediaClipper/Config/MediaClipper.php b/app/Libraries/MediaClipper/Config/MediaClipper.php
index 536e4a5e4b3292fd3adc20b102c7232d79f66759..5f5420d6ef23bdeb560cd433d1df6ead9e3695f9 100644
--- a/app/Libraries/MediaClipper/Config/MediaClipper.php
+++ b/app/Libraries/MediaClipper/Config/MediaClipper.php
@@ -37,7 +37,7 @@ class MediaClipper extends BaseConfig
             'episodeTitle' => [
                 'fontsize' => 32,
                 'x' => 150,
-                'y' => 690,
+                'y' => 660,
                 'lines' => 3,
                 'lineWidth' => 28,
                 'leading' => 20,
@@ -45,20 +45,20 @@ class MediaClipper extends BaseConfig
             'podcastTitle' => [
                 'fontsize' => 20,
                 'x' => 150,
-                'y' => 640,
+                'y' => 620,
             ],
             'episodeNumbering' => [
                 'fontsize' => 18,
                 'paddingX' => 10,
                 'paddingY' => 5,
-                'x' => 180 + 10,
+                'x' => 180,
                 'y' => 540,
             ],
             'timestamp' => [
                 'fontsize' => 32,
                 'padding' => 10,
-                'x' => 1678,
-                'y' => 986,
+                'x' => 1680,
+                'y' => 985,
             ],
             'progressbar' => [
                 'height' => 10,
@@ -70,7 +70,7 @@ class MediaClipper extends BaseConfig
                 'rescaleHeight' => 540,
                 'x' => 0,
                 'y' => 810,
-                'mask' => APPPATH . 'Libraries/MediaClipper/waves-mask.png',
+                'mask' => APPPATH . 'Libraries/MediaClipper/soundwaves-mask-landscape.png',
             ],
             'subtitles' => [
                 'fontsize' => 18,
@@ -82,10 +82,124 @@ class MediaClipper extends BaseConfig
         'portrait' => [
             'width' => 1080,
             'height' => 1920,
+            'cover' => [
+                'width' => 280,
+                'height' => 280,
+                'radius' => 16,
+                'x' => 50,
+                'y' => 50,
+            ],
+            'quotes' => [
+                'width' => 256,
+                'height' => 256,
+                'x' => 75,
+                'y' => 520,
+            ],
+            'episodeTitle' => [
+                'fontsize' => 42,
+                'x' => 360,
+                'y' => 110,
+                'lines' => 3,
+                'lineWidth' => 32,
+                'leading' => 20,
+            ],
+            'podcastTitle' => [
+                'fontsize' => 32,
+                'x' => 360,
+                'y' => 55,
+            ],
+            'episodeNumbering' => [
+                'fontsize' => 28,
+                'paddingX' => 0,
+                'paddingY' => 10,
+                'x' => 50,
+                'y' => 330,
+            ],
+            'timestamp' => [
+                'fontsize' => 48,
+                'padding' => 10,
+                'x' => 735,
+                'y' => 1800,
+            ],
+            'progressbar' => [
+                'height' => 10,
+            ],
+            'soundwaves' => [
+                'width' => 54,
+                'height' => 96,
+                'rescaleWidth' => 1080,
+                'rescaleHeight' => 1920,
+                'x' => 0,
+                'y' => 960,
+                'mask' => APPPATH . 'Libraries/MediaClipper/soundwaves-mask-portrait.png',
+            ],
+            'subtitles' => [
+                'fontsize' => 18,
+                'marginL' => 60,
+                'marginR' => 20,
+                'marginV' => 97,
+            ],
         ],
         'squared' => [
             'width' => 1200,
             'height' => 1200,
+            'cover' => [
+                'width' => 200,
+                'height' => 200,
+                'radius' => 16,
+                'x' => 40,
+                'y' => 40,
+            ],
+            'quotes' => [
+                'width' => 200,
+                'height' => 200,
+                'x' => 85,
+                'y' => 320,
+            ],
+            'episodeTitle' => [
+                'fontsize' => 36,
+                'x' => 260,
+                'y' => 90,
+                'lines' => 2,
+                'lineWidth' => 38,
+                'leading' => 20,
+            ],
+            'podcastTitle' => [
+                'fontsize' => 28,
+                'x' => 260,
+                'y' => 50,
+            ],
+            'episodeNumbering' => [
+                'fontsize' => 20,
+                'paddingX' => 0,
+                'paddingY' => 10,
+                'x' => 40,
+                'y' => 240,
+            ],
+            'timestamp' => [
+                'fontsize' => 48,
+                'padding' => 10,
+                'x' => 855,
+                'y' => 1070,
+            ],
+            'progressbar' => [
+                'height' => 10,
+            ],
+            'soundwaves' => [
+                'width' => 60,
+                'height' => 60,
+                'rescaleWidth' => 1200,
+                'rescaleHeight' => 1200,
+                'x' => 0,
+                'y' => 600,
+                'mask' => APPPATH . 'Libraries/MediaClipper/soundwaves-mask-squared.png',
+            ],
+            'subtitles' => [
+                'fontsize' => 20,
+                'marginL' => 60,
+                'marginR' => 20,
+                'marginV' => 98,
+            ],
         ],
     ];
 }
diff --git a/app/Libraries/MediaClipper/VideoClip.php b/app/Libraries/MediaClipper/VideoClip.php
index 257522df20a46d504c0af0e8832de30fd74e37fa..e2f7ad6e218662caecc11a6ff3ac4d6b30bb9329 100644
--- a/app/Libraries/MediaClipper/VideoClip.php
+++ b/app/Libraries/MediaClipper/VideoClip.php
@@ -28,6 +28,12 @@ class VideoClip
 
     protected float $duration;
 
+    protected string $audioInput;
+
+    protected string $episodeCoverPath;
+
+    protected ?string $subtitlesInput = null;
+
     protected string $soundbiteOutput;
 
     protected string $subtitlesClipOutput;
@@ -65,27 +71,30 @@ class VideoClip
 
         helper('media');
 
+        $this->audioInput = media_path($this->episode->audio_file_path);
+        $this->episodeCoverPath = media_path($this->episode->cover->path);
+        if ($this->episode->transcript_file_path !== null) {
+            $this->subtitlesInput = media_path($this->episode->transcript_file_path);
+        }
+
         $podcastFolder = media_path("podcasts/{$this->episode->podcast->handle}");
 
         $this->soundbiteOutput = $podcastFolder . "/{$this->episode->slug}-soundbite-{$this->start}-to-{$this->end}.mp3";
         $this->subtitlesClipOutput = $podcastFolder . "/{$this->episode->slug}-subtitles-clip-{$this->start}-to-{$this->end}.srt";
         $this->videoClipBgOutput = $podcastFolder . "/{$this->episode->slug}-clip-bg-{$this->format}.png";
-        $this->videoClipOutput = $podcastFolder . "/{$this->episode->slug}-clip-{$this->start}-to-{$this->end}.mp4";
+        $this->videoClipOutput = $podcastFolder . "/{$this->episode->slug}-clip-{$this->start}-to-{$this->end}-{$this->format}.mp4";
     }
 
     public function soundbite(): void
     {
-        $audioInput = media_path($this->episode->audio_file_path);
-        $soundbiteCmd = "ffmpeg -y -ss {$this->start} -t {$this->duration} -i {$audioInput} {$this->soundbiteOutput}";
+        $soundbiteCmd = "ffmpeg -y -ss {$this->start} -t {$this->duration} -i {$this->audioInput} {$this->soundbiteOutput}";
         exec($soundbiteCmd);
     }
 
     public function subtitlesClip(): void
     {
-        if ($this->episode->transcript_file_path !== null) {
-            $srtFileInput = media_path($this->episode->transcript_file_path);
-
-            $subtitleClipCmd = "ffmpeg -y -i {$srtFileInput} -ss {$this->start} -t {$this->duration} {$this->subtitlesClipOutput}";
+        if ($this->subtitlesInput) {
+            $subtitleClipCmd = "ffmpeg -y -i {$this->subtitlesInput} -ss {$this->start} -t {$this->duration} {$this->subtitlesClipOutput}";
             exec($subtitleClipCmd);
         }
     }
@@ -181,7 +190,7 @@ class VideoClip
             return false;
         }
 
-        $episodeCover = imagecreatefromjpeg(media_path($this->episode->cover->path));
+        $episodeCover = imagecreatefromjpeg($this->episodeCoverPath);
         if (! $episodeCover) {
             return false;
         }
@@ -431,11 +440,20 @@ class VideoClip
             $lines = explode(PHP_EOL, $text);
             foreach ($lines as $i => $line) {
                 // Print line On Image
-                imagettftext($image, $fontsize, 0, $x, $y + (($fontsize + $leading) * $i), $white, $fontPath, $line);
+                imagettftext(
+                    $image,
+                    $fontsize,
+                    0,
+                    $x,
+                    $y + $fontsize + (($fontsize + $leading) * $i),
+                    $white,
+                    $fontPath,
+                    $line
+                );
             }
         } else {
             // Print Text On Image
-            imagettftext($image, $fontsize, 0, $x, $y, $white, $fontPath, $text);
+            imagettftext($image, $fontsize, 0, $x, $y + $fontsize, $white, $fontPath, $text);
         }
 
         return true;
@@ -465,12 +483,12 @@ class VideoClip
             return false;
         }
 
-        $x1 = $x + $bbox['left'];
-        $y1 = $y + $bbox['top'];
-        $x2 = $x + $bbox['width'] + $paddingX;
-        $y2 = $y + $bbox['height'] + $paddingY;
+        $x1 = $x + $bbox['left'] + $paddingX;
+        $y1 = $y + $bbox['top'] + $paddingY;
+        $x2 = $x + $bbox['width'] + ($paddingX * 2);
+        $y2 = $y + $bbox['height'] + ($paddingY * 2);
 
-        imagefilledrectangle($image, $x - $paddingX, $y - $paddingY, $x2, $y2, $bgColor);
+        imagefilledrectangle($image, $x, $y, $x2, $y2, $bgColor);
         imagettftext($image, $fontsize, 0, $x1, $y1, $white, $fontPath, $text);
 
         return true;
diff --git a/app/Libraries/MediaClipper/waves-mask.png b/app/Libraries/MediaClipper/soundwaves-mask-landscape.png
similarity index 100%
rename from app/Libraries/MediaClipper/waves-mask.png
rename to app/Libraries/MediaClipper/soundwaves-mask-landscape.png
diff --git a/app/Libraries/MediaClipper/soundwaves-mask-portrait.png b/app/Libraries/MediaClipper/soundwaves-mask-portrait.png
new file mode 100644
index 0000000000000000000000000000000000000000..67a2bfb0ad8b4ceab5fe8bbfcc01523c17422e33
Binary files /dev/null and b/app/Libraries/MediaClipper/soundwaves-mask-portrait.png differ
diff --git a/app/Libraries/MediaClipper/soundwaves-mask-squared.png b/app/Libraries/MediaClipper/soundwaves-mask-squared.png
new file mode 100644
index 0000000000000000000000000000000000000000..4c64e69a452b1b710b0feaf2dfe56b75351c4fa3
Binary files /dev/null and b/app/Libraries/MediaClipper/soundwaves-mask-squared.png differ
diff --git a/modules/Admin/Controllers/ClipsController.php b/modules/Admin/Controllers/ClipsController.php
index f93ffead1290b0b3a58e303835ec5ace5e7eac4e..cfb9eb4d2d88f0cc9ed73e1a6f0fa9554e069207 100644
--- a/modules/Admin/Controllers/ClipsController.php
+++ b/modules/Admin/Controllers/ClipsController.php
@@ -73,10 +73,11 @@ class ClipsController extends BaseController
 
     public function generateVideoClip(): RedirectResponse
     {
+        // TODO: add end_time greater than start_time, with minimum ?
         $rules = [
-            'format' => 'required',
-            'start_time' => 'required',
-            'end_time' => 'required',
+            'format' => 'required|in_list[landscape,portrait,squared]',
+            'start_time' => 'required|numeric',
+            'end_time' => 'required|numeric|differs[start_time]',
         ];
 
         if (! $this->validate($rules)) {
@@ -86,15 +87,11 @@ class ClipsController extends BaseController
                 ->with('errors', $this->validator->getErrors());
         }
 
-        // TODO: start and end
-
-        helper('media');
-
         $clipper = new VideoClip(
             $this->episode,
             (float) $this->request->getPost('start_time'),
             (float) $this->request->getPost('end_time',),
-            'landscape'
+            $this->request->getPost('format'),
         );
         $clipper->generate();
 
diff --git a/themes/cp_admin/episode/video_clips.php b/themes/cp_admin/episode/video_clips.php
index e64144c9cd7131fbb9bb0767d90fcc13b42c4bdc..314b060cbed9bad86c9ca750181ee69573d6ef56 100644
--- a/themes/cp_admin/episode/video_clips.php
+++ b/themes/cp_admin/episode/video_clips.php
@@ -15,16 +15,16 @@
 <fieldset>
 <legend>Format</legend>
 <div class="mx-auto">
-    <input type="radio" name="format" value="16:9" id="landscape"/>
+    <input type="radio" name="format" value="landscape" id="landscape" checked="checked"/>
     <label for="landscape">Landscape - 16:9</label>
 </div>
 <div class="mx-auto">
-    <input type="radio" name="format" value="1:1" id="square" checked="checked"/>
-    <label for="square">Square - 1:1</label>
+    <input type="radio" name="format" value="portrait" id="portrait"/>
+    <label for="portrait">Portrait - 9:16</label>
 </div>
 <div class="mx-auto">
-    <input type="radio" name="format" value="9:16" id="portrait"/>
-    <label for="portrait">Portrait - 9:16</label>
+    <input type="radio" name="format" value="squared" id="square"/>
+    <label for="square">Square - 1:1</label>
 </div>
 </fieldset>