Browse Source

Merge branch 'test' into gpt

lh 2 tháng trước cách đây
mục cha
commit
d0016aabd5

+ 3 - 4
app/Console/Commands/CheckVideoGenerationTasksCommand.php

@@ -90,7 +90,7 @@ class CheckVideoGenerationTasksCommand extends Command
                 // 查询视频生成任务状态
                 $videoTask = DB::table('mp_generate_video_tasks')
                     ->where('id', $videoTaskId)
-                    ->select('id', 'status', 'result_url', 'last_frame_url', 'error_message', 'result_json', 'extra_params')
+                    ->select('id', 'status', 'result_url', 'compressed_url', 'last_frame_url', 'error_message', 'result_json', 'extra_params')
                     ->first();
 
                 if (!$videoTask) {
@@ -106,9 +106,8 @@ class CheckVideoGenerationTasksCommand extends Command
                 // 根据任务状态更新分镜表
                 if ($videoTask->status === 'success') {
                     $updateData['video_task_status'] = '已完成';
-                    $updateData['video_url'] = $videoTask->result_url;
-                    $compressed_video_url = compressVideo($updateData['video_url']);
-                    if ($compressed_video_url) $updateData['preview_video_url'] = $compressed_video_url;
+                    $updateData['origin_video_url'] = $videoTask->result_url;
+                    $updateData['video_url'] = $videoTask->compressed_url ?: $videoTask->result_url;
                     $updateData['current_type'] = 2;
                     
                     // 如果有尾帧图片,也更新

+ 188 - 0
app/Console/Test/TestCommand.php

@@ -50,6 +50,11 @@ class TestCommand extends Command
      */
     public function handle()
     {
+
+        $this->handleHistoryTasks();
+        $this->handleHistorySegments();
+        dd('end!');
+
         // dd(testStoryboardParsing(''));
         $content = "";
         dd(handleScriptContent($content));
@@ -329,4 +334,187 @@ class TestCommand extends Command
         dd('成功!');
         // \Log::info('generate_json: '.$generate_json);
     }
+
+    /**
+     * 处理历史视频任务 - 压缩视频并更新 compressed_url
+     */
+    private function handleHistoryTasks()
+    {
+        $this->info('开始处理历史视频任务...');
+        
+        try {
+            // 查询所有 result_url 有值但 compressed_url 为空的成功任务
+            $tasks = DB::table('mp_generate_video_tasks')
+                ->where('status', 'success')
+                ->whereNotNull('result_url')
+                ->where('result_url', '!=', '')
+                ->where(function($query) {
+                    $query->whereNull('compressed_url')
+                          ->orWhere('compressed_url', '');
+                })
+                ->select('id', 'result_url')
+                ->get();
+            
+            $total = $tasks->count();
+            $this->info("找到 {$total} 个需要处理的任务");
+            
+            if ($total === 0) {
+                $this->info('没有需要处理的任务');
+                return;
+            }
+            
+            $successCount = 0;
+            $failCount = 0;
+            
+            foreach ($tasks as $index => $task) {
+                $taskId = $task->id;
+                $resultUrl = $task->result_url;
+                
+                $current = $index + 1;
+                $this->info("处理任务 [{$taskId}] ({$current}/{$total})");
+                
+                try {
+                    // 压缩视频
+                    $compressedUrl = compressVideo($resultUrl);
+                    
+                    // 如果压缩失败,使用原始URL
+                    $finalUrl = $compressedUrl ?: $resultUrl;
+                    
+                    // 更新数据库
+                    $updated = DB::table('mp_generate_video_tasks')
+                        ->where('id', $taskId)
+                        ->update([
+                            'compressed_url' => $finalUrl,
+                            'updated_at' => date('Y-m-d H:i:s')
+                        ]);
+                    
+                    if ($updated) {
+                        $successCount++;
+                        if ($compressedUrl) {
+                            $this->info("✓ 任务 [{$taskId}] 压缩成功");
+                        } else {
+                            $this->warn("⚠ 任务 [{$taskId}] 压缩失败,使用原始URL");
+                        }
+                    } else {
+                        $failCount++;
+                        $this->error("✗ 任务 [{$taskId}] 更新失败");
+                    }
+                    
+                } catch (\Exception $e) {
+                    $failCount++;
+                    $this->error("✗ 任务 [{$taskId}] 处理异常: " . $e->getMessage());
+                    dLog('command')->error('处理历史视频任务异常', [
+                        'task_id' => $taskId,
+                        'error' => $e->getMessage()
+                    ]);
+                }
+                
+                // 每处理10个任务休息一下,避免压力过大
+                if ($current % 10 === 0) {
+                    sleep(1);
+                }
+            }
+            
+            $this->info("历史视频任务处理完成!");
+            $this->info("总数: {$total}, 成功: {$successCount}, 失败: {$failCount}");
+            
+        } catch (\Exception $e) {
+            $this->error('处理历史视频任务失败: ' . $e->getMessage());
+            dLog('command')->error('处理历史视频任务失败', ['error' => $e->getMessage()]);
+        }
+    }
+
+    /**
+     * 处理历史分镜数据 - 根据视频任务更新分镜表
+     */
+    private function handleHistorySegments()
+    {
+        $this->info('开始处理历史分镜数据...');
+        
+        try {
+            // 查询所有有 video_task_id 的分镜
+            $segments = DB::table('mp_episode_segments')
+                ->whereNotNull('video_task_id')
+                ->where('video_task_id', '>', 0)
+                ->select('segment_id', 'video_task_id')
+                ->get();
+            
+            $total = $segments->count();
+            $this->info("找到 {$total} 个需要处理的分镜");
+            
+            if ($total === 0) {
+                $this->info('没有需要处理的分镜');
+                return;
+            }
+            
+            $successCount = 0;
+            $skipCount = 0;
+            $failCount = 0;
+            
+            foreach ($segments as $index => $segment) {
+                $segmentId = $segment->segment_id;
+                $videoTaskId = $segment->video_task_id;
+                
+                $current = $index + 1;
+                $this->info("处理分镜 [{$segmentId}] ({$current}/{$total})");
+                
+                try {
+                    // 查询对应的视频任务
+                    $videoTask = DB::table('mp_generate_video_tasks')
+                        ->where('id', $videoTaskId)
+                        ->where('status', 'success')
+                        ->whereNotNull('result_url')
+                        ->where('result_url', '!=', '')
+                        ->whereNotNull('compressed_url')
+                        ->where('compressed_url', '!=', '')
+                        ->select('result_url', 'compressed_url')
+                        ->first();
+                    
+                    if (!$videoTask) {
+                        $skipCount++;
+                        $this->warn("⊘ 分镜 [{$segmentId}] 对应的视频任务不存在或未完成");
+                        continue;
+                    }
+                    
+                    // 更新分镜表
+                    $updated = DB::table('mp_episode_segments')
+                        ->where('segment_id', $segmentId)
+                        ->update([
+                            'origin_video_url' => $videoTask->result_url,
+                            'video_url' => $videoTask->compressed_url,
+                            'updated_at' => date('Y-m-d H:i:s')
+                        ]);
+                    
+                    if ($updated) {
+                        $successCount++;
+                        $this->info("✓ 分镜 [{$segmentId}] 更新成功");
+                    } else {
+                        $failCount++;
+                        $this->error("✗ 分镜 [{$segmentId}] 更新失败");
+                    }
+                    
+                } catch (\Exception $e) {
+                    $failCount++;
+                    $this->error("✗ 分镜 [{$segmentId}] 处理异常: " . $e->getMessage());
+                    dLog('command')->error('处理历史分镜数据异常', [
+                        'segment_id' => $segmentId,
+                        'video_task_id' => $videoTaskId,
+                        'error' => $e->getMessage()
+                    ]);
+                }
+                
+                // 每处理10个分镜休息一下
+                if ($current % 10 === 0) {
+                    sleep(1);
+                }
+            }
+            
+            $this->info("历史分镜数据处理完成!");
+            $this->info("总数: {$total}, 成功: {$successCount}, 跳过: {$skipCount}, 失败: {$failCount}");
+            
+        } catch (\Exception $e) {
+            $this->error('处理历史分镜数据失败: ' . $e->getMessage());
+            dLog('command')->error('处理历史分镜数据失败', ['error' => $e->getMessage()]);
+        }
+    }
 }

+ 8 - 25
app/Http/Controllers/Anime/AnimeController.php

@@ -475,14 +475,14 @@ class AnimeController extends BaseController
                                     
                                     // 更新分镜表
                                     $segmentUpdateData = [
-                                        'video_url' => $statusResult['result_url'],
+                                        'origin_video_url' => $statusResult['result_url'],
                                         'video_task_status' => '已完成',
                                         'last_frame_url' => $statusResult['last_frame_url'] ?? '',
                                         'current_type' => 2,
                                         'updated_at' => $now
                                     ];
-                                    $compressed_video_url = compressVideo($segmentUpdateData['video_url']);
-                                    if ($compressed_video_url) $segmentUpdateData['preview_video_url'] = $compressed_video_url;
+                                    $compressed_video_url = compressVideo($statusResult['result_url']);
+                                    $segmentUpdateData['video_url'] = $compressed_video_url ?: $statusResult['result_url'];
                                     
                                     // 只有当video_duration存在且大于0时才更新
                                     if (isset($statusResult['video_duration']) && $statusResult['video_duration'] > 0) {
@@ -576,7 +576,8 @@ class AnimeController extends BaseController
                             'data' => [
                                 'task_id' => $task->id,
                                 'status' => $task->status,
-                                'video_url' => $task->result_url,
+                                'video_url' => $task->compressed_url ?: $task->result_url,
+                                'origin_video_url' => $task->result_url,
                                 'last_frame_url' => $task->last_frame_url,
                                 'error_message' => $task->error_message
                             ]
@@ -933,14 +934,14 @@ class AnimeController extends BaseController
                                         if ($segmentId) {
                                             // 更新分镜表
                                             $segmentUpdateData = [
-                                                'video_url' => $statusResult['result_url'],
+                                                'origin_video_url' => $statusResult['result_url'],
                                                 'video_task_status' => '已完成',
                                                 'last_frame_url' => $statusResult['last_frame_url'] ?? '',
                                                 'current_type' => 2,
                                                 'updated_at' => $now
                                             ];
-                                            $compressed_video_url = compressVideo($segmentUpdateData['video_url']);
-                                            if ($compressed_video_url) $segmentUpdateData['preview_video_url'] = $compressed_video_url;
+                                            $compressed_video_url = compressVideo($statusResult['result_url']);
+                                            $segmentUpdateData['video_url'] = $compressed_video_url ?: $statusResult['result_url'];
                                             
                                             // 只有当video_duration存在且大于0时才更新
                                             if (isset($statusResult['video_duration']) && $statusResult['video_duration'] > 0) {
@@ -1574,24 +1575,6 @@ class AnimeController extends BaseController
             ->orderBy('segment_number')
             ->get();
 
-        if (env('APP_ENV') == 'production') {   // 正式环境才压缩
-            // 循环判断分镜中preview_video_url是否存在,如果没有但video_url有值,则压缩video_url并赋值给preview_video_url
-            foreach ($segments as $segment) {
-                $segment = (array)$segment;
-                if ((empty($segment['preview_video_url']) || $segment['preview_video_url'] === '') 
-                    && !empty($segment['video_url']) && $segment['video_url'] !== '') {
-                    // 压缩视频
-                    $compressedUrl = compressVideo($segment['video_url'], 'videos');
-                    
-                    // 只有压缩成功才更新数据库
-                    if ($compressedUrl !== '') {
-                        DB::table('mp_episode_segments')
-                            ->where('id', $segment['id'])
-                            ->update(['preview_video_url' => $compressedUrl]);
-                    }
-                }
-            }
-        }
 
         // 判断是否有未完成的任务
         $uncompleted_pic_count = DB::table('mp_episode_segments')->where('anime_id', $animeId)

+ 5 - 0
app/Models/MpGenerateVideoTask.php

@@ -23,6 +23,7 @@ class MpGenerateVideoTask extends Model
         'frames',
         'status',
         'result_url',
+        'compressed_url',
         'error_message',
         'extra_params',
         'started_at',
@@ -56,6 +57,10 @@ class MpGenerateVideoTask extends Model
             $updateData['result_url'] = $data['result_url'];
         }
         
+        if (isset($data['compressed_url'])) {
+            $updateData['compressed_url'] = $data['compressed_url'];
+        }
+        
         if (isset($data['last_frame_url'])) {
             $updateData['last_frame_url'] = $data['last_frame_url'];
         }

+ 22 - 15
app/Services/AIGeneration/AIVideoGenerationService.php

@@ -330,14 +330,14 @@ class AIVideoGenerationService
                     
                     // 构建更新数据
                     $segmentUpdateData = [
-                        'video_url' => $statusInfo['result_url'],
+                        'origin_video_url' => $statusInfo['result_url'],
                         'video_task_status' => '已完成',
                         'current_type' => 2,
                         'last_frame_url' => $statusInfo['last_frame_url'] ?? '',
                         'updated_at' => $now
                     ];
-                    $compressed_video_url = compressVideo($segmentUpdateData['video_url']);
-                    if ($compressed_video_url) $segmentUpdateData['preview_video_url'] = $compressed_video_url;
+                    $compressed_video_url = compressVideo($statusInfo['result_url']);
+                    $segmentUpdateData['video_url'] = $compressed_video_url ?: $statusInfo['result_url'];
                     
                     // 只有当video_duration存在且大于0时才更新
                     if (isset($statusInfo['video_duration']) && $statusInfo['video_duration'] > 0) {
@@ -594,14 +594,14 @@ class AIVideoGenerationService
                     
                     // 构建更新数据
                     $segmentUpdateData = [
-                        'video_url' => $statusInfo['result_url'],
+                        'origin_video_url' => $statusInfo['result_url'],
                         'video_task_status' => '已完成',
                         'current_type' => 2,
                         'last_frame_url' => $statusInfo['last_frame_url'] ?? '',
                         'updated_at' => $now
                     ];
-                    $compressed_video_url = compressVideo($segmentUpdateData['video_url']);
-                    if ($compressed_video_url) $segmentUpdateData['preview_video_url'] = $compressed_video_url;
+                    $compressed_video_url = compressVideo($statusInfo['result_url']);
+                    $segmentUpdateData['video_url'] = $compressed_video_url ?: $statusInfo['result_url'];
                     
                     // 只有当video_duration存在且大于0时才更新
                     if (isset($statusInfo['video_duration']) && $statusInfo['video_duration'] > 0) {
@@ -744,6 +744,10 @@ class AIVideoGenerationService
                     $video_name = $video_name . $video_ext;
                     $url = uploadStreamByTos('video', file_get_contents($video_url), $video_name);
                     $updateData['result_url'] = $url;
+                    
+                    // 压缩视频
+                    $compressed_video_url = compressVideo($url);
+                    $updateData['compressed_url'] = $compressed_video_url ?: $url;
                 }
                 
                 // 计算视频时长
@@ -888,8 +892,8 @@ class AIVideoGenerationService
                         $video_name = $video_name . $video_ext;
                         $url = uploadStreamByTos('video', file_get_contents($video_url), $video_name);
                         $updateData['result_url'] = $url;
-                        $compressed_video_url = compressVideo($updateData['result_url']);
-                        if ($compressed_video_url) $updateData['preview_video_url'] = $compressed_video_url;
+                        $compressed_video_url = compressVideo($url);
+                        $updateData['compressed_url'] = $compressed_video_url ?: $url;
                         
                         dLog('generate')->info('Seedance 视频保存成功: ' . $url);
                     } catch (\Exception $e) {
@@ -990,10 +994,13 @@ class AIVideoGenerationService
             if ($taskStatus === MpGenerateVideoTask::STATUS_SUCCESS) {
                 $segmentUpdateData['video_task_status'] = '已完成';
                 if (isset($updateData['result_url'])) {
-                    $segmentUpdateData['video_url'] = $updateData['result_url'];
-                }
-                if (isset($updateData['preview_video_url'])) {
-                    $segmentUpdateData['preview_video_url'] = $updateData['preview_video_url'];
+                    $segmentUpdateData['origin_video_url'] = $updateData['result_url'];
+                    // 如果有压缩视频URL,使用压缩后的
+                    if (isset($updateData['compressed_url'])) {
+                        $segmentUpdateData['video_url'] = $updateData['compressed_url'];
+                    } else {
+                        $segmentUpdateData['video_url'] = $updateData['result_url'];
+                    }
                 }
             } elseif ($taskStatus === MpGenerateVideoTask::STATUS_FAILED) {
                 $segmentUpdateData['video_task_status'] = '失败';
@@ -1379,14 +1386,14 @@ class AIVideoGenerationService
                     
                     // 构建更新数据
                     $segmentUpdateData = [
-                        'video_url' => $statusInfo['result_url'],
+                        'origin_video_url' => $statusInfo['result_url'],
                         'video_task_status' => '已完成',
                         'current_type' => 2,
                         'last_frame_url' => $statusInfo['last_frame_url'] ?? '',
                         'updated_at' => $now
                     ];
-                    $compressed_video_url = compressVideo($segmentUpdateData['video_url']);
-                    if ($compressed_video_url) $segmentUpdateData['preview_video_url'] = $compressed_video_url;
+                    $compressed_video_url = compressVideo($statusInfo['result_url']);
+                    $segmentUpdateData['video_url'] = $compressed_video_url ?: $statusInfo['result_url'];
                     
                     // 只有当video_duration存在且大于0时才更新
                     if (isset($statusInfo['video_duration']) && $statusInfo['video_duration'] > 0) {

+ 7 - 12
app/Services/Anime/AnimeService.php

@@ -103,7 +103,6 @@ class AnimeService
                 'video_duration' => getProp($segment, 'video_duration', 0),
                 'video_time_point_start' => getProp($segment, 'video_time_point_start', 0),
                 'video_time_point_end' => getProp($segment, 'video_time_point_end', getProp($segment, 'video_duration', 0)),
-                'preview_video_url' => getProp($segment, 'preview_video_url'),
                 'last_frame_url' => getProp($segment, 'last_frame_url'),
                 'current_type' => getProp($segment, 'current_type'),
             ];
@@ -841,15 +840,11 @@ class AnimeService
 
         if (!$segment_id) Utils::throwError('20003:请选择分镜!');
 
-        // 获取当前预览视频
-        $preview_video_url = DB::table('mp_episode_segments')->where('segment_id', $segment_id)->value('preview_video_url');
-        if (!$preview_video_url) $preview_video_url = '';
         $query = DB::table('mp_anime_records')->where('segment_id', $segment_id)->select('role', 'content', 'segment_id', 'image_url', 'video_url', 'created_at');
         
-        $chat = $query->orderBy('id')->get()->map(function ($value) use ($preview_video_url) {
+        $chat = $query->orderBy('id')->get()->map(function ($value) {
             $value = (array)$value;
             $value['created_at'] = transDate($value['created_at']);
-            $value['preview_video_url'] = $preview_video_url;
             return $value;
         })->toArray();
 
@@ -868,7 +863,7 @@ class AnimeService
         // 获取历史视频
         $video_history = DB::table('mp_generate_video_tasks')->where('alias_segment_id', $segment_id)->where('status', 'success')->orderBy('created_at', 'desc')->get();
         foreach($video_history as $task) {
-            $result_url = getProp($task, 'result_url');
+            $result_url = getProp($task, 'compressed_url');
             if (is_json($result_url)) {
                 $url = array_merge($url, json_decode($result_url, true));
             }else {
@@ -1072,16 +1067,16 @@ class AnimeService
             }
 
             if ($video_url) {
-                $update_data['video_url'] = $video_url;
+                $update_data['origin_video_url'] = $video_url;
                 $compressed_video_url = compressVideo($video_url);
                 $update_data['current_type'] = 2;
-                if ($compressed_video_url) $update_data['preview_video_url'] = $compressed_video_url;
+                $update_data['video_url'] = $compressed_video_url ?: $video_url;
 
                 // 同时写入一个简单的视频生成任务
                 $video_task = [
                     'alias_segment_id'  => $segment_id,
                     'status' => 'success',
-                    'result_url' => $video_url,
+                    'result_url' => $update_data['video_url'],
                     'created_at' => date('Y-m-d H:i:s'),
                     'updated_at' => date('Y-m-d H:i:s'),
                 ];
@@ -1705,10 +1700,10 @@ class AnimeService
 
         if ($img_url) $insert_data['img_url'] = $img_url;
         if ($video_url) {
-            $insert_data['video_url'] = $video_url;
+            $insert_data['origin_video_url'] = $video_url;
             $insert_data['current_type'] = 2;
             $compressed_video_url = compressVideo($video_url);
-            if ($compressed_video_url) $insert_data['preview_video_url'] = $compressed_video_url;
+            $insert_data['video_url'] = $compressed_video_url ?: $video_url;
         }
 
         try {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
resources/views/index.blade.php