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