Showing
7 changed files
with
459 additions
and
86 deletions
| ... | @@ -2,6 +2,7 @@ | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | ||
| 3 | namespace App\Console\Commands; | 3 | namespace App\Console\Commands; |
| 4 | 4 | ||
| 5 | +use App\Models\AdminMakeVideo; | ||
| 5 | use Illuminate\Console\Command; | 6 | use Illuminate\Console\Command; |
| 6 | use Illuminate\Support\Facades\Storage; | 7 | use Illuminate\Support\Facades\Storage; |
| 7 | 8 | ||
| ... | @@ -44,51 +45,44 @@ class DevFFmpeg extends Command | ... | @@ -44,51 +45,44 @@ class DevFFmpeg extends Command |
| 44 | */ | 45 | */ |
| 45 | public function handle() | 46 | public function handle() |
| 46 | { | 47 | { |
| 48 | + $adminMakeVideo = AdminMakeVideo::query()->first(); | ||
| 49 | + $adminMakeVideo->video_url = Storage::disk('public')->path($adminMakeVideo->video_url); | ||
| 50 | +// $adminMakeVideo->thumbnail_url = Storage::disk('public')->path($adminMakeVideo->thumbnail_url); | ||
| 51 | + $adminMakeVideo->poem; | ||
| 52 | + $adminMakeVideo->temp->components; | ||
| 53 | + dd($adminMakeVideo->toArray()); | ||
| 54 | + | ||
| 55 | + $file = $adminMakeVideo->video_url; | ||
| 56 | +// $watermark = Storage::disk('public')->path('image/logo.jpg'); | ||
| 57 | + // 转换logo大小 | ||
| 58 | + $watermark = $this->translateLogo(Storage::disk('public')->path('image/logo.jpg')); | ||
| 59 | + $watermark_x = 20; | ||
| 60 | + $watermark_y = 20; | ||
| 61 | + $end_wallpaper = Storage::disk('public')->path('ffmpeg') . "/end_wallpaper.png"; | ||
| 62 | + $thumbnail = Storage::disk('public')->path('ffmpeg') . "/thumbnail.png"; | ||
| 63 | + $font = Storage::disk('public')->path('ffmpeg') . "/arialuni.ttf"; | ||
| 64 | + $signature = "一言"; | ||
| 65 | + $signature_x = 0; | ||
| 66 | + $signature_y = -20; | ||
| 67 | +// $content = '题破山寺后禅院' . "\t" . ' -- 常建' . PHP_EOL . | ||
| 68 | +// '清晨入古寺,初日照高林。' . PHP_EOL . | ||
| 69 | +// '曲径通幽处,禅房花木深。' . PHP_EOL . | ||
| 70 | +// '山光悦鸟性,潭影空人心。' . PHP_EOL . | ||
| 71 | +// '万籁此都寂,但余钟磬音。' . PHP_EOL ; | ||
| 72 | + $content = $adminMakeVideo->poem->content; | ||
| 73 | + | ||
| 74 | + | ||
| 75 | + // 生成贴纸和签名 | ||
| 76 | + $end_wallpaper = $this->wallpaperWithSignature($end_wallpaper, $thumbnail, $signature, $font); | ||
| 77 | + | ||
| 78 | + // 截取最后一帧 | ||
| 79 | + $last_frame_video = $this->makeLastFrameVideo($file); | ||
| 80 | + | ||
| 81 | + $animate = ''; | ||
| 82 | + if ($last_frame_video) { | ||
| 83 | + $animate = $this->makeAnimate($last_frame_video, $end_wallpaper, '', $signature_x, $signature_y, $font); | ||
| 84 | + } | ||
| 47 | 85 | ||
| 48 | -// $file = Storage::disk('public')->path('ffmpeg') . "/qinghuaci.mp4"; | ||
| 49 | -// $font = Storage::disk('public')->path('ffmpeg') . "/arialuni.ttf"; | ||
| 50 | - | ||
| 51 | - | ||
| 52 | -// $signature = '题破山寺后禅院' . "\t" . ' -- 常建' . PHP_EOL . | ||
| 53 | -// '清晨入古寺,初日照高林。' . PHP_EOL . | ||
| 54 | -// '曲径通幽处,禅房花木深。' . PHP_EOL . | ||
| 55 | -// '山光悦鸟性,潭影空人心。' . PHP_EOL . | ||
| 56 | -// '万籁此都寂,但余钟磬音。' . PHP_EOL ; | ||
| 57 | -// | ||
| 58 | -//// $cmd = $this->ffplay . ' -i ' . escapeshellarg($file) . | ||
| 59 | -//// ' -vf "'. | ||
| 60 | -//// 'drawtext='. | ||
| 61 | -//// 'fontfile=' . escapeshellarg($font) . ':'. | ||
| 62 | -//// 'text=' . escapeshellarg($signature) . ':'. | ||
| 63 | -//// 'fontsize=43:'. | ||
| 64 | -//// 'fontcolor=white@1.0:'. | ||
| 65 | -//// 'x=main_w/2' . '-260' . ':'. | ||
| 66 | -//// 'y=main_h/2' . '-20' . ':'. | ||
| 67 | -//// 'box=1:boxcolor=0xd0cdcc@0.5'. | ||
| 68 | -//// '"'; | ||
| 69 | -// $video = $this->getTempPath(); | ||
| 70 | -// $cmd = $this->ffmpeg . ' -y -i ' . escapeshellarg($file) . | ||
| 71 | -// ' -vf "'. | ||
| 72 | -// 'drawtext='. | ||
| 73 | -// 'fontfile=' . escapeshellarg($font) . ':'. | ||
| 74 | -// 'text=' . escapeshellarg($signature) . ':'. | ||
| 75 | -// 'fontsize=43:'. | ||
| 76 | -// 'fontcolor=white@1.0:'. | ||
| 77 | -// 'x=main_w/2' . '-260' . ':'. | ||
| 78 | -// 'y=main_h/2' . '-20' . ':'. | ||
| 79 | -// 'box=1:boxcolor=0xd0cdcc@0.5'. | ||
| 80 | -// '" ' . escapeshellarg($video); | ||
| 81 | -// | ||
| 82 | -// $file = $this->execmd($cmd); | ||
| 83 | -// | ||
| 84 | -//dd($file); | ||
| 85 | - | ||
| 86 | - | ||
| 87 | -$file = Storage::disk('public')->path('ffmpeg') . "/output_1646128658383.mp4"; | ||
| 88 | -$watermark = Storage::disk('public')->path('ffmpeg') . "/LOGO_eng.png"; | ||
| 89 | -$watermark_x = 20; | ||
| 90 | -$watermark_y = 20; | ||
| 91 | -$animate = Storage::disk('public')->path('ffmpeg') . "/output_16461288409938.mp4"; | ||
| 92 | 86 | ||
| 93 | $video = $this->getTempPath(); | 87 | $video = $this->getTempPath(); |
| 94 | $watermark_x = $watermark_x ? $watermark_x : 0; | 88 | $watermark_x = $watermark_x ? $watermark_x : 0; |
| ... | @@ -110,48 +104,34 @@ $animate = Storage::disk('public')->path('ffmpeg') . "/output_16461288409938.mp4 | ... | @@ -110,48 +104,34 @@ $animate = Storage::disk('public')->path('ffmpeg') . "/output_16461288409938.mp4 |
| 110 | // ' -c:a libfdk_aac -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' . | 104 | // ' -c:a libfdk_aac -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' . |
| 111 | ' -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' . | 105 | ' -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' . |
| 112 | escapeshellarg($video); | 106 | escapeshellarg($video); |
| 107 | + | ||
| 113 | if ($this->execmd($cmd)) { | 108 | if ($this->execmd($cmd)) { |
| 114 | - return $video; | 109 | + // todo create insert |
| 115 | } else { | 110 | } else { |
| 116 | return false; | 111 | return false; |
| 117 | } | 112 | } |
| 118 | 113 | ||
| 114 | + $video2 = $this->getTempPath(); | ||
| 115 | + $cmd = $this->ffmpeg . ' -y -i ' . escapeshellarg($video) . | ||
| 116 | + ' -vf '. | ||
| 117 | + 'drawtext="'. | ||
| 118 | + 'fontfile=' . escapeshellarg($font) . ':'. | ||
| 119 | + 'text=' . escapeshellarg($content) . ':'. | ||
| 120 | + 'fontsize=43:'. | ||
| 121 | + 'fontcolor=white@1.0:'. | ||
| 122 | + 'x=main_w/2' . '-260' . ':'. | ||
| 123 | + 'y=main_h/2' . '-20' . ':'. | ||
| 124 | + 'box=1:boxcolor=0xd0cdcc@0.5'. | ||
| 125 | + '" ' . escapeshellarg($video2); | ||
| 119 | 126 | ||
| 120 | 127 | ||
| 121 | 128 | ||
| 122 | - | 129 | + if ($this->execmd($cmd)) { |
| 123 | -// $file = Storage::disk('public')->path('ffmpeg') . "/20180403172057586426000359.mp4"; | 130 | + // todo create insert |
| 124 | - $end_wallpaper = Storage::disk('public')->path('ffmpeg') . "/end_wallpaper.png"; | 131 | + } else { |
| 125 | - $thumbnail = Storage::disk('public')->path('ffmpeg') . "/thumbnail.png"; | 132 | + return false; |
| 126 | - $font = Storage::disk('public')->path('ffmpeg') . "/arialuni.ttf"; | ||
| 127 | - $signature = "一个比较长的用户昵称"; | ||
| 128 | - $signature_x = 0; | ||
| 129 | - $signature_y = -20; | ||
| 130 | - $user_audio = Storage::disk('public')->path('ffmpeg') . "/20181128172555064722000590.aac"; | ||
| 131 | - $watermark = Storage::disk('public')->path('ffmpeg') . "/LOGO_eng.png"; | ||
| 132 | - $watermark_x = 20; | ||
| 133 | - $watermark_y = 20; | ||
| 134 | - | ||
| 135 | - | ||
| 136 | - // 生成贴纸和签名 | ||
| 137 | - $end_wallpaper = $this->wallpaperWithSignature($end_wallpaper, $thumbnail, $signature, $font); | ||
| 138 | - | ||
| 139 | - // 截取最后一帧 | ||
| 140 | - $last_frame_video = $this->makeLastFrameVideo($file); | ||
| 141 | - | ||
| 142 | - | ||
| 143 | - $animate = ''; | ||
| 144 | - if ($last_frame_video) { | ||
| 145 | - $animate = $this->makeAnimate($last_frame_video, $end_wallpaper, '', $signature_x, $signature_y, $font); | ||
| 146 | } | 133 | } |
| 147 | 134 | ||
| 148 | - dd($animate); | ||
| 149 | -// | ||
| 150 | - $mofunshow = $this->makeMofunshow($file, $user_audio, $animate, null, $watermark, $watermark_x, $watermark_y); | ||
| 151 | - dd($mofunshow); | ||
| 152 | - | ||
| 153 | - | ||
| 154 | - return 0; | ||
| 155 | } | 135 | } |
| 156 | 136 | ||
| 157 | 137 | ||
| ... | @@ -523,6 +503,23 @@ $animate = Storage::disk('public')->path('ffmpeg') . "/output_16461288409938.mp4 | ... | @@ -523,6 +503,23 @@ $animate = Storage::disk('public')->path('ffmpeg') . "/output_16461288409938.mp4 |
| 523 | 503 | ||
| 524 | 504 | ||
| 525 | /** | 505 | /** |
| 506 | + * logo 大小转换 | ||
| 507 | + * @param $logo | ||
| 508 | + * @return bool | ||
| 509 | + */ | ||
| 510 | + public function translateLogo($logo) | ||
| 511 | + { | ||
| 512 | + $image = Storage::disk('public')->path('ffmpeg/output_150x150.jpg'); | ||
| 513 | + $cmd = $this->ffmpeg . ' -y -i ' . escapeshellarg($logo) . | ||
| 514 | + ' -vf scale=150:150 ' . escapeshellarg($image); | ||
| 515 | + if ($this->execmd($cmd)) { | ||
| 516 | + return $image; | ||
| 517 | + } else { | ||
| 518 | + return false; | ||
| 519 | + } | ||
| 520 | + } | ||
| 521 | + | ||
| 522 | + /** | ||
| 526 | * 合成视频秀 | 523 | * 合成视频秀 |
| 527 | * @param $file | 524 | * @param $file |
| 528 | * @param $audio | 525 | * @param $audio | ... | ... |
| ... | @@ -40,12 +40,36 @@ class MakeVideo implements ShouldQueue | ... | @@ -40,12 +40,36 @@ class MakeVideo implements ShouldQueue |
| 40 | */ | 40 | */ |
| 41 | public function handle() | 41 | public function handle() |
| 42 | { | 42 | { |
| 43 | - // 执行合成逻辑 | 43 | + $adminMakeVideo = $this->adminMakeVideo; |
| 44 | - $file = Storage::disk('public')->path('ffmpeg') . "/output_1646128658383.mp4"; | 44 | + $adminMakeVideo->video_url = Storage::disk('public')->path($adminMakeVideo->video_url); |
| 45 | - $watermark = Storage::disk('public')->path('ffmpeg') . "/LOGO_eng.png"; | 45 | + $adminMakeVideo->poem; |
| 46 | + $adminMakeVideo->temp->components; | ||
| 47 | + | ||
| 48 | + $file = $adminMakeVideo->video_url; | ||
| 46 | $watermark_x = 20; | 49 | $watermark_x = 20; |
| 47 | $watermark_y = 20; | 50 | $watermark_y = 20; |
| 48 | - $animate = Storage::disk('public')->path('ffmpeg') . "/output_16461288409938.mp4"; | 51 | + $end_wallpaper = Storage::disk('public')->path('ffmpeg') . "/end_wallpaper.png"; |
| 52 | + $thumbnail = Storage::disk('public')->path('ffmpeg') . "/thumbnail.png"; | ||
| 53 | + $font = Storage::disk('public')->path('ffmpeg') . "/arialuni.ttf"; | ||
| 54 | + $signature = "一言"; | ||
| 55 | + $signature_x = 0; | ||
| 56 | + $signature_y = -20; | ||
| 57 | + $content = $adminMakeVideo->poem->content; | ||
| 58 | + | ||
| 59 | + // 转换logo大小 | ||
| 60 | + $watermark = $this->translateLogo(Storage::disk('public')->path('image/logo.jpg')); | ||
| 61 | + | ||
| 62 | + // 生成贴纸和签名 | ||
| 63 | + $end_wallpaper = $this->wallpaperWithSignature($end_wallpaper, $thumbnail, $signature, $font); | ||
| 64 | + | ||
| 65 | + // 截取最后一帧 | ||
| 66 | + $last_frame_video = $this->makeLastFrameVideo($file); | ||
| 67 | + | ||
| 68 | + $animate = ''; | ||
| 69 | + if ($last_frame_video) { | ||
| 70 | + $animate = $this->makeAnimate($last_frame_video, $end_wallpaper, '', $signature_x, $signature_y, $font); | ||
| 71 | + } | ||
| 72 | + | ||
| 49 | 73 | ||
| 50 | $video = $this->getTempPath(); | 74 | $video = $this->getTempPath(); |
| 51 | $watermark_x = $watermark_x ? $watermark_x : 0; | 75 | $watermark_x = $watermark_x ? $watermark_x : 0; |
| ... | @@ -57,18 +81,32 @@ class MakeVideo implements ShouldQueue | ... | @@ -57,18 +81,32 @@ class MakeVideo implements ShouldQueue |
| 57 | ' -i ' . escapeshellarg($file) . | 81 | ' -i ' . escapeshellarg($file) . |
| 58 | ' -i ' . escapeshellarg($animate) . | 82 | ' -i ' . escapeshellarg($animate) . |
| 59 | $am_inp . | 83 | $am_inp . |
| 60 | -// ' -filter_complex "[0:0]' . '' . $am_filter . 'setsar=sar=1/1[t];[t] [2:a] [1:0] [1:1] concat=n=2:v=1:a=1 [v] [a]"' . | ||
| 61 | ' -filter_complex "[0:0]' . '' . $am_filter . '[0:1] [1:0] [1:1] concat=n=2:v=1:a=1 [v] [a]"' . | 84 | ' -filter_complex "[0:0]' . '' . $am_filter . '[0:1] [1:0] [1:1] concat=n=2:v=1:a=1 [v] [a]"' . |
| 62 | ' -map [v] -map [a]'; | 85 | ' -map [v] -map [a]'; |
| 63 | - | ||
| 64 | $cmd .= | 86 | $cmd .= |
| 65 | ' -c:v libx264 -s 800x450 -bt 256k -r 25' . | 87 | ' -c:v libx264 -s 800x450 -bt 256k -r 25' . |
| 66 | -// todo 没有libfdk_aac库 | ||
| 67 | -// ' -c:a libfdk_aac -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' . | ||
| 68 | ' -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' . | 88 | ' -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' . |
| 69 | escapeshellarg($video); | 89 | escapeshellarg($video); |
| 90 | + | ||
| 91 | + // 执行合成 | ||
| 92 | + $this->execmd($cmd); | ||
| 93 | + | ||
| 94 | + $video2 = $this->getTempPath(); | ||
| 95 | + $cmd = $this->ffmpeg . ' -y -i ' . escapeshellarg($video) . | ||
| 96 | + ' -vf '. | ||
| 97 | + 'drawtext="'. | ||
| 98 | + 'fontfile=' . escapeshellarg($font) . ':'. | ||
| 99 | + 'text=' . escapeshellarg($content) . ':'. | ||
| 100 | + 'fontsize=43:'. | ||
| 101 | + 'fontcolor=white@1.0:'. | ||
| 102 | + 'x=main_w/2' . '-260' . ':'. | ||
| 103 | + 'y=main_h/2' . '-20' . ':'. | ||
| 104 | + 'box=1:boxcolor=0xd0cdcc@0.5'. | ||
| 105 | + '" ' . escapeshellarg($video2); | ||
| 106 | + | ||
| 70 | if ($this->execmd($cmd)) { | 107 | if ($this->execmd($cmd)) { |
| 71 | - return $video; | 108 | + // 全部合成以后创建 临境 |
| 109 | + | ||
| 72 | } else { | 110 | } else { |
| 73 | return false; | 111 | return false; |
| 74 | } | 112 | } |
| ... | @@ -440,4 +478,21 @@ class MakeVideo implements ShouldQueue | ... | @@ -440,4 +478,21 @@ class MakeVideo implements ShouldQueue |
| 440 | imagecopymerge($background, $thumbnail, 127, 26, 0, 0, imagesx($thumbnail), imagesy($thumbnail), 100); | 478 | imagecopymerge($background, $thumbnail, 127, 26, 0, 0, imagesx($thumbnail), imagesy($thumbnail), 100); |
| 441 | return $background; | 479 | return $background; |
| 442 | } | 480 | } |
| 481 | + | ||
| 482 | + /** | ||
| 483 | + * logo 大小转换 | ||
| 484 | + * @param $logo | ||
| 485 | + * @return bool | ||
| 486 | + */ | ||
| 487 | + public function translateLogo($logo) | ||
| 488 | + { | ||
| 489 | + $image = Storage::disk('public')->path('ffmpeg/output_150x150.jpg'); | ||
| 490 | + $cmd = $this->ffmpeg . ' -y -i ' . escapeshellarg($logo) . | ||
| 491 | + ' -vf scale=150:150 ' . escapeshellarg($image); | ||
| 492 | + if ($this->execmd($cmd)) { | ||
| 493 | + return $image; | ||
| 494 | + } else { | ||
| 495 | + return false; | ||
| 496 | + } | ||
| 497 | + } | ||
| 443 | } | 498 | } | ... | ... |
| ... | @@ -5,6 +5,8 @@ namespace App\Models; | ... | @@ -5,6 +5,8 @@ namespace App\Models; |
| 5 | use Dcat\Admin\Traits\HasDateTimeFormatter; | 5 | use Dcat\Admin\Traits\HasDateTimeFormatter; |
| 6 | 6 | ||
| 7 | use Illuminate\Database\Eloquent\Model; | 7 | use Illuminate\Database\Eloquent\Model; |
| 8 | +use Illuminate\Support\Facades\Storage; | ||
| 9 | +use Illuminate\Support\Str; | ||
| 8 | 10 | ||
| 9 | class AdminMakeVideo extends Model | 11 | class AdminMakeVideo extends Model |
| 10 | { | 12 | { |
| ... | @@ -12,4 +14,41 @@ class AdminMakeVideo extends Model | ... | @@ -12,4 +14,41 @@ class AdminMakeVideo extends Model |
| 12 | protected $table = 'admin_make_video'; | 14 | protected $table = 'admin_make_video'; |
| 13 | 15 | ||
| 14 | protected $guarded = ['']; | 16 | protected $guarded = ['']; |
| 17 | + | ||
| 18 | + public function getVideoUrl() | ||
| 19 | + { | ||
| 20 | + if (Str::contains($this->video_url, '//')) { | ||
| 21 | + return $this->video_url; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + return Storage::disk('public')->url($this->video_url); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + public function getThumbnailUrl() | ||
| 28 | + { | ||
| 29 | + if (Str::contains($this->thumbnail_url, '//')) { | ||
| 30 | + return $this->thumbnail_url; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + return Storage::disk('public')->url($this->thumbnail_url); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + public function getImagesUrl() | ||
| 37 | + { | ||
| 38 | + if (Str::contains($this->images_url, '//')) { | ||
| 39 | + return $this->images_url; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + return Storage::disk('public')->url($this->images_url); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + public function poem() | ||
| 46 | + { | ||
| 47 | + return $this->hasOne(OnePoem::class,'id','poem_id'); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + public function temp() | ||
| 51 | + { | ||
| 52 | + return $this->hasOne(VideoTemp::class,'id','temp_id'); | ||
| 53 | + } | ||
| 15 | } | 54 | } | ... | ... |
| ... | @@ -13,6 +13,7 @@ | ... | @@ -13,6 +13,7 @@ |
| 13 | "jiannei/laravel-response": "^4.0", | 13 | "jiannei/laravel-response": "^4.0", |
| 14 | "jpush/jpush": "^3.6", | 14 | "jpush/jpush": "^3.6", |
| 15 | "laravel/framework": "^8.75", | 15 | "laravel/framework": "^8.75", |
| 16 | + "laravel/horizon": "^5.9", | ||
| 16 | "laravel/sanctum": "^2.11", | 17 | "laravel/sanctum": "^2.11", |
| 17 | "laravel/socialite": "^5.2", | 18 | "laravel/socialite": "^5.2", |
| 18 | "laravel/tinker": "^2.5", | 19 | "laravel/tinker": "^2.5", | ... | ... |
| ... | @@ -4,7 +4,7 @@ | ... | @@ -4,7 +4,7 @@ |
| 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", |
| 5 | "This file is @generated automatically" | 5 | "This file is @generated automatically" |
| 6 | ], | 6 | ], |
| 7 | - "content-hash": "aa46d9704a095f2da2d480e58e475235", | 7 | + "content-hash": "653de2c6fbfa22bf510ea8db8c4b24ee", |
| 8 | "packages": [ | 8 | "packages": [ |
| 9 | { | 9 | { |
| 10 | "name": "asm89/stack-cors", | 10 | "name": "asm89/stack-cors", |
| ... | @@ -2016,6 +2016,89 @@ | ... | @@ -2016,6 +2016,89 @@ |
| 2016 | "time": "2021-12-21T20:22:29+00:00" | 2016 | "time": "2021-12-21T20:22:29+00:00" |
| 2017 | }, | 2017 | }, |
| 2018 | { | 2018 | { |
| 2019 | + "name": "laravel/horizon", | ||
| 2020 | + "version": "v5.9.3", | ||
| 2021 | + "source": { | ||
| 2022 | + "type": "git", | ||
| 2023 | + "url": "https://github.com/laravel/horizon.git", | ||
| 2024 | + "reference": "2c2c28dff4b0f8632f74ca1945f830fb462c6b56" | ||
| 2025 | + }, | ||
| 2026 | + "dist": { | ||
| 2027 | + "type": "zip", | ||
| 2028 | + "url": "https://api.github.com/repos/laravel/horizon/zipball/2c2c28dff4b0f8632f74ca1945f830fb462c6b56", | ||
| 2029 | + "reference": "2c2c28dff4b0f8632f74ca1945f830fb462c6b56", | ||
| 2030 | + "shasum": "", | ||
| 2031 | + "mirrors": [ | ||
| 2032 | + { | ||
| 2033 | + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", | ||
| 2034 | + "preferred": true | ||
| 2035 | + } | ||
| 2036 | + ] | ||
| 2037 | + }, | ||
| 2038 | + "require": { | ||
| 2039 | + "ext-json": "*", | ||
| 2040 | + "ext-pcntl": "*", | ||
| 2041 | + "ext-posix": "*", | ||
| 2042 | + "illuminate/contracts": "^8.17|^9.0", | ||
| 2043 | + "illuminate/queue": "^8.17|^9.0", | ||
| 2044 | + "illuminate/support": "^8.17|^9.0", | ||
| 2045 | + "nesbot/carbon": "^2.17", | ||
| 2046 | + "php": "^7.3|^8.0", | ||
| 2047 | + "ramsey/uuid": "^4.0", | ||
| 2048 | + "symfony/error-handler": "^5.0|^6.0", | ||
| 2049 | + "symfony/process": "^5.0|^6.0" | ||
| 2050 | + }, | ||
| 2051 | + "require-dev": { | ||
| 2052 | + "mockery/mockery": "^1.0", | ||
| 2053 | + "orchestra/testbench": "^6.0|^7.0", | ||
| 2054 | + "phpunit/phpunit": "^9.0", | ||
| 2055 | + "predis/predis": "^1.1" | ||
| 2056 | + }, | ||
| 2057 | + "suggest": { | ||
| 2058 | + "ext-redis": "Required to use the Redis PHP driver.", | ||
| 2059 | + "predis/predis": "Required when not using the Redis PHP driver (^1.1)." | ||
| 2060 | + }, | ||
| 2061 | + "type": "library", | ||
| 2062 | + "extra": { | ||
| 2063 | + "branch-alias": { | ||
| 2064 | + "dev-master": "5.x-dev" | ||
| 2065 | + }, | ||
| 2066 | + "laravel": { | ||
| 2067 | + "providers": [ | ||
| 2068 | + "Laravel\\Horizon\\HorizonServiceProvider" | ||
| 2069 | + ], | ||
| 2070 | + "aliases": { | ||
| 2071 | + "Horizon": "Laravel\\Horizon\\Horizon" | ||
| 2072 | + } | ||
| 2073 | + } | ||
| 2074 | + }, | ||
| 2075 | + "autoload": { | ||
| 2076 | + "psr-4": { | ||
| 2077 | + "Laravel\\Horizon\\": "src/" | ||
| 2078 | + } | ||
| 2079 | + }, | ||
| 2080 | + "notification-url": "https://packagist.org/downloads/", | ||
| 2081 | + "license": [ | ||
| 2082 | + "MIT" | ||
| 2083 | + ], | ||
| 2084 | + "authors": [ | ||
| 2085 | + { | ||
| 2086 | + "name": "Taylor Otwell", | ||
| 2087 | + "email": "taylor@laravel.com" | ||
| 2088 | + } | ||
| 2089 | + ], | ||
| 2090 | + "description": "Dashboard and code-driven configuration for Laravel queues.", | ||
| 2091 | + "keywords": [ | ||
| 2092 | + "laravel", | ||
| 2093 | + "queue" | ||
| 2094 | + ], | ||
| 2095 | + "support": { | ||
| 2096 | + "issues": "https://github.com/laravel/horizon/issues", | ||
| 2097 | + "source": "https://github.com/laravel/horizon/tree/v5.9.3" | ||
| 2098 | + }, | ||
| 2099 | + "time": "2022-02-22T20:56:51+00:00" | ||
| 2100 | + }, | ||
| 2101 | + { | ||
| 2019 | "name": "laravel/sanctum", | 2102 | "name": "laravel/sanctum", |
| 2020 | "version": "v2.13.0", | 2103 | "version": "v2.13.0", |
| 2021 | "source": { | 2104 | "source": { | ... | ... |
| ... | @@ -173,6 +173,7 @@ return [ | ... | @@ -173,6 +173,7 @@ return [ |
| 173 | App\Providers\AuthServiceProvider::class, | 173 | App\Providers\AuthServiceProvider::class, |
| 174 | // App\Providers\BroadcastServiceProvider::class, | 174 | // App\Providers\BroadcastServiceProvider::class, |
| 175 | App\Providers\EventServiceProvider::class, | 175 | App\Providers\EventServiceProvider::class, |
| 176 | + App\Providers\HorizonServiceProvider::class, | ||
| 176 | App\Providers\RouteServiceProvider::class, | 177 | App\Providers\RouteServiceProvider::class, |
| 177 | 178 | ||
| 178 | // 社会化登录 | 179 | // 社会化登录 | ... | ... |
config/horizon.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use Illuminate\Support\Str; | ||
| 4 | + | ||
| 5 | +return [ | ||
| 6 | + | ||
| 7 | + /* | ||
| 8 | + |-------------------------------------------------------------------------- | ||
| 9 | + | Horizon Domain | ||
| 10 | + |-------------------------------------------------------------------------- | ||
| 11 | + | | ||
| 12 | + | This is the subdomain where Horizon will be accessible from. If this | ||
| 13 | + | setting is null, Horizon will reside under the same domain as the | ||
| 14 | + | application. Otherwise, this value will serve as the subdomain. | ||
| 15 | + | | ||
| 16 | + */ | ||
| 17 | + | ||
| 18 | + 'domain' => env('HORIZON_DOMAIN', null), | ||
| 19 | + | ||
| 20 | + /* | ||
| 21 | + |-------------------------------------------------------------------------- | ||
| 22 | + | Horizon Path | ||
| 23 | + |-------------------------------------------------------------------------- | ||
| 24 | + | | ||
| 25 | + | This is the URI path where Horizon will be accessible from. Feel free | ||
| 26 | + | to change this path to anything you like. Note that the URI will not | ||
| 27 | + | affect the paths of its internal API that aren't exposed to users. | ||
| 28 | + | | ||
| 29 | + */ | ||
| 30 | + | ||
| 31 | + 'path' => env('HORIZON_PATH', 'horizon'), | ||
| 32 | + | ||
| 33 | + /* | ||
| 34 | + |-------------------------------------------------------------------------- | ||
| 35 | + | Horizon Redis Connection | ||
| 36 | + |-------------------------------------------------------------------------- | ||
| 37 | + | | ||
| 38 | + | This is the name of the Redis connection where Horizon will store the | ||
| 39 | + | meta information required for it to function. It includes the list | ||
| 40 | + | of supervisors, failed jobs, job metrics, and other information. | ||
| 41 | + | | ||
| 42 | + */ | ||
| 43 | + | ||
| 44 | + 'use' => 'default', | ||
| 45 | + | ||
| 46 | + /* | ||
| 47 | + |-------------------------------------------------------------------------- | ||
| 48 | + | Horizon Redis Prefix | ||
| 49 | + |-------------------------------------------------------------------------- | ||
| 50 | + | | ||
| 51 | + | This prefix will be used when storing all Horizon data in Redis. You | ||
| 52 | + | may modify the prefix when you are running multiple installations | ||
| 53 | + | of Horizon on the same server so that they don't have problems. | ||
| 54 | + | | ||
| 55 | + */ | ||
| 56 | + | ||
| 57 | + 'prefix' => env( | ||
| 58 | + 'HORIZON_PREFIX', | ||
| 59 | + Str::slug(env('APP_NAME', 'laravel'), '_').'_horizon:' | ||
| 60 | + ), | ||
| 61 | + | ||
| 62 | + /* | ||
| 63 | + |-------------------------------------------------------------------------- | ||
| 64 | + | Horizon Route Middleware | ||
| 65 | + |-------------------------------------------------------------------------- | ||
| 66 | + | | ||
| 67 | + | These middleware will get attached onto each Horizon route, giving you | ||
| 68 | + | the chance to add your own middleware to this list or change any of | ||
| 69 | + | the existing middleware. Or, you can simply stick with this list. | ||
| 70 | + | | ||
| 71 | + */ | ||
| 72 | + | ||
| 73 | + 'middleware' => ['web'], | ||
| 74 | + | ||
| 75 | + /* | ||
| 76 | + |-------------------------------------------------------------------------- | ||
| 77 | + | Queue Wait Time Thresholds | ||
| 78 | + |-------------------------------------------------------------------------- | ||
| 79 | + | | ||
| 80 | + | This option allows you to configure when the LongWaitDetected event | ||
| 81 | + | will be fired. Every connection / queue combination may have its | ||
| 82 | + | own, unique threshold (in seconds) before this event is fired. | ||
| 83 | + | | ||
| 84 | + */ | ||
| 85 | + | ||
| 86 | + 'waits' => [ | ||
| 87 | + 'redis:default' => 60, | ||
| 88 | + ], | ||
| 89 | + | ||
| 90 | + /* | ||
| 91 | + |-------------------------------------------------------------------------- | ||
| 92 | + | Job Trimming Times | ||
| 93 | + |-------------------------------------------------------------------------- | ||
| 94 | + | | ||
| 95 | + | Here you can configure for how long (in minutes) you desire Horizon to | ||
| 96 | + | persist the recent and failed jobs. Typically, recent jobs are kept | ||
| 97 | + | for one hour while all failed jobs are stored for an entire week. | ||
| 98 | + | | ||
| 99 | + */ | ||
| 100 | + | ||
| 101 | + 'trim' => [ | ||
| 102 | + 'recent' => 60, | ||
| 103 | + 'pending' => 60, | ||
| 104 | + 'completed' => 60, | ||
| 105 | + 'recent_failed' => 10080, | ||
| 106 | + 'failed' => 10080, | ||
| 107 | + 'monitored' => 10080, | ||
| 108 | + ], | ||
| 109 | + | ||
| 110 | + /* | ||
| 111 | + |-------------------------------------------------------------------------- | ||
| 112 | + | Metrics | ||
| 113 | + |-------------------------------------------------------------------------- | ||
| 114 | + | | ||
| 115 | + | Here you can configure how many snapshots should be kept to display in | ||
| 116 | + | the metrics graph. This will get used in combination with Horizon's | ||
| 117 | + | `horizon:snapshot` schedule to define how long to retain metrics. | ||
| 118 | + | | ||
| 119 | + */ | ||
| 120 | + | ||
| 121 | + 'metrics' => [ | ||
| 122 | + 'trim_snapshots' => [ | ||
| 123 | + 'job' => 24, | ||
| 124 | + 'queue' => 24, | ||
| 125 | + ], | ||
| 126 | + ], | ||
| 127 | + | ||
| 128 | + /* | ||
| 129 | + |-------------------------------------------------------------------------- | ||
| 130 | + | Fast Termination | ||
| 131 | + |-------------------------------------------------------------------------- | ||
| 132 | + | | ||
| 133 | + | When this option is enabled, Horizon's "terminate" command will not | ||
| 134 | + | wait on all of the workers to terminate unless the --wait option | ||
| 135 | + | is provided. Fast termination can shorten deployment delay by | ||
| 136 | + | allowing a new instance of Horizon to start while the last | ||
| 137 | + | instance will continue to terminate each of its workers. | ||
| 138 | + | | ||
| 139 | + */ | ||
| 140 | + | ||
| 141 | + 'fast_termination' => false, | ||
| 142 | + | ||
| 143 | + /* | ||
| 144 | + |-------------------------------------------------------------------------- | ||
| 145 | + | Memory Limit (MB) | ||
| 146 | + |-------------------------------------------------------------------------- | ||
| 147 | + | | ||
| 148 | + | This value describes the maximum amount of memory the Horizon master | ||
| 149 | + | supervisor may consume before it is terminated and restarted. For | ||
| 150 | + | configuring these limits on your workers, see the next section. | ||
| 151 | + | | ||
| 152 | + */ | ||
| 153 | + | ||
| 154 | + 'memory_limit' => 64, | ||
| 155 | + | ||
| 156 | + /* | ||
| 157 | + |-------------------------------------------------------------------------- | ||
| 158 | + | Queue Worker Configuration | ||
| 159 | + |-------------------------------------------------------------------------- | ||
| 160 | + | | ||
| 161 | + | Here you may define the queue worker settings used by your application | ||
| 162 | + | in all environments. These supervisors and settings handle all your | ||
| 163 | + | queued jobs and will be provisioned by Horizon during deployment. | ||
| 164 | + | | ||
| 165 | + */ | ||
| 166 | + | ||
| 167 | + 'defaults' => [ | ||
| 168 | + 'supervisor-1' => [ | ||
| 169 | + 'connection' => 'redis', | ||
| 170 | + 'queue' => ['default'], | ||
| 171 | + 'balance' => 'auto', | ||
| 172 | + 'maxProcesses' => 1, | ||
| 173 | + 'maxTime' => 0, | ||
| 174 | + 'maxJobs' => 0, | ||
| 175 | + 'memory' => 128, | ||
| 176 | + 'tries' => 1, | ||
| 177 | + 'timeout' => 60, | ||
| 178 | + 'nice' => 0, | ||
| 179 | + ], | ||
| 180 | + ], | ||
| 181 | + | ||
| 182 | + 'environments' => [ | ||
| 183 | + 'production' => [ | ||
| 184 | + 'supervisor-1' => [ | ||
| 185 | + 'maxProcesses' => 10, | ||
| 186 | + 'balanceMaxShift' => 1, | ||
| 187 | + 'balanceCooldown' => 3, | ||
| 188 | + ], | ||
| 189 | + ], | ||
| 190 | + | ||
| 191 | + 'local' => [ | ||
| 192 | + 'supervisor-1' => [ | ||
| 193 | + 'maxProcesses' => 3, | ||
| 194 | + ], | ||
| 195 | + ], | ||
| 196 | + ], | ||
| 197 | +]; |
-
Please register or login to post a comment