Browse Source

视频预览

moshaorui 3 weeks ago
parent
commit
6069571787

+ 158 - 0
app/Console/Commands/GeneratePreviewVideo.php

@@ -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;
+        }
+    }
+
+
+
+
+}

+ 35 - 0
database/migrations/2025_03_19_124906_create_preview_video_table.php

@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('site_preview_video', function (Blueprint $table) {
+            $table->id()->key()->autoIncrement();
+            $table->string('video_url');
+            $table->string('preview_url');
+            $table->tinyInteger('status')->default(0);
+            $table->timestamp('created_at', 0);
+            $table->timestamp('updated_at', 0);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('preview_video');
+    }
+};