Loading app/Libraries/MediaClipper/Config/MediaClipper.php +120 −6 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ class MediaClipper extends BaseConfig 'episodeTitle' => [ 'fontsize' => 32, 'x' => 150, 'y' => 690, 'y' => 660, 'lines' => 3, 'lineWidth' => 28, 'leading' => 20, Loading @@ -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, Loading @@ -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, Loading @@ -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, ], ], ]; } app/Libraries/MediaClipper/VideoClip.php +33 −15 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -181,7 +190,7 @@ class VideoClip return false; } $episodeCover = imagecreatefromjpeg(media_path($this->episode->cover->path)); $episodeCover = imagecreatefromjpeg($this->episodeCoverPath); if (! $episodeCover) { return false; } Loading Loading @@ -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; Loading Loading @@ -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; Loading app/Libraries/MediaClipper/waves-mask.png→app/Libraries/MediaClipper/soundwaves-mask-landscape.png (10.4 KiB) File moved. View file app/Libraries/MediaClipper/soundwaves-mask-portrait.png 0 → 100644 +12.3 KiB Loading image diff... app/Libraries/MediaClipper/soundwaves-mask-squared.png 0 → 100644 +8.38 KiB Loading image diff... Loading
app/Libraries/MediaClipper/Config/MediaClipper.php +120 −6 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ class MediaClipper extends BaseConfig 'episodeTitle' => [ 'fontsize' => 32, 'x' => 150, 'y' => 690, 'y' => 660, 'lines' => 3, 'lineWidth' => 28, 'leading' => 20, Loading @@ -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, Loading @@ -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, Loading @@ -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, ], ], ]; }
app/Libraries/MediaClipper/VideoClip.php +33 −15 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -181,7 +190,7 @@ class VideoClip return false; } $episodeCover = imagecreatefromjpeg(media_path($this->episode->cover->path)); $episodeCover = imagecreatefromjpeg($this->episodeCoverPath); if (! $episodeCover) { return false; } Loading Loading @@ -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; Loading Loading @@ -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; Loading
app/Libraries/MediaClipper/waves-mask.png→app/Libraries/MediaClipper/soundwaves-mask-landscape.png (10.4 KiB) File moved. View file