Showing
7 changed files
with
160 additions
and
163 deletions
| ... | @@ -181,9 +181,8 @@ class AdminMakeVideoController extends AdminController | ... | @@ -181,9 +181,8 @@ class AdminMakeVideoController extends AdminController |
| 181 | Storage::disk('public')->delete($immerse->url); | 181 | Storage::disk('public')->delete($immerse->url); |
| 182 | Storage::disk('public')->delete($immerse->thumbnail); | 182 | Storage::disk('public')->delete($immerse->thumbnail); |
| 183 | Storage::disk('public')->delete($immerse->bgm); | 183 | Storage::disk('public')->delete($immerse->bgm); |
| 184 | + $immerse->delete(); | ||
| 184 | 185 | ||
| 185 | - | 186 | + return $this->form()->response()->refresh()->success('删除成功'); |
| 186 | - dd($id); | ||
| 187 | -// return $this->form()->destroy($id); | ||
| 188 | } | 187 | } |
| 189 | } | 188 | } | ... | ... |
| ... | @@ -4,14 +4,11 @@ namespace App\Http\Controllers\V1; | ... | @@ -4,14 +4,11 @@ namespace App\Http\Controllers\V1; |
| 4 | 4 | ||
| 5 | use App\Http\Controllers\Controller; | 5 | use App\Http\Controllers\Controller; |
| 6 | use App\Models\Immerse; | 6 | use App\Models\Immerse; |
| 7 | -use App\Models\UserMakeVideo; | ||
| 8 | use App\Jobs\UserMakeVideo as MakeVideo; | 7 | use App\Jobs\UserMakeVideo as MakeVideo; |
| 9 | use App\Jobs\UserMakeImages as MakeImages; | 8 | use App\Jobs\UserMakeImages as MakeImages; |
| 10 | use Illuminate\Http\Request; | 9 | use Illuminate\Http\Request; |
| 11 | use Illuminate\Support\Facades\Auth; | 10 | use Illuminate\Support\Facades\Auth; |
| 12 | -use Illuminate\Support\Facades\Storage; | ||
| 13 | use Illuminate\Support\Facades\Validator; | 11 | use Illuminate\Support\Facades\Validator; |
| 14 | -use Illuminate\Support\Str; | ||
| 15 | use Jiannei\Response\Laravel\Support\Facades\Response; | 12 | use Jiannei\Response\Laravel\Support\Facades\Response; |
| 16 | 13 | ||
| 17 | class ImmerseController extends Controller | 14 | class ImmerseController extends Controller |
| ... | @@ -41,7 +38,7 @@ class ImmerseController extends Controller | ... | @@ -41,7 +38,7 @@ class ImmerseController extends Controller |
| 41 | 'type' => 'required', | 38 | 'type' => 'required', |
| 42 | 'content' => 'sometimes', | 39 | 'content' => 'sometimes', |
| 43 | 'weather' => 'sometimes', | 40 | 'weather' => 'sometimes', |
| 44 | - 'thumbnail_url' => 'sometimes', | 41 | + 'thumbnail' => 'sometimes', |
| 45 | ]); | 42 | ]); |
| 46 | 43 | ||
| 47 | if ($validator->fails()){ | 44 | if ($validator->fails()){ |
| ... | @@ -50,10 +47,12 @@ class ImmerseController extends Controller | ... | @@ -50,10 +47,12 @@ class ImmerseController extends Controller |
| 50 | 47 | ||
| 51 | $validated = $validator->validated(); | 48 | $validated = $validator->validated(); |
| 52 | 49 | ||
| 50 | + $user_id = $request->user()->id; | ||
| 51 | + | ||
| 53 | $immerse = Immerse::query()->find($request->item_id); | 52 | $immerse = Immerse::query()->find($request->item_id); |
| 54 | if ($validated['type'] == 1){ | 53 | if ($validated['type'] == 1){ |
| 55 | $create = Immerse::query()->create([ | 54 | $create = Immerse::query()->create([ |
| 56 | - 'user_id' => Auth::user()->getAuthIdentifier(), | 55 | + 'user_id' => $user_id, |
| 57 | 'title' => '', | 56 | 'title' => '', |
| 58 | 'content' => $validated['content'], | 57 | 'content' => $validated['content'], |
| 59 | 'url' => '', | 58 | 'url' => '', |
| ... | @@ -64,6 +63,7 @@ class ImmerseController extends Controller | ... | @@ -64,6 +63,7 @@ class ImmerseController extends Controller |
| 64 | 'temp_id' => $immerse->temp_id, | 63 | 'temp_id' => $immerse->temp_id, |
| 65 | 'thumbnail' => $immerse->thumbnail, | 64 | 'thumbnail' => $immerse->thumbnail, |
| 66 | 'bgm' => $validated['item_url'], | 65 | 'bgm' => $validated['item_url'], |
| 66 | + 'state' => 0 | ||
| 67 | ]); | 67 | ]); |
| 68 | 68 | ||
| 69 | // 添加至队列 | 69 | // 添加至队列 |
| ... | @@ -71,7 +71,7 @@ class ImmerseController extends Controller | ... | @@ -71,7 +71,7 @@ class ImmerseController extends Controller |
| 71 | }else{ | 71 | }else{ |
| 72 | // 视频 | 72 | // 视频 |
| 73 | $create = Immerse::query()->create([ | 73 | $create = Immerse::query()->create([ |
| 74 | - 'user_id' => Auth::user()->getAuthIdentifier(), | 74 | + 'user_id' => $user_id, |
| 75 | 'title' => '', | 75 | 'title' => '', |
| 76 | 'content' => $validated['content'], | 76 | 'content' => $validated['content'], |
| 77 | 'url' => '', | 77 | 'url' => '', |
| ... | @@ -82,13 +82,14 @@ class ImmerseController extends Controller | ... | @@ -82,13 +82,14 @@ class ImmerseController extends Controller |
| 82 | 'temp_id' => $immerse->temp_id, | 82 | 'temp_id' => $immerse->temp_id, |
| 83 | 'thumbnail' => '', | 83 | 'thumbnail' => '', |
| 84 | 'bgm' => $immerse->bgm, | 84 | 'bgm' => $immerse->bgm, |
| 85 | + 'state' => 0 | ||
| 85 | ]); | 86 | ]); |
| 86 | 87 | ||
| 87 | // 添加至队列 | 88 | // 添加至队列 |
| 88 | MakeVideo::dispatch($create, $validated['item_url']); | 89 | MakeVideo::dispatch($create, $validated['item_url']); |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | - return Response::created($create->id); | 92 | + return Response::created($create); |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | /** | 95 | /** | ... | ... |
| ... | @@ -144,7 +144,7 @@ class UserController extends Controller | ... | @@ -144,7 +144,7 @@ class UserController extends Controller |
| 144 | 144 | ||
| 145 | $user_id = Auth::user()->getAuthIdentifier(); | 145 | $user_id = Auth::user()->getAuthIdentifier(); |
| 146 | 146 | ||
| 147 | - $immerse = Immerse::query()->where('user_id', 1); | 147 | + $immerse = Immerse::query()->where('user_id', $user_id); |
| 148 | switch ($type) | 148 | switch ($type) |
| 149 | { | 149 | { |
| 150 | case 0 : // 审核中... | 150 | case 0 : // 审核中... | ... | ... |
| ... | @@ -2,7 +2,6 @@ | ... | @@ -2,7 +2,6 @@ |
| 2 | 2 | ||
| 3 | namespace App\Jobs; | 3 | namespace App\Jobs; |
| 4 | 4 | ||
| 5 | -use App\Models\AdminMakeVideo; | ||
| 6 | use App\Models\Immerse; | 5 | use App\Models\Immerse; |
| 7 | use App\Models\VideoTemp; | 6 | use App\Models\VideoTemp; |
| 8 | use Carbon\Carbon; | 7 | use Carbon\Carbon; |
| ... | @@ -15,6 +14,7 @@ use Illuminate\Queue\SerializesModels; | ... | @@ -15,6 +14,7 @@ use Illuminate\Queue\SerializesModels; |
| 15 | use Illuminate\Support\Facades\File; | 14 | use Illuminate\Support\Facades\File; |
| 16 | use Illuminate\Support\Facades\Log; | 15 | use Illuminate\Support\Facades\Log; |
| 17 | use Illuminate\Support\Facades\Storage; | 16 | use Illuminate\Support\Facades\Storage; |
| 17 | +use Illuminate\Support\Str; | ||
| 18 | 18 | ||
| 19 | class UserMakeImages implements ShouldQueue | 19 | class UserMakeImages implements ShouldQueue |
| 20 | { | 20 | { |
| ... | @@ -63,83 +63,88 @@ class UserMakeImages implements ShouldQueue | ... | @@ -63,83 +63,88 @@ class UserMakeImages implements ShouldQueue |
| 63 | $this->width = $width = $media_info['streams'][0]['width']; | 63 | $this->width = $width = $media_info['streams'][0]['width']; |
| 64 | $this->height = $height = $media_info['streams'][0]['height']; | 64 | $this->height = $height = $media_info['streams'][0]['height']; |
| 65 | 65 | ||
| 66 | - if ($this->immerse->type == 2 && $this->immerse->bgm){ | 66 | + try{ |
| 67 | - // 没有背景音,单图一张,输出为单图。 | 67 | + if ($this->immerse->bgm == '' || $this->immerse->bgm == null) { |
| 68 | - $output = $this->getTempPath('.png',false); | 68 | + // 没有背景音,单图一张,输出为单图。 |
| 69 | - $cmd = $this->ffmpeg . ' -y '. | 69 | + $output = $this->getTempPath('.png',false); |
| 70 | - ' -i ' . escapeshellarg($image). | 70 | + $cmd = $this->ffmpeg . ' -y '. |
| 71 | - ' -i ' . escapeshellarg($watermark). | 71 | + ' -i ' . escapeshellarg($image). |
| 72 | - ' -filter_complex "[0:0] ' . | 72 | + ' -i ' . escapeshellarg($watermark). |
| 73 | - $this->getTextContentString(). | 73 | + ' -filter_complex "[0:0] ' . |
| 74 | - ' [text];[text]'. | 74 | + $this->getTextContentString(). |
| 75 | - ' [1:0]overlay=20:20" ' . | 75 | + ' [text];[text]'. |
| 76 | - escapeshellarg($output); | 76 | + ' [1:0]overlay=20:20" ' . |
| 77 | - | 77 | + escapeshellarg($output); |
| 78 | - if (!$this->execmd($cmd)) return; | 78 | + |
| 79 | - | 79 | + if (!$this->execmd($cmd)) return; |
| 80 | - // 全部合成以后创建 临境 | 80 | + |
| 81 | - $video_info = $this->mediainfo($output); | 81 | + // 全部合成以后创建 临境 |
| 82 | - }else{ | 82 | + $video_info = $this->mediainfo($output); |
| 83 | - // 有背景音 单图合成视频,时长为音频时长,音频加入背景音 | 83 | + }else{ |
| 84 | - $bgm = Storage::disk('public')->path($this->immerse->bgm); | 84 | + // 有背景音 单图合成视频,时长为音频时长,音频加入背景音 |
| 85 | - | 85 | + $bgm = Storage::disk('public')->path($this->immerse->bgm); |
| 86 | - $end_wallpaper = Storage::disk('public')->path('ffmpeg/end_wallpaper.png'); | 86 | + |
| 87 | - $thumbnail = Storage::disk('public')->path('ffmpeg/thumbnail.png'); | 87 | + $end_wallpaper = Storage::disk('public')->path('ffmpeg/end_wallpaper.png'); |
| 88 | - $font = Storage::disk('public')->path('ffmpeg') . "/arialuni.ttf"; | 88 | + $thumbnail = Storage::disk('public')->path('ffmpeg/thumbnail.png'); |
| 89 | - $signature = "一言 · 官方出品"; | 89 | + $font = Storage::disk('public')->path('ffmpeg') . "/arialuni.ttf"; |
| 90 | - | 90 | + $signature = "一言 · 官方出品"; |
| 91 | - // 生成贴纸和签名 | 91 | + |
| 92 | - $end_wallpaper = $this->wallpaperWithSignature($end_wallpaper, $thumbnail, $signature, $font); | 92 | + // 生成贴纸和签名 |
| 93 | - | 93 | + $end_wallpaper = $this->wallpaperWithSignature($end_wallpaper, $thumbnail, $signature, $font); |
| 94 | - // 制作最后一帧 | 94 | + |
| 95 | - $size = $this->width . 'x' . $this->height; | 95 | + // 制作最后一帧 |
| 96 | - $time_length = 0.7; | 96 | + $size = $this->width . 'x' . $this->height; |
| 97 | - $r = 24; | 97 | + $time_length = 0.7; |
| 98 | - $last_frame_video = $this->getTempPath('.mp4'); | 98 | + $r = 24; |
| 99 | - $font = Storage::disk('public')->path('ffmpeg/arialuni.ttf'); | 99 | + $last_frame_video = $this->getTempPath('.mp4'); |
| 100 | - | 100 | + $font = Storage::disk('public')->path('ffmpeg/arialuni.ttf'); |
| 101 | - $cmd = $this->ffmpeg . ' -y -i ' . escapeshellarg($image) . | 101 | + |
| 102 | - ' -i ' . escapeshellarg($watermark) . | 102 | + $cmd = $this->ffmpeg . ' -y -i ' . escapeshellarg($image) . |
| 103 | - " -f lavfi -i nullsrc=s={$size}:d={$time_length}:r={$r} -f lavfi -i aevalsrc=0:duration={$time_length}" . | 103 | + ' -i ' . escapeshellarg($watermark) . |
| 104 | - ' -filter_complex "'. | 104 | + " -f lavfi -i nullsrc=s={$size}:d={$time_length}:r={$r} -f lavfi -i aevalsrc=0:duration={$time_length}" . |
| 105 | - ' [0:0] ' . $this->getTextContentString() . | 105 | + ' -filter_complex "'. |
| 106 | - '[text];[text][1:0]overlay=20:20[water];' . | 106 | + ' [0:0] ' . $this->getTextContentString() . |
| 107 | - ' [water]select=\'eq(n,0)\',setpts=PTS-STARTPTS[lastframe];[2:v][lastframe]overlay[v] " ' . | 107 | + '[text];[text][1:0]overlay=20:20[water];' . |
| 108 | - ' -map [v] -map 3:a ' . escapeshellarg($last_frame_video); | 108 | + ' [water]select=\'eq(n,0)\',setpts=PTS-STARTPTS[lastframe];[2:v][lastframe]overlay[v] " ' . |
| 109 | - | 109 | + ' -map [v] -map 3:a ' . escapeshellarg($last_frame_video); |
| 110 | - if (!$this->execmd($cmd)) return; | 110 | + |
| 111 | - | 111 | + if (!$this->execmd($cmd)) return; |
| 112 | - // 利用最后一帧制作动画 | 112 | + |
| 113 | - $signature_x = 0; | 113 | + // 利用最后一帧制作动画 |
| 114 | - $signature_y = -20; | 114 | + $signature_x = 0; |
| 115 | - $animate = $this->makeAnimate($last_frame_video, $end_wallpaper, '', $signature_x, $signature_y, $font); | 115 | + $signature_y = -20; |
| 116 | - | 116 | + $animate = $this->makeAnimate($last_frame_video, $end_wallpaper, '', $signature_x, $signature_y, $font); |
| 117 | - $output = $this->getTempPath('.mp4',false); | 117 | + |
| 118 | - | 118 | + $output = $this->getTempPath('.mp4',false); |
| 119 | - $cmd = $this->ffmpeg . ' -y ' . | 119 | + |
| 120 | - ' -i ' . escapeshellarg($image). | 120 | + $cmd = $this->ffmpeg . ' -y ' . |
| 121 | - ' -i ' . escapeshellarg($watermark). | 121 | + ' -i ' . escapeshellarg($image). |
| 122 | - ' -i ' . escapeshellarg($bgm) . | 122 | + ' -i ' . escapeshellarg($watermark). |
| 123 | - ' -i ' . escapeshellarg($animate) . | 123 | + ' -i ' . escapeshellarg($bgm) . |
| 124 | - ' -filter_complex "[0:0] ' . $this->getTextContentString(). | 124 | + ' -i ' . escapeshellarg($animate) . |
| 125 | - '[text];[text][1:0]overlay=20:20[water];' . | 125 | + ' -filter_complex "[0:0] ' . $this->getTextContentString(). |
| 126 | - '[water][2:a][3:v][3:a]concat=n=2:v=1:a=1[v][a]" '. | 126 | + '[text];[text][1:0]overlay=20:20[water];' . |
| 127 | - ' -map [v] -map [a] '. | 127 | + '[water][2:a][3:v][3:a]concat=n=2:v=1:a=1[v][a]" '. |
| 128 | - ' -c:v libx264 -bt 256k -r 25' . | 128 | + ' -map [v] -map [a] '. |
| 129 | - ' -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' | 129 | + ' -c:v libx264 -bt 256k -r 25' . |
| 130 | - . escapeshellarg($output); | 130 | + ' -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' |
| 131 | - | 131 | + . escapeshellarg($output); |
| 132 | - if (!$this->execmd($cmd)) return; | 132 | + |
| 133 | - | 133 | + if (!$this->execmd($cmd)) return; |
| 134 | - $video_info = $this->mediainfo($output); | 134 | + |
| 135 | - } | 135 | + $video_info = $this->mediainfo($output); |
| 136 | + } | ||
| 136 | 137 | ||
| 137 | - $this->immerse->query()->update([ | 138 | + $this->immerse->url = Str::of($output)->replace(Storage::disk('public')->path(''), ''); |
| 138 | - 'url' => str_replace(Storage::disk('public')->path(''),'',$output), | 139 | + $this->immerse->state = 1; |
| 139 | - 'state' => 1, | 140 | + $this->immerse->duration = $video_info['format']['duration'] ?? 0.00; |
| 140 | - 'duration' => $video_info['format']['duration'] ?? 0, | 141 | + $this->immerse->size = $video_info['format']['size']; |
| 141 | - 'size' => $video_info['format']['size'], | 142 | + $this->immerse->save(); |
| 142 | - ]); | 143 | + }catch (\Exception $exception){ |
| 144 | + $this->immerse->state = 2; | ||
| 145 | + $this->immerse->save(); | ||
| 146 | + Log::channel('daily')->error($exception->getMessage()); | ||
| 147 | + } | ||
| 143 | } | 148 | } |
| 144 | 149 | ||
| 145 | /*** | 150 | /*** |
| ... | @@ -249,7 +254,7 @@ class UserMakeImages implements ShouldQueue | ... | @@ -249,7 +254,7 @@ class UserMakeImages implements ShouldQueue |
| 249 | 254 | ||
| 250 | public function getTextContentString() | 255 | public function getTextContentString() |
| 251 | { | 256 | { |
| 252 | - $components = $this->adminMakeVideo->temp()->first()->components()->get(); | 257 | + $components = $this->immerse->temp()->first()->components()->get(); |
| 253 | 258 | ||
| 254 | $font = Storage::disk('public')->path('ffmpeg/arialuni.ttf'); | 259 | $font = Storage::disk('public')->path('ffmpeg/arialuni.ttf'); |
| 255 | 260 | ||
| ... | @@ -258,7 +263,7 @@ class UserMakeImages implements ShouldQueue | ... | @@ -258,7 +263,7 @@ class UserMakeImages implements ShouldQueue |
| 258 | foreach ($components as $component) { | 263 | foreach ($components as $component) { |
| 259 | switch ($component->name){ | 264 | switch ($component->name){ |
| 260 | case 'one_poem': | 265 | case 'one_poem': |
| 261 | - $content = $this->adminMakeVideo->poem->content; | 266 | + $content = $this->immerse->poem->content; |
| 262 | $text_file = $this->getTempPath('.txt'); | 267 | $text_file = $this->getTempPath('.txt'); |
| 263 | file_put_contents($text_file, $content); | 268 | file_put_contents($text_file, $content); |
| 264 | 269 | ||
| ... | @@ -310,7 +315,7 @@ class UserMakeImages implements ShouldQueue | ... | @@ -310,7 +315,7 @@ class UserMakeImages implements ShouldQueue |
| 310 | 'box=1:boxcolor=' . $text_bg_color . '@' . $opacity . '", '; | 315 | 'box=1:boxcolor=' . $text_bg_color . '@' . $opacity . '", '; |
| 311 | break; | 316 | break; |
| 312 | case 'feel': | 317 | case 'feel': |
| 313 | - $content = $this->adminMakeVideo->feel; | 318 | + $content = $this->immerse->feel; |
| 314 | $text_color = $component->text_color ?? 'white'; | 319 | $text_color = $component->text_color ?? 'white'; |
| 315 | $text_bg_color = $component->text_bg_color ?? '0xd0cdcc'; | 320 | $text_bg_color = $component->text_bg_color ?? '0xd0cdcc'; |
| 316 | $opacity = $component->opacity ? $component->opacity / 100 : '0.5'; | 321 | $opacity = $component->opacity ? $component->opacity / 100 : '0.5'; | ... | ... |
| ... | @@ -15,6 +15,7 @@ use Illuminate\Queue\InteractsWithQueue; | ... | @@ -15,6 +15,7 @@ use Illuminate\Queue\InteractsWithQueue; |
| 15 | use Illuminate\Queue\SerializesModels; | 15 | use Illuminate\Queue\SerializesModels; |
| 16 | use Illuminate\Support\Facades\Log; | 16 | use Illuminate\Support\Facades\Log; |
| 17 | use Illuminate\Support\Facades\Storage; | 17 | use Illuminate\Support\Facades\Storage; |
| 18 | +use Illuminate\Support\Str; | ||
| 18 | 19 | ||
| 19 | class UserMakeVideo implements ShouldQueue | 20 | class UserMakeVideo implements ShouldQueue |
| 20 | { | 21 | { |
| ... | @@ -56,7 +57,7 @@ class UserMakeVideo implements ShouldQueue | ... | @@ -56,7 +57,7 @@ class UserMakeVideo implements ShouldQueue |
| 56 | public function handle() | 57 | public function handle() |
| 57 | { | 58 | { |
| 58 | $file = Storage::disk('public')->path($this->resource_url); | 59 | $file = Storage::disk('public')->path($this->resource_url); |
| 59 | - $is_bgm = isset($this->immerse->bgm); | 60 | + $is_bgm = isset($this->immerse->bgm) && $this->immerse->bgm != ''; |
| 60 | $bgm = Storage::disk('public')->path($this->immerse->bgm); | 61 | $bgm = Storage::disk('public')->path($this->immerse->bgm); |
| 61 | 62 | ||
| 62 | // 1.getmediainfo 记录时长,音频视频取最长。 | 63 | // 1.getmediainfo 记录时长,音频视频取最长。 |
| ... | @@ -119,63 +120,68 @@ class UserMakeVideo implements ShouldQueue | ... | @@ -119,63 +120,68 @@ class UserMakeVideo implements ShouldQueue |
| 119 | return; | 120 | return; |
| 120 | } | 121 | } |
| 121 | 122 | ||
| 122 | - $end_wallpaper = Storage::disk('public')->path('ffmpeg') . "/end_wallpaper.png"; | 123 | + try{ |
| 123 | - $thumbnail = Storage::disk('public')->path('ffmpeg') . "/thumbnail.png"; | 124 | + $end_wallpaper = Storage::disk('public')->path('ffmpeg') . "/end_wallpaper.png"; |
| 124 | - $font = Storage::disk('public')->path('ffmpeg') . "/arialuni.ttf"; | 125 | + $thumbnail = Storage::disk('public')->path('ffmpeg') . "/thumbnail.png"; |
| 126 | + $font = Storage::disk('public')->path('ffmpeg') . "/arialuni.ttf"; | ||
| 127 | + | ||
| 128 | + $user = User::query()->find($this->immerse->user_id); | ||
| 129 | + $signature = $user->nickname ?? $user->email; | ||
| 130 | + | ||
| 131 | + // 生成贴纸和签名 | ||
| 132 | + $end_wallpaper = $this->wallpaperWithSignature($end_wallpaper, $thumbnail, $signature, $font); | ||
| 133 | + | ||
| 134 | + // 截取最后一帧 | ||
| 135 | + $last_frame_video = $this->getTempPath(); | ||
| 136 | + $this->width = $width = $media_info['streams'][0]['width']; | ||
| 137 | + $height = $media_info['streams'][0]['height']; | ||
| 138 | + $size = $width . 'x' . $height; | ||
| 139 | + $time_length = 0.7; | ||
| 140 | + $r = 24; | ||
| 141 | + $frame_n = $media_info['streams'][0]['nb_frames'] - 2; | ||
| 142 | + $cmd = $this->ffmpeg . ' -y -i ' . escapeshellarg($file) . | ||
| 143 | + " -f lavfi -i nullsrc=s={$size}:d={$time_length}:r={$r} -f lavfi -i aevalsrc=0:duration={$time_length}" . | ||
| 144 | + " -filter_complex \"[0:v]select='eq(n,{$frame_n})',setpts=PTS-STARTPTS[lastframe];[1:v][lastframe]overlay[v]\"" . | ||
| 145 | + ' -map [v] -map 2:a ' . escapeshellarg($last_frame_video); | ||
| 146 | + if (!$this->execmd($cmd)) return; | ||
| 125 | 147 | ||
| 126 | - $user = User::query()->find($this->immerse->user_id); | ||
| 127 | - $signature = $user->nickname; | ||
| 128 | 148 | ||
| 129 | - // 生成贴纸和签名 | 149 | + $signature_x = 0; |
| 130 | - $end_wallpaper = $this->wallpaperWithSignature($end_wallpaper, $thumbnail, $signature, $font); | 150 | + $signature_y = -20; |
| 151 | + $animate = $this->makeAnimate($last_frame_video, $end_wallpaper, '', $signature_x, $signature_y, $font); | ||
| 131 | 152 | ||
| 132 | - // 截取最后一帧 | 153 | + $watermark = Storage::disk('public')->path('ffmpeg/LOGO_eng.png'); |
| 133 | - $last_frame_video = $this->getTempPath(); | 154 | + |
| 134 | - $this->width = $width = $media_info['streams'][0]['width']; | 155 | + $video = $this->getTempPath('.mp4',false); |
| 135 | - $height = $media_info['streams'][0]['height']; | 156 | + $cmd = $this->ffmpeg . ' -y '. |
| 136 | - $size = $width . 'x' . $height; | 157 | + ' -i ' . escapeshellarg($file). |
| 137 | - $time_length = 0.7; | 158 | + ' -i ' . escapeshellarg($animate). |
| 138 | - $r = 24; | 159 | + ' -i ' . escapeshellarg($watermark). |
| 139 | - $frame_n = $media_info['streams'][0]['nb_frames'] - 2; | 160 | + $audio_input . |
| 140 | - $cmd = $this->ffmpeg . ' -y -i ' . escapeshellarg($file) . | 161 | + ' -filter_complex "[0:0] ' . |
| 141 | - " -f lavfi -i nullsrc=s={$size}:d={$time_length}:r={$r} -f lavfi -i aevalsrc=0:duration={$time_length}" . | 162 | + $this->getTextContentString(). |
| 142 | - " -filter_complex \"[0:v]select='eq(n,{$frame_n})',setpts=PTS-STARTPTS[lastframe];[1:v][lastframe]overlay[v]\"" . | 163 | + ' [text];[text]'. |
| 143 | - ' -map [v] -map 2:a ' . escapeshellarg($last_frame_video); | 164 | + ' [2:v]overlay=20:20[water];[water]' . $audio_filter . '[1:0][1:1] concat=n=2:v=1:a=1[v][a]" ' . |
| 144 | - if (!$this->execmd($cmd)) return; | 165 | + ' -map [v] -map [a]'. |
| 145 | - | 166 | + ' -c:v libx264 -bt 256k -r 25' . |
| 146 | - | 167 | + ' -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' . |
| 147 | - $signature_x = 0; | 168 | + escapeshellarg($video); |
| 148 | - $signature_y = -20; | 169 | + |
| 149 | - $animate = $this->makeAnimate($last_frame_video, $end_wallpaper, '', $signature_x, $signature_y, $font); | 170 | + if (!$this->execmd($cmd)) return; |
| 150 | - | 171 | + |
| 151 | - $watermark = Storage::disk('public')->path('ffmpeg/LOGO_eng.png'); | 172 | + // 全部合成以后创建 临境 |
| 152 | - | 173 | + $video_info = $this->mediainfo($video); |
| 153 | - $video = $this->getTempPath('.mp4',false); | 174 | + |
| 154 | - $cmd = $this->ffmpeg . ' -y '. | 175 | + $this->immerse->url = Str::of($video)->replace(Storage::disk('public')->path(''), ''); |
| 155 | - ' -i ' . escapeshellarg($file). | 176 | + $this->immerse->state = 1; |
| 156 | - ' -i ' . escapeshellarg($animate). | 177 | + $this->immerse->duration = $video_info['format']['duration'] ?? 0.00; |
| 157 | - ' -i ' . escapeshellarg($watermark). | 178 | + $this->immerse->size = $video_info['format']['size']; |
| 158 | - $audio_input . | 179 | + $this->immerse->save(); |
| 159 | - ' -filter_complex "[0:0] ' . | 180 | + }catch (\Exception $exception){ |
| 160 | - $this->getTextContentString(). | 181 | + $this->immerse->state = 2; |
| 161 | - ' [text];[text]'. | 182 | + $this->immerse->save(); |
| 162 | - ' [2:v]overlay=20:20[water];[water]' . $audio_filter . '[1:0][1:1] concat=n=2:v=1:a=1[v][a]" ' . | 183 | + Log::channel('daily')->error($exception->getMessage()); |
| 163 | - ' -map [v] -map [a]'. | 184 | + } |
| 164 | - ' -c:v libx264 -bt 256k -r 25' . | ||
| 165 | - ' -ar 44100 -ac 2 -qmin 30 -qmax 60 -profile:v baseline -preset fast ' . | ||
| 166 | - escapeshellarg($video); | ||
| 167 | - | ||
| 168 | - if (!$this->execmd($cmd)) return; | ||
| 169 | - | ||
| 170 | - // 全部合成以后创建 临境 | ||
| 171 | - $video_info = $this->mediainfo($video); | ||
| 172 | - | ||
| 173 | - $this->immerse->query()->update([ | ||
| 174 | - 'url' => str_replace(Storage::disk('public')->path(''),'',$output), | ||
| 175 | - 'state' => 1, | ||
| 176 | - 'duration' => $video_info['format']['duration'] ?? 0, | ||
| 177 | - 'size' => $video_info['format']['size'], | ||
| 178 | - ]); | ||
| 179 | 185 | ||
| 180 | return; | 186 | return; |
| 181 | } | 187 | } |
| ... | @@ -677,6 +683,6 @@ class UserMakeVideo implements ShouldQueue | ... | @@ -677,6 +683,6 @@ class UserMakeVideo implements ShouldQueue |
| 677 | } | 683 | } |
| 678 | } | 684 | } |
| 679 | 685 | ||
| 680 | - return ceil($this->width * $width / 10 / $max_len); | 686 | + return ceil($this->width * $width / 100 / $max_len); |
| 681 | } | 687 | } |
| 682 | } | 688 | } | ... | ... |
| ... | @@ -27,20 +27,6 @@ class Immerse extends Model | ... | @@ -27,20 +27,6 @@ class Immerse extends Model |
| 27 | return Storage::disk('public')->url($url); | 27 | return Storage::disk('public')->url($url); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | - public function getThumbnailAttribute($url) | ||
| 31 | - { | ||
| 32 | - | ||
| 33 | - if ($url == '') return $url; | ||
| 34 | - | ||
| 35 | - return Storage::disk('public')->url($url); | ||
| 36 | - } | ||
| 37 | - | ||
| 38 | - public function getBgmAttribute($url) | ||
| 39 | - { | ||
| 40 | - if ($url == '') return $url; | ||
| 41 | - | ||
| 42 | - return Storage::disk('public')->url($url); | ||
| 43 | - } | ||
| 44 | 30 | ||
| 45 | public function poem() | 31 | public function poem() |
| 46 | { | 32 | { | ... | ... |
| ... | @@ -40,12 +40,12 @@ Route::prefix('v1')->namespace('App\Http\Controllers\V1')->group(function (Route | ... | @@ -40,12 +40,12 @@ Route::prefix('v1')->namespace('App\Http\Controllers\V1')->group(function (Route |
| 40 | /** 用户信息*/ | 40 | /** 用户信息*/ |
| 41 | $api->get('/user', 'UserController@user')->middleware('auth:sanctum'); | 41 | $api->get('/user', 'UserController@user')->middleware('auth:sanctum'); |
| 42 | 42 | ||
| 43 | - /** 上传作品 */ | 43 | + /** 我的作品 */ |
| 44 | $api->get('/my/videos', 'UserController@videos')->middleware('auth:sanctum'); | 44 | $api->get('/my/videos', 'UserController@videos')->middleware('auth:sanctum'); |
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | /** 临境 */ | 47 | /** 临境 */ |
| 48 | - $api->apiResource('/immersive', 'ImmerseController'); | 48 | + $api->apiResource('/immersive', 'ImmerseController')->middleware('auth:sanctum'); |
| 49 | 49 | ||
| 50 | /** 众妙 */ | 50 | /** 众妙 */ |
| 51 | $api->get('/packpoem', 'HomeController@packpoem'); | 51 | $api->get('/packpoem', 'HomeController@packpoem'); | ... | ... |
-
Please register or login to post a comment