李帅

1.优化ffmpeg命令,适配各种类型视频

...@@ -5,7 +5,6 @@ namespace App\Jobs; ...@@ -5,7 +5,6 @@ namespace App\Jobs;
5 use App\Models\Immerse; 5 use App\Models\Immerse;
6 use App\Models\VideoTemp; 6 use App\Models\VideoTemp;
7 use Illuminate\Bus\Queueable; 7 use Illuminate\Bus\Queueable;
8 -use Illuminate\Contracts\Queue\ShouldBeUnique;
9 use Illuminate\Contracts\Queue\ShouldQueue; 8 use Illuminate\Contracts\Queue\ShouldQueue;
10 use Illuminate\Foundation\Bus\Dispatchable; 9 use Illuminate\Foundation\Bus\Dispatchable;
11 use Illuminate\Queue\InteractsWithQueue; 10 use Illuminate\Queue\InteractsWithQueue;
...@@ -25,6 +24,8 @@ class AdminMakeImmerse implements ShouldQueue ...@@ -25,6 +24,8 @@ class AdminMakeImmerse implements ShouldQueue
25 24
26 protected $ffprobe; 25 protected $ffprobe;
27 26
27 + protected $media_info;
28 +
28 protected $output_width; 29 protected $output_width;
29 30
30 protected $output_height; 31 protected $output_height;
...@@ -56,9 +57,8 @@ class AdminMakeImmerse implements ShouldQueue ...@@ -56,9 +57,8 @@ class AdminMakeImmerse implements ShouldQueue
56 $template = $adminMakeVideo->temp->where('state',1)->first(); 57 $template = $adminMakeVideo->temp->where('state',1)->first();
57 58
58 // 素材准备 59 // 素材准备
59 - $drawtext = $this->getTextContentString();
60 $watermark = $this->getAbsolutePath('images/LOGO_eng.png'); 60 $watermark = $this->getAbsolutePath('images/LOGO_eng.png');
61 - $is_bgm = $template->bg_music == 1; 61 + $is_bgm = $template->bg_music == 1; //是否手动上传背景音
62 $bgm = $this->getAbsolutePath($template->bgm_url); 62 $bgm = $this->getAbsolutePath($template->bgm_url);
63 63
64 // 区分类型 64 // 区分类型
...@@ -66,6 +66,8 @@ class AdminMakeImmerse implements ShouldQueue ...@@ -66,6 +66,8 @@ class AdminMakeImmerse implements ShouldQueue
66 $file = $this->getAbsolutePath($adminMakeVideo->video_url); 66 $file = $this->getAbsolutePath($adminMakeVideo->video_url);
67 // 分析视频 67 // 分析视频
68 $media_info = $this->mediainfo($file); 68 $media_info = $this->mediainfo($file);
69 + // 素材准备
70 + $drawtext = $this->getTextContentString();
69 71
70 if ($media_info['format']['nb_streams'] >= 2) { 72 if ($media_info['format']['nb_streams'] >= 2) {
71 /** 音频视频轨都有 */ 73 /** 音频视频轨都有 */
...@@ -262,6 +264,8 @@ class AdminMakeImmerse implements ShouldQueue ...@@ -262,6 +264,8 @@ class AdminMakeImmerse implements ShouldQueue
262 264
263 public function mediainfo($file) 265 public function mediainfo($file)
264 { 266 {
267 + if ($this->media_info) return $this->media_info;
268 +
265 $cmd = $this->ffprobe . ' -v quiet -print_format json -show_format -show_streams ' . escapeshellarg($file); 269 $cmd = $this->ffprobe . ' -v quiet -print_format json -show_format -show_streams ' . escapeshellarg($file);
266 $output = $this->execmd($cmd); 270 $output = $this->execmd($cmd);
267 $data = json_decode($output, true); 271 $data = json_decode($output, true);
...@@ -269,6 +273,7 @@ class AdminMakeImmerse implements ShouldQueue ...@@ -269,6 +273,7 @@ class AdminMakeImmerse implements ShouldQueue
269 $output = mb_convert_encoding($output, "UTF-8"); 273 $output = mb_convert_encoding($output, "UTF-8");
270 $data = json_decode($output, true); 274 $data = json_decode($output, true);
271 } 275 }
276 + $this->media_info = $data;
272 return $data; 277 return $data;
273 } 278 }
274 279
...@@ -372,19 +377,44 @@ class AdminMakeImmerse implements ShouldQueue ...@@ -372,19 +377,44 @@ class AdminMakeImmerse implements ShouldQueue
372 case 'every_poem': 377 case 'every_poem':
373 case 'one_poem': 378 case 'one_poem':
374 $content = $this->adminMakeVideo->poem->content; 379 $content = $this->adminMakeVideo->poem->content;
375 - $text_file = $this->getAbsolutePath($this->getTempPath('.txt','text')); 380 + $contents = explode("\n",$content); //计算诗词行数
376 - file_put_contents($text_file, $content); 381 + if ($this->media_info['format']['duration'] < 2 * count($contents)) {
377 - $drawtext .= 'drawtext="'. 382 + $text_file = $this->getAbsolutePath($this->getTempPath('.txt','text'));
378 - 'fontfile=' . escapeshellarg($font_file) . ':' . 383 + file_put_contents($text_file, $content);
379 - 'textfile=' . escapeshellarg($text_file) . ':' . 384 + $drawtext .= 'drawtext="'.
380 - 'fontsize=' . $this->calcFontSize($component->font_size) . ':' . 385 + 'fontfile=' . escapeshellarg($font_file) . ':' .
381 - 'fontcolor=' . $text_color . '@' . $opacity . ':' . 386 + 'textfile=' . escapeshellarg($text_file) . ':' .
382 - 'x=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][0]) . ':' . 387 + 'fontsize=' . $this->calcFontSize($component->font_size) . ':' .
383 - 'y=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][1]) . ':' . 388 + 'fontcolor=' . $text_color . '@' . $opacity . ':' .
384 - 'fix_bounds='. $fix_bounds . ':' . 389 + 'x=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][0]) . ':' .
385 - 'box=1:boxborderw='. $text_bg_box . ':' . 390 + 'y=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][1]) . ':' .
386 - 'boxcolor=' . $text_bg_color . '@' . $opacity . '", '; 391 + 'fix_bounds='. $fix_bounds . ':' .
387 - 392 + 'box=1:boxborderw='. $text_bg_box . ':' .
393 + 'boxcolor=' . $text_bg_color . '@' . $opacity . '", ';
394 +
395 + }else{
396 + $FID = $FOD = 1.0;
397 + if ($this->media_info['format']['duration'] > 3 * count($contents)) $FID = $FOD = 1.5;
398 +
399 + $round = round($this->media_info['format']['duration'] / count($contents),1);
400 + foreach ($contents as $key => $content){
401 + $DS = $key * $round;
402 + $DE = $DS + $round;
403 + $text_file = $this->getAbsolutePath($this->getTempPath('.txt','text'));
404 + file_put_contents($text_file, $content);
405 + $drawtext .= 'drawtext="'.
406 + 'fontfile=' . escapeshellarg($font_file) . ':' .
407 + 'textfile=' . escapeshellarg($text_file) . ':' .
408 + 'fontsize=' . $this->calcFontSize($component->font_size) . ':' .
409 +// 'fontcolor=' . $text_color . '@' . $opacity . ':' .
410 + 'fontcolor_expr=' . $text_color . '%{eif\\: clip(255*(1*between(t\\, ' . $DE . ' + ' . $FID . '\\, ' . $DE . ' - ' . $FOD . ') + ((t - ' . $DS . ')/' . $FID . ')*between(t\\, ' . $DS . '\\, ' . $DS . ' + ' . $FID . ') + (-(t - ' . $DE . ')/' . $FOD . ')*between(t\\, ' . $DE . ' - ' . $FOD . '\\, ' . $DE . ') )\\, 0\\, 255) \\: x\\: 2 }:' .
411 + 'x=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][0]) . ':' .
412 + 'y=' . escapeshellarg(VideoTemp::POSITION_FFMPEG[$component->position][1]) . ':' .
413 + 'fix_bounds='. $fix_bounds . ':' .
414 + 'box=1:boxborderw='. $text_bg_box . ':' .
415 + 'boxcolor=' . $text_bg_color . '@' . $opacity . '", ';
416 + }
417 + }
388 break; 418 break;
389 case 'weather': 419 case 'weather':
390 $content = $this->adminMakeVideo->weather; 420 $content = $this->adminMakeVideo->weather;
......