李帅

1.重构模板和临境上传功能

...@@ -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 // 社会化登录
......
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 +];