Showing
4 changed files
with
238 additions
and
30 deletions
| ... | @@ -172,22 +172,42 @@ class VideoTempController extends AdminController | ... | @@ -172,22 +172,42 @@ class VideoTempController extends AdminController |
| 172 | $form->checkbox('components','组件') | 172 | $form->checkbox('components','组件') |
| 173 | ->when('every_poem', function (Form\BlockForm $form) { | 173 | ->when('every_poem', function (Form\BlockForm $form) { |
| 174 | $form->select('pos_every_poem', '每日位置')->options(VideoTemp::POSITION_OPTIONS); | 174 | $form->select('pos_every_poem', '每日位置')->options(VideoTemp::POSITION_OPTIONS); |
| 175 | + $form->number('font_size_every_poem','容器宽度')->default(6)->help('范围为1-9,默认容器外边距为1/20'); | ||
| 176 | + $form->text('text_color_every_poem','字体颜色')->default('white'); | ||
| 177 | + $form->text('text_bg_color_every_poem','背景颜色'); | ||
| 178 | + $form->rate('opacity_every_poem','透明度')->default(50)->help('范围为0-100,100表示不透明,0表示完全透明'); | ||
| 175 | $form->divider(); | 179 | $form->divider(); |
| 176 | }) | 180 | }) |
| 177 | ->when('one_poem', function (Form\BlockForm $form) { | 181 | ->when('one_poem', function (Form\BlockForm $form) { |
| 178 | $form->select('pos_one_poem', '一言位置')->options(VideoTemp::POSITION_OPTIONS); | 182 | $form->select('pos_one_poem', '一言位置')->options(VideoTemp::POSITION_OPTIONS); |
| 183 | + $form->number('font_size_one_poem','容器宽度')->default(6)->help('范围为1-9,默认容器外边距为1/20'); | ||
| 184 | + $form->text('text_color_one_poem','字体颜色')->default('white'); | ||
| 185 | + $form->text('text_bg_color_one_poem','背景颜色'); | ||
| 186 | + $form->rate('opacity_one_poem','透明度')->default(50)->help('范围为0-100,100表示不透明,0表示完全透明'); | ||
| 179 | $form->divider(); | 187 | $form->divider(); |
| 180 | }) | 188 | }) |
| 181 | ->when('weather', function (Form\BlockForm $form) { | 189 | ->when('weather', function (Form\BlockForm $form) { |
| 182 | $form->select('pos_weather', '天气位置')->options(VideoTemp::POSITION_OPTIONS); | 190 | $form->select('pos_weather', '天气位置')->options(VideoTemp::POSITION_OPTIONS); |
| 191 | + $form->number('font_size_weather','容器宽度')->default(6)->help('范围为1-9,默认容器外边距为1/20'); | ||
| 192 | + $form->text('text_color_weather','字体颜色')->default('white'); | ||
| 193 | + $form->text('text_bg_color_weather','背景颜色'); | ||
| 194 | + $form->rate('opacity_weather','透明度')->default(50)->help('范围为0-100,100表示不透明,0表示完全透明'); | ||
| 183 | $form->divider(); | 195 | $form->divider(); |
| 184 | }) | 196 | }) |
| 185 | ->when('date', function (Form\BlockForm $form) { | 197 | ->when('date', function (Form\BlockForm $form) { |
| 186 | $form->select('pos_date', '日期位置')->options(VideoTemp::POSITION_OPTIONS); | 198 | $form->select('pos_date', '日期位置')->options(VideoTemp::POSITION_OPTIONS); |
| 199 | + $form->number('font_size_date','容器宽度')->default(6)->help('范围为1-9,默认容器外边距为1/20'); | ||
| 200 | + $form->text('text_color_date','字体颜色')->default('white'); | ||
| 201 | + $form->text('text_bg_color_date','背景颜色'); | ||
| 202 | + $form->rate('opacity_date','透明度')->default(50)->help('范围为0-100,100表示不透明,0表示完全透明'); | ||
| 187 | $form->divider(); | 203 | $form->divider(); |
| 188 | }) | 204 | }) |
| 189 | ->when('feel', function (Form\BlockForm $form) { | 205 | ->when('feel', function (Form\BlockForm $form) { |
| 190 | $form->select('pos_feel', '有感位置')->options(VideoTemp::POSITION_OPTIONS); | 206 | $form->select('pos_feel', '有感位置')->options(VideoTemp::POSITION_OPTIONS); |
| 207 | + $form->number('font_size_feel','容器宽度')->default(6)->help('范围为1-9,默认容器外边距为1/20'); | ||
| 208 | + $form->text('text_color_feel','字体颜色')->default('white'); | ||
| 209 | + $form->text('text_bg_color_feel','背景颜色'); | ||
| 210 | + $form->rate('opacity_feel','透明度')->default(50)->help('范围为0-100,100表示不透明,0表示完全透明'); | ||
| 191 | $form->divider(); | 211 | $form->divider(); |
| 192 | }) | 212 | }) |
| 193 | ->default(['one_poem','weather','date']) | 213 | ->default(['one_poem','weather','date']) |
| ... | @@ -230,7 +250,11 @@ class VideoTempController extends AdminController | ... | @@ -230,7 +250,11 @@ class VideoTempController extends AdminController |
| 230 | Component::query()->create([ | 250 | Component::query()->create([ |
| 231 | 'temp_id' => $vide_temp->id, | 251 | 'temp_id' => $vide_temp->id, |
| 232 | 'name' => $component, | 252 | 'name' => $component, |
| 233 | - 'position' => $all['pos_' . $component] | 253 | + 'position' => $all['pos_' . $component], |
| 254 | + 'font_size' => $all['font_size_' . $component], | ||
| 255 | + 'text_color' => $all['text_color_' . $component], | ||
| 256 | + 'text_bg_color' => $all['text_bg_color_' . $component], | ||
| 257 | + 'opacity' => $all['opacity_' . $component], | ||
| 234 | ]); | 258 | ]); |
| 235 | } | 259 | } |
| 236 | } | 260 | } | ... | ... |
| ... | @@ -4,8 +4,11 @@ namespace App\Console\Commands; | ... | @@ -4,8 +4,11 @@ namespace App\Console\Commands; |
| 4 | 4 | ||
| 5 | use App\Models\AdminMakeVideo; | 5 | use App\Models\AdminMakeVideo; |
| 6 | use App\Models\Immerse; | 6 | use App\Models\Immerse; |
| 7 | +use App\Models\VideoTemp; | ||
| 8 | +use Carbon\Carbon; | ||
| 7 | use Illuminate\Console\Command; | 9 | use Illuminate\Console\Command; |
| 8 | use Illuminate\Support\Facades\Storage; | 10 | use Illuminate\Support\Facades\Storage; |
| 11 | +use voku\helper\ASCII; | ||
| 9 | 12 | ||
| 10 | class DevFFmpeg extends Command | 13 | class DevFFmpeg extends Command |
| 11 | { | 14 | { |
| ... | @@ -52,6 +55,9 @@ class DevFFmpeg extends Command | ... | @@ -52,6 +55,9 @@ class DevFFmpeg extends Command |
| 52 | $is_bgm = false; | 55 | $is_bgm = false; |
| 53 | $bgm = $path . 'bgm.aac'; | 56 | $bgm = $path . 'bgm.aac'; |
| 54 | 57 | ||
| 58 | + | ||
| 59 | + $string = $this->getTextContentString(); | ||
| 60 | + | ||
| 55 | // 1.getmediainfo 记录时长,音频视频取最长。 | 61 | // 1.getmediainfo 记录时长,音频视频取最长。 |
| 56 | $cmd = $this->ffprobe . ' -v quiet -print_format json -show_format -show_streams ' . escapeshellarg($file); | 62 | $cmd = $this->ffprobe . ' -v quiet -print_format json -show_format -show_streams ' . escapeshellarg($file); |
| 57 | $output = $this->execmd($cmd); | 63 | $output = $this->execmd($cmd); |
| ... | @@ -158,16 +164,9 @@ class DevFFmpeg extends Command | ... | @@ -158,16 +164,9 @@ class DevFFmpeg extends Command |
| 158 | ' -i ' . escapeshellarg($path . 'logo.png'). | 164 | ' -i ' . escapeshellarg($path . 'logo.png'). |
| 159 | $audio_input. | 165 | $audio_input. |
| 160 | ' -filter_complex "[0:0] ' . | 166 | ' -filter_complex "[0:0] ' . |
| 161 | - 'drawtext="'. | 167 | + $string. |
| 162 | - 'fontfile=' . escapeshellarg($path . 'arialuni.ttf') . ':' . | 168 | + '[text];[text]'. |
| 163 | - 'text=' . escapeshellarg($content) . ':'. | 169 | + '[2:v]overlay=20:20[water];[water]'.$audio_filter.'[1:0][1:1] concat=n=2:v=1:a=1[v][a]" '. |
| 164 | - 'fontsize='.$font_size.':'. | ||
| 165 | - 'fontcolor=white@1.0:'. | ||
| 166 | - 'x=' . escapeshellarg('(w-text_w)/2') . ':' . | ||
| 167 | - 'y=' . escapeshellarg('(h-text_h)/2') . ':' . | ||
| 168 | - 'box=1:boxcolor=0xd0cdcc@0.5'. | ||
| 169 | - '" [text];'. | ||
| 170 | - '[text] [2:v]overlay=20:20[water];[water]'.$audio_filter.'[1:0][1:1] concat=n=2:v=1:a=1[v][a]" '. | ||
| 171 | ' -map [v] -map [a]'. | 170 | ' -map [v] -map [a]'. |
| 172 | ' -c:v libx264 -bt 256k -r 25' . | 171 | ' -c:v libx264 -bt 256k -r 25' . |
| 173 | ' -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' . | 172 | ' -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' . |
| ... | @@ -737,5 +736,98 @@ class DevFFmpeg extends Command | ... | @@ -737,5 +736,98 @@ class DevFFmpeg extends Command |
| 737 | return false; | 736 | return false; |
| 738 | } | 737 | } |
| 739 | } | 738 | } |
| 739 | + | ||
| 740 | + public function getTextContentString() | ||
| 741 | + { | ||
| 742 | + $components = VideoTemp::query()->find(6)->components()->get(); | ||
| 743 | + | ||
| 744 | + $font = Storage::disk('public')->path('ffmpeg/arialuni.ttf'); | ||
| 745 | + | ||
| 746 | + $drawtext = ''; | ||
| 747 | + | ||
| 748 | + foreach ($components as $component) { | ||
| 749 | + switch ($component->name){ | ||
| 750 | + case 'one_poem': | ||
| 751 | + $content = '题破山寺后禅院' . "\t" . ' -- 常建' . PHP_EOL . | ||
| 752 | + '清晨入古寺,初日照高林。' . PHP_EOL . | ||
| 753 | + '曲径通幽处,禅房花木深。' . PHP_EOL . | ||
| 754 | + '山光悦鸟性,潭影空人心。' . PHP_EOL . | ||
| 755 | + '万籁此都寂,但余钟磬音。' . PHP_EOL ; | ||
| 756 | + | ||
| 757 | + $text_color = $component->text_color ?? 'white'; | ||
| 758 | + $text_bg_color = $component->text_bg_color ?? '0xd0cdcc'; | ||
| 759 | + $opacity = $component->opacity ? $component->opacity / 100 : '0.5'; | ||
| 760 | + | ||
| 761 | + $drawtext .= 'drawtext="'. | ||
| 762 | + 'fontfile=' . escapeshellarg($font) . ':' . | ||
| 763 | + 'text=' . escapeshellarg($content) . ':' . | ||
| 764 | + 'fontsize=' . $component->font_size . ':' . | ||
| 765 | + 'fontcolor=' . $text_color . '@1.0:' . | ||
| 766 | + 'x=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][0]) . ':' . | ||
| 767 | + 'y=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][1]) . ':' . | ||
| 768 | + 'box=1:boxcolor=' . $text_bg_color . '@' . $opacity . '", '; | ||
| 769 | + | ||
| 770 | + break; | ||
| 771 | + case 'every_poem': | ||
| 772 | + break; | ||
| 773 | + case 'weather': | ||
| 774 | + $content = '多云'; | ||
| 775 | + $text_color = $component->text_color ?? 'white'; | ||
| 776 | + $text_bg_color = $component->text_bg_color ?? '0xd0cdcc'; | ||
| 777 | + $opacity = $component->opacity ? $component->opacity / 100 : '0.5'; | ||
| 778 | + | ||
| 779 | + $drawtext .= 'drawtext="'. | ||
| 780 | + 'fontfile=' . escapeshellarg($font) . ':' . | ||
| 781 | + 'text=' . escapeshellarg($content) . ':' . | ||
| 782 | + 'fontsize=' . $component->font_size . ':' . | ||
| 783 | + 'fontcolor=' . $text_color . '@1.0:' . | ||
| 784 | + 'x=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][0]) . ':' . | ||
| 785 | + 'y=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][1]) . ':' . | ||
| 786 | + 'box=1:boxcolor=' . $text_bg_color . '@' . $opacity . '", '; | ||
| 787 | + | ||
| 788 | + break; | ||
| 789 | + case 'date': | ||
| 790 | + $content = Carbon::now()->format('Y年m月d日H时'); | ||
| 791 | + $text_color = $component->text_color ?? 'white'; | ||
| 792 | + $text_bg_color = $component->text_bg_color ?? '0xd0cdcc'; | ||
| 793 | + $opacity = $component->opacity ? $component->opacity / 100 : '0.5'; | ||
| 794 | + | ||
| 795 | + $drawtext .= 'drawtext="'. | ||
| 796 | + 'fontfile=' . escapeshellarg($font) . ':' . | ||
| 797 | + 'text=' . escapeshellarg($content) . ':' . | ||
| 798 | + 'fontsize=' . $component->font_size . ':' . | ||
| 799 | + 'fontcolor=' . $text_color . '@1.0:' . | ||
| 800 | + 'x=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][0]) . ':' . | ||
| 801 | + 'y=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][1]) . ':' . | ||
| 802 | + 'box=1:boxcolor=' . $text_bg_color . '@' . $opacity . '", '; | ||
| 803 | + break; | ||
| 804 | + case 'feel': | ||
| 805 | + $content = '测试有感文本'; | ||
| 806 | + $text_color = $component->text_color ?? 'white'; | ||
| 807 | + $text_bg_color = $component->text_bg_color ?? '0xd0cdcc'; | ||
| 808 | + $opacity = $component->opacity ? $component->opacity / 100 : '0.5'; | ||
| 809 | + | ||
| 810 | + $drawtext .= 'drawtext="'. | ||
| 811 | + 'fontfile=' . escapeshellarg($font) . ':' . | ||
| 812 | + 'text=' . escapeshellarg($content) . ':' . | ||
| 813 | + 'fontsize=' . $component->font_size . ':' . | ||
| 814 | + 'fontcolor=' . $text_color . '@1.0:' . | ||
| 815 | + 'x=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][0]) . ':' . | ||
| 816 | + 'y=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][1]) . ':' . | ||
| 817 | + 'box=1:boxcolor=' . $text_bg_color . '@' . $opacity . '", '; | ||
| 818 | + break; | ||
| 819 | + } | ||
| 820 | + } | ||
| 821 | + | ||
| 822 | + return rtrim($drawtext,', '); | ||
| 823 | + } | ||
| 740 | } | 824 | } |
| 741 | 825 | ||
| 826 | + | ||
| 827 | + | ||
| 828 | + | ||
| 829 | + | ||
| 830 | + | ||
| 831 | + | ||
| 832 | + | ||
| 833 | + | ... | ... |
| ... | @@ -4,6 +4,8 @@ namespace App\Jobs; | ... | @@ -4,6 +4,8 @@ namespace App\Jobs; |
| 4 | 4 | ||
| 5 | use App\Models\AdminMakeVideo; | 5 | use App\Models\AdminMakeVideo; |
| 6 | use App\Models\Immerse; | 6 | use App\Models\Immerse; |
| 7 | +use App\Models\VideoTemp; | ||
| 8 | +use Carbon\Carbon; | ||
| 7 | use Illuminate\Bus\Queueable; | 9 | use Illuminate\Bus\Queueable; |
| 8 | use Illuminate\Contracts\Queue\ShouldBeUnique; | 10 | use Illuminate\Contracts\Queue\ShouldBeUnique; |
| 9 | use Illuminate\Contracts\Queue\ShouldQueue; | 11 | use Illuminate\Contracts\Queue\ShouldQueue; |
| ... | @@ -25,6 +27,8 @@ class MakeVideo implements ShouldQueue | ... | @@ -25,6 +27,8 @@ class MakeVideo implements ShouldQueue |
| 25 | 27 | ||
| 26 | protected $ffplay; | 28 | protected $ffplay; |
| 27 | 29 | ||
| 30 | + protected $width; | ||
| 31 | + | ||
| 28 | /** | 32 | /** |
| 29 | * Create a new job instance. | 33 | * Create a new job instance. |
| 30 | * @param AdminMakeVideo $adminMakeVideo | 34 | * @param AdminMakeVideo $adminMakeVideo |
| ... | @@ -114,14 +118,14 @@ class MakeVideo implements ShouldQueue | ... | @@ -114,14 +118,14 @@ class MakeVideo implements ShouldQueue |
| 114 | $end_wallpaper = Storage::disk('public')->path('ffmpeg') . "/end_wallpaper.png"; | 118 | $end_wallpaper = Storage::disk('public')->path('ffmpeg') . "/end_wallpaper.png"; |
| 115 | $thumbnail = Storage::disk('public')->path('ffmpeg') . "/thumbnail.png"; | 119 | $thumbnail = Storage::disk('public')->path('ffmpeg') . "/thumbnail.png"; |
| 116 | $font = Storage::disk('public')->path('ffmpeg') . "/arialuni.ttf"; | 120 | $font = Storage::disk('public')->path('ffmpeg') . "/arialuni.ttf"; |
| 117 | - $signature = "一言官方出品"; | 121 | + $signature = "一言 · 官方出品"; |
| 118 | 122 | ||
| 119 | // 生成贴纸和签名 | 123 | // 生成贴纸和签名 |
| 120 | $end_wallpaper = $this->wallpaperWithSignature($end_wallpaper, $thumbnail, $signature, $font); | 124 | $end_wallpaper = $this->wallpaperWithSignature($end_wallpaper, $thumbnail, $signature, $font); |
| 121 | 125 | ||
| 122 | // 截取最后一帧 | 126 | // 截取最后一帧 |
| 123 | $last_frame_video = $this->getTempPath(); | 127 | $last_frame_video = $this->getTempPath(); |
| 124 | - $width = $media_info['streams'][0]['width']; | 128 | + $this->width = $width = $media_info['streams'][0]['width']; |
| 125 | $height = $media_info['streams'][0]['height']; | 129 | $height = $media_info['streams'][0]['height']; |
| 126 | $size = $width . 'x' . $height; | 130 | $size = $width . 'x' . $height; |
| 127 | $time_length = 0.7; | 131 | $time_length = 0.7; |
| ... | @@ -138,12 +142,9 @@ class MakeVideo implements ShouldQueue | ... | @@ -138,12 +142,9 @@ class MakeVideo implements ShouldQueue |
| 138 | $signature_y = -20; | 142 | $signature_y = -20; |
| 139 | $animate = $this->makeAnimate($last_frame_video, $end_wallpaper, '', $signature_x, $signature_y, $font); | 143 | $animate = $this->makeAnimate($last_frame_video, $end_wallpaper, '', $signature_x, $signature_y, $font); |
| 140 | 144 | ||
| 141 | - $font_size = ceil($width / 16); | 145 | + $this->getTextContentString($adminMakeVideo); |
| 142 | - $content = $adminMakeVideo->poem->content . PHP_EOL; | ||
| 143 | - $content_position = $adminMakeVideo->getContentPosition(); | ||
| 144 | - $watermark = Storage::disk('public')->path('ffmpeg/LOGO_eng.png'); | ||
| 145 | - $font_family = Storage::disk('public')->path('ffmpeg/arialuni.ttf'); | ||
| 146 | 146 | ||
| 147 | + $watermark = Storage::disk('public')->path('ffmpeg/LOGO_eng.png'); | ||
| 147 | 148 | ||
| 148 | $video = $this->getTempPath('.mp4',false); | 149 | $video = $this->getTempPath('.mp4',false); |
| 149 | $cmd = $this->ffmpeg . ' -y '. | 150 | $cmd = $this->ffmpeg . ' -y '. |
| ... | @@ -152,15 +153,8 @@ class MakeVideo implements ShouldQueue | ... | @@ -152,15 +153,8 @@ class MakeVideo implements ShouldQueue |
| 152 | ' -i ' . escapeshellarg($watermark). | 153 | ' -i ' . escapeshellarg($watermark). |
| 153 | $audio_input . | 154 | $audio_input . |
| 154 | ' -filter_complex "[0:0] ' . | 155 | ' -filter_complex "[0:0] ' . |
| 155 | - 'drawtext="'. | 156 | + $this->getTextContentString(). |
| 156 | - 'fontfile=' . escapeshellarg($font_family) . ':' . | 157 | + '[text];[text]'. |
| 157 | - 'text=' . escapeshellcmd($content) . ':'. | ||
| 158 | - 'fontsize='.$font_size.':'. | ||
| 159 | - 'fontcolor=white@1.0:'. | ||
| 160 | - 'x=' . escapeshellarg($content_position[0]) . ':' . | ||
| 161 | - 'y=' . escapeshellarg($content_position[1]) . ':' . | ||
| 162 | - 'box=1:boxcolor=0xd0cdcc@0.5'. | ||
| 163 | - '" [text];'. | ||
| 164 | '[text] [2:v]overlay=20:20[water];[water]' . $audio_filter . '[1:0][1:1] concat=n=2:v=1:a=1[v][a]" ' . | 158 | '[text] [2:v]overlay=20:20[water];[water]' . $audio_filter . '[1:0][1:1] concat=n=2:v=1:a=1[v][a]" ' . |
| 165 | ' -map [v] -map [a]'. | 159 | ' -map [v] -map [a]'. |
| 166 | ' -c:v libx264 -bt 256k -r 25' . | 160 | ' -c:v libx264 -bt 256k -r 25' . |
| ... | @@ -600,4 +594,102 @@ class MakeVideo implements ShouldQueue | ... | @@ -600,4 +594,102 @@ class MakeVideo implements ShouldQueue |
| 600 | return false; | 594 | return false; |
| 601 | } | 595 | } |
| 602 | } | 596 | } |
| 597 | + | ||
| 598 | + public function getTextContentString() | ||
| 599 | + { | ||
| 600 | + $components = $this->adminMakeVideo->temp->components->get(); | ||
| 601 | + | ||
| 602 | + $font = Storage::disk('public')->path('ffmpeg/arialuni.ttf'); | ||
| 603 | + | ||
| 604 | + $drawtext = ''; | ||
| 605 | + | ||
| 606 | + foreach ($components as $component) { | ||
| 607 | + switch ($component->name){ | ||
| 608 | + case 'one_poem': | ||
| 609 | + $content = $this->adminMakeVideo->poem->content . PHP_EOL; | ||
| 610 | + | ||
| 611 | + $text_color = $component->text_color ?? 'white'; | ||
| 612 | + $text_bg_color = $component->text_bg_color ?? '0xd0cdcc'; | ||
| 613 | + $opacity = $component->opacity ? $component->opacity / 100 : '0.5'; | ||
| 614 | + | ||
| 615 | + $drawtext .= 'drawtext="'. | ||
| 616 | + 'fontfile=' . escapeshellarg($font) . ':' . | ||
| 617 | + 'text=' . escapeshellcmd($content) . ':' . | ||
| 618 | + 'fontsize=' . $this->calcFontSize($component->font_size,$content) . ':' . | ||
| 619 | + 'fontcolor=' . $text_color . '@1.0:' . | ||
| 620 | + 'x=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][0]) . ':' . | ||
| 621 | + 'y=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][1]) . ':' . | ||
| 622 | + 'box=1:boxcolor=' . $text_bg_color . '@' . $opacity . '", '; | ||
| 623 | + | ||
| 624 | + break; | ||
| 625 | + case 'every_poem': | ||
| 626 | + break; | ||
| 627 | + case 'weather': | ||
| 628 | + $content = '多云'; | ||
| 629 | + $text_color = $component->text_color ?? 'white'; | ||
| 630 | + $text_bg_color = $component->text_bg_color ?? '0xd0cdcc'; | ||
| 631 | + $opacity = $component->opacity ? $component->opacity / 100 : '0.5'; | ||
| 632 | + | ||
| 633 | + $drawtext .= 'drawtext="'. | ||
| 634 | + 'fontfile=' . escapeshellarg($font) . ':' . | ||
| 635 | + 'text=' . escapeshellarg($content) . ':' . | ||
| 636 | + 'fontsize=' . $this->calcFontSize($component->font_size,$content) . ':' . | ||
| 637 | + 'fontcolor=' . $text_color . '@1.0:' . | ||
| 638 | + 'x=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][0]) . ':' . | ||
| 639 | + 'y=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][1]) . ':' . | ||
| 640 | + 'box=1:boxcolor=' . $text_bg_color . '@' . $opacity . '", '; | ||
| 641 | + | ||
| 642 | + break; | ||
| 643 | + case 'date': | ||
| 644 | + $content = Carbon::now()->format('Y年m月d日H时'); | ||
| 645 | + $text_color = $component->text_color ?? 'white'; | ||
| 646 | + $text_bg_color = $component->text_bg_color ?? '0xd0cdcc'; | ||
| 647 | + $opacity = $component->opacity ? $component->opacity / 100 : '0.5'; | ||
| 648 | + | ||
| 649 | + $drawtext .= 'drawtext="'. | ||
| 650 | + 'fontfile=' . escapeshellarg($font) . ':' . | ||
| 651 | + 'text=' . escapeshellarg($content) . ':' . | ||
| 652 | + 'fontsize=' . $this->calcFontSize($component->font_size,$content) . ':' . | ||
| 653 | + 'fontcolor=' . $text_color . '@1.0:' . | ||
| 654 | + 'x=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][0]) . ':' . | ||
| 655 | + 'y=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][1]) . ':' . | ||
| 656 | + 'box=1:boxcolor=' . $text_bg_color . '@' . $opacity . '", '; | ||
| 657 | + break; | ||
| 658 | + case 'feel': | ||
| 659 | + $content = $this->adminMakeVideo->feel; | ||
| 660 | + $text_color = $component->text_color ?? 'white'; | ||
| 661 | + $text_bg_color = $component->text_bg_color ?? '0xd0cdcc'; | ||
| 662 | + $opacity = $component->opacity ? $component->opacity / 100 : '0.5'; | ||
| 663 | + | ||
| 664 | + $drawtext .= 'drawtext="'. | ||
| 665 | + 'fontfile=' . escapeshellarg($font) . ':' . | ||
| 666 | + 'text=' . escapeshellarg($content) . ':' . | ||
| 667 | + 'fontsize=' . $this->calcFontSize($component->font_size,$content) . ':' . | ||
| 668 | + 'fontcolor=' . $text_color . '@1.0:' . | ||
| 669 | + 'x=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][0]) . ':' . | ||
| 670 | + 'y=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][1]) . ':' . | ||
| 671 | + 'box=1:boxcolor=' . $text_bg_color . '@' . $opacity . '", '; | ||
| 672 | + break; | ||
| 673 | + } | ||
| 674 | + } | ||
| 675 | + | ||
| 676 | + return rtrim($drawtext,', '); | ||
| 677 | + } | ||
| 678 | + | ||
| 679 | + /** | ||
| 680 | + * @param $width | ||
| 681 | + * @param $content | ||
| 682 | + * @return float | ||
| 683 | + */ | ||
| 684 | + public function calcFontSize($width, $content) | ||
| 685 | + { | ||
| 686 | + $max_len = 1; | ||
| 687 | + foreach (explode("\n",$content) as $item){ | ||
| 688 | + if (mb_strlen($item) > $max_len){ | ||
| 689 | + $max_len = mb_strlen($item); | ||
| 690 | + } | ||
| 691 | + } | ||
| 692 | + | ||
| 693 | + return ceil($this->width * $width / 10 / $max_len); | ||
| 694 | + } | ||
| 603 | } | 695 | } | ... | ... |
| ... | @@ -17,9 +17,9 @@ class VideoTemp extends Model | ... | @@ -17,9 +17,9 @@ class VideoTemp extends Model |
| 17 | ]; | 17 | ]; |
| 18 | 18 | ||
| 19 | const POSITION_FFMPEG = [ | 19 | const POSITION_FFMPEG = [ |
| 20 | - 'topLeft' => [0, 0], 'topMiddle' => ['(w-text_w)/2', 0], 'topRight' => ['w-text_w', 0], | 20 | + 'topLeft' => ['0', 'text_h'], 'topMiddle' => ['(w-text_w)/2', 'text_h'], 'topRight' => ['w-text_w', 'text_h'], |
| 21 | - 'midLeft' => [0, '(h-text_h)/2'], 'midMiddle' => ['(w-text_w)/2', '(h-text_h)/2'], 'midRight' => ['w-text_w', '(h-text_h)/2'], | 21 | + 'midLeft' => ['0', '(h-text_h)/2'], 'midMiddle' => ['(w-text_w)/2', '(h-text_h)/2'], 'midRight' => ['w-text_w', '(h-text_h)/2'], |
| 22 | - 'botLeft' => [0, 'h-text_h'], 'botMiddle' => ['(w-text_w)/2', 'h-text_h'], 'botRight' => ['w-text_w', 'h-text_h'], | 22 | + 'botLeft' => ['0', 'h-text_h*2'], 'botMiddle' => ['(w-text_w)/2', 'h-text_h*2'], 'botRight' => ['w-text_w', 'h-text_h*2'], |
| 23 | ]; | 23 | ]; |
| 24 | 24 | ||
| 25 | protected $table = 'video_temp'; | 25 | protected $table = 'video_temp'; | ... | ... |
-
Please register or login to post a comment