|
@@ -0,0 +1,158 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Console\Commands;
|
|
|
+
|
|
|
+use App\Libraries\CommonHelper;
|
|
|
+use Illuminate\Console\Command;
|
|
|
+use Illuminate\Support\Carbon;
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
+use Dcat\Admin\Traits\HasUploadedFile;
|
|
|
+use FFMpeg\FFMpeg;
|
|
|
+use FFMpeg\Coordinate\TimeCode;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * 生成预览10秒视频
|
|
|
+ *
|
|
|
+ * @author <EMAIL>
|
|
|
+ * 运行命令:php artisan command:preview-video
|
|
|
+ */
|
|
|
+
|
|
|
+class GeneratePreviewVideo extends Command
|
|
|
+{
|
|
|
+ use HasUploadedFile;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The name and signature of the console command.
|
|
|
+ *
|
|
|
+ * @var string
|
|
|
+ */
|
|
|
+ protected $signature = 'command:preview-video';
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The console command description.
|
|
|
+ *
|
|
|
+ * @var string
|
|
|
+ */
|
|
|
+ protected $description = '生成预览视频';
|
|
|
+
|
|
|
+ public $timeSecond = 5;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Execute the console command.
|
|
|
+ *
|
|
|
+ * @return int
|
|
|
+ */
|
|
|
+ public function handle()
|
|
|
+ {
|
|
|
+ $disk = $this->disk('oss');
|
|
|
+
|
|
|
+ $reslut = DB::table('site_preview_video')
|
|
|
+ ->where('status', '==', 0) // 过滤非空 video 字段
|
|
|
+ ->orderBy('id') // 按主键排序确保顺序
|
|
|
+ ->get();
|
|
|
+
|
|
|
+ foreach ($reslut as $item) {
|
|
|
+ $video_url = $this->ossUrl($item->video_url);
|
|
|
+ $fileName = basename($video_url);
|
|
|
+ $fileInfo = pathinfo($fileName);
|
|
|
+ $previewName = $fileInfo['filename'] . '_preview.' . $fileInfo['extension'];
|
|
|
+ $previewPath = storage_path('tmp/previews/'.$previewName);
|
|
|
+ $this->generatePreview($video_url, $previewPath);
|
|
|
+ dd($previewPath);
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //$this->importVideo();
|
|
|
+ return Command::SUCCESS;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function ossUrl($url)
|
|
|
+ {
|
|
|
+ if (strpos($url, 'http:') === 0 || strpos($url, 'https:') === 0) {
|
|
|
+ return $url;
|
|
|
+ }
|
|
|
+ return "https://mietublcom.oss-cn-hongkong.aliyuncs.com".'/'.$url;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public function generatePreview($inputUrl, $outputPath) {
|
|
|
+ $ffmpeg = FFMpeg::create([
|
|
|
+ 'ffmpeg.binaries' => '/usr/bin/ffmpeg',
|
|
|
+ 'ffprobe.binaries' => '/usr/bin/ffprobe',
|
|
|
+ 'timeout' => 300
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $video = $ffmpeg->open($inputUrl);
|
|
|
+ $video->filters()->clip(TimeCode::fromSeconds(0), TimeCode::fromSeconds($this->timeSecond));
|
|
|
+
|
|
|
+ // 输出为H.264编码的MP4
|
|
|
+ $format = new \FFMpeg\Format\Video\X264('aac');
|
|
|
+ $video->save($format, $outputPath);
|
|
|
+
|
|
|
+ return $outputPath;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /*ssssssss
|
|
|
+ * 把旧数据导入新的预览表
|
|
|
+ */
|
|
|
+ function importVideo()
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ // 分批处理数据,避免内存溢出
|
|
|
+ DB::table('site_album')
|
|
|
+ ->where('video', '<>', '[]') // 过滤非空 video 字段
|
|
|
+ ->orderBy('id') // 按主键排序确保顺序
|
|
|
+ ->chunkById(10000, function ($albums) { // 每次处理 100 条
|
|
|
+ $insertData = [];
|
|
|
+
|
|
|
+ foreach ($albums as $album) {
|
|
|
+ // 跳过无效 JSON 数据
|
|
|
+ $videos = json_decode($album->video, true);
|
|
|
+ if (json_last_error() !== JSON_ERROR_NONE || !is_array($videos)) {
|
|
|
+ Log::warning("Invalid JSON in album ID: {$album->id}");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach ($videos as $video) {
|
|
|
+ // 校验必要字段存在性
|
|
|
+ if (empty($video['video_src']) || empty($video['cover'])) {
|
|
|
+ Log::warning("Missing video_src or cover in album ID: {$album->id}");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理 URL 长度限制
|
|
|
+ $videoUrl = substr($video['video_src'], 0, 255);
|
|
|
+
|
|
|
+ // 构建插入数据
|
|
|
+ $insertData[] = [
|
|
|
+ 'video_url' => $videoUrl,
|
|
|
+ 'preview_url' => '',
|
|
|
+ 'status' => 0,
|
|
|
+ 'created_at' => Carbon::now(),
|
|
|
+ 'updated_at' => Carbon::now(),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 插入剩余数据
|
|
|
+ if (!empty($insertData)) {
|
|
|
+ DB::table('site_preview_video')->insert($insertData);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return true;
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error("Video import failed: " . $e->getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|