lh 4 months ago
parent
commit
59b16f2a1a

+ 63 - 35
app/Http/Controllers/AIGeneration/VideoGenerationController.php

@@ -259,14 +259,14 @@ class VideoGenerationController extends BaseController
         
         // 验证基本参数
         $baseRules = [
-            // 'model' => 'required|string|in:doubao-seedance-1-5-pro-251215,doubao-seedance-1-0-pro-250528',
+            'model' => 'required|string|in:doubao-seedance-1-5-pro-251215,doubao-seedance-1-0-pro-250528,doubao-seedance-1-0-pro-fast-251015,doubao-seedance-1-0-lite-t2v-250428,doubao-seedance-1-0-lite-i2v-250428',
             'prompt' => 'required|max:1000',
             // 'content' => 'required|array|min:1',
         ];
         
         $baseMessages = [
-            // 'model.required' => '模型参数不能为空',
-            // 'model.in' => '模型只支持 doubao-seedance-1-5-pro-251215、doubao-seedance-1-0-pro-250528',
+            'model.required' => '模型参数不能为空',
+            'model.in' => '模型只支持 doubao-seedance-1-5-pro-251215、doubao-seedance-1-0-pro-250528、doubao-seedance-1-0-pro-fast-251015、doubao-seedance-1-0-lite-t2v-250428、doubao-seedance-1-0-lite-i2v-250428',
             'prompt.required' => '提示词不能为空',
             'prompt.max' => '提示词不能超过1000个字符',
             // 'content.required' => '内容参数不能为空',
@@ -282,9 +282,9 @@ class VideoGenerationController extends BaseController
             'execution_expires_after' => 'nullable|integer|min:3600|max:259200',
             'generate_audio' => 'nullable|boolean',
             'draft' => 'nullable|boolean',
-            'video_resolution' => 'nullable|in:480P,720P,1080P',
+            'video_resolution' => 'required|in:480P,720P,1080P',
             'ratio' => 'nullable|in:16:9,4:3,1:1,3:4,9:16,21:9,adaptive',
-            'video_duration' => 'nullable|integer|min:2|max:12',
+            'video_duration' => 'required|integer|min:2|max:12',
             'frames' => 'nullable|integer|min:29|max:289',
             'seed' => 'nullable|integer|min:-1|max:4294967295',
             'camera_fixed' => 'nullable|boolean',
@@ -297,8 +297,10 @@ class VideoGenerationController extends BaseController
             'execution_expires_after.integer' => '任务超时时间必须是整数',
             'execution_expires_after.min' => '任务超时时间不能少于3600秒',
             'execution_expires_after.max' => '任务超时时间不能超过259200秒',
+            'video_resolution.required' => '请选择视频分辨率',
             'video_resolution.in' => '分辨率只能是 480P、720P 或 1080P',
             'ratio.in' => '宽高比参数不正确',
+            'video_duration.required' => '请填写视频时长',
             'video_duration.integer' => '视频时长必须是整数',
             'video_duration.min' => '视频时长不能少于2秒',
             'video_duration.max' => '视频时长不能超过12秒',
@@ -369,18 +371,23 @@ class VideoGenerationController extends BaseController
         $firstFrame = null;
         $tailFrame = null;
 
+        // 以下首尾帧做模型兼容:
+        // doubao-seedance-1-0-lite-t2v-250428只支持文生视频
+        // doubao-seedance-1-0-pro-fast-251015只支持文生视频、图生视频-首帧
         // 处理首帧图片(文件上传方式)
         if ($request->hasFile('first_frame_file')) {
             $firstFrameFile = $request->file('first_frame_file');
             $firstFrame = $this->processFrameFile($firstFrameFile, 'first');
-            $data['first_frame_url'] = $firstFrame['url'];
-            $data['content'][] = [
-                'type' => 'image_url',
-                'image_url' => [
-                    'url' => $data['first_frame_url'],
-                ],
-                'role' => 'first_frame',
-            ];
+            if (!in_array($data['model'], ['doubao-seedance-1-0-lite-t2v-250428'])) {
+                $data['first_frame_url'] = $firstFrame['url'];
+                $data['content'][] = [
+                    'type' => 'image_url',
+                    'image_url' => [
+                        'url' => $data['first_frame_url'],
+                    ],
+                    'role' => 'first_frame',
+                ];
+            }
         }
         // 处理首帧图片(URL方式)
         elseif (isset($data['first_frame_url']) && !empty($data['first_frame_url'])) {
@@ -388,27 +395,33 @@ class VideoGenerationController extends BaseController
             if (!$firstFrame) {
                 Utils::throwError('1003:首帧图片获取失败');
             }
-            $data['content'][] = [
-                'type' => 'image_url',
-                'image_url' => [
-                    'url' => $data['first_frame_url'],
-                ],
-                'role' => 'first_frame',
-            ];
+            if (!in_array($data['model'], ['doubao-seedance-1-0-lite-t2v-250428'])) {
+                $data['content'][] = [
+                    'type' => 'image_url',
+                    'image_url' => [
+                        'url' => $data['first_frame_url'],
+                    ],
+                    'role' => 'first_frame',
+                ];
+            }else {
+                $data['first_frame_url'] = '';
+            }
         }
 
         // 处理尾帧图片(文件上传方式)
         if ($request->hasFile('tail_frame_file')) {
             $tailFrameFile = $request->file('tail_frame_file');
             $tailFrame = $this->processFrameFile($tailFrameFile, 'tail');
-            $data['tail_frame_url'] = $tailFrame['url'];
-            $data['content'][] = [
-                'type' => 'image_url',
-                'image_url' => [
-                    'url' => $data['tail_frame_url'],
-                ],
-                'role' => 'last_frame',
-            ];
+            if (!in_array($data['model'], ['doubao-seedance-1-0-lite-t2v-250428', 'doubao-seedance-1-0-pro-fast-251015'])) {
+                $data['tail_frame_url'] = $tailFrame['url'];
+                $data['content'][] = [
+                    'type' => 'image_url',
+                    'image_url' => [
+                        'url' => $data['tail_frame_url'],
+                    ],
+                    'role' => 'last_frame',
+                ];
+            }
         }
         // 处理尾帧图片(URL方式)
         elseif (isset($data['tail_frame_url']) && !empty($data['tail_frame_url'])) {
@@ -416,15 +429,30 @@ class VideoGenerationController extends BaseController
             if (!$tailFrame) {
                 Utils::throwError('1003:尾帧图片获取失败');
             }
-            $data['content'][] = [
-                'type' => 'image_url',
-                'image_url' => [
-                    'url' => $data['tail_frame_url'],
-                ],
-                'role' => 'last_frame',
-            ];
+            
+            if (!in_array($data['model'], ['doubao-seedance-1-0-lite-t2v-250428', 'doubao-seedance-1-0-pro-fast-251015'])) {
+                $data['content'][] = [
+                    'type' => 'image_url',
+                    'image_url' => [
+                        'url' => $data['tail_frame_url'],
+                    ],
+                    'role' => 'last_frame',
+                ];
+            }else {
+                $data['tail_frame_url'] = '';
+            }
         }
         
+        // 验证模型参数
+        if (!in_array($data['model'], ['doubao-seedance-1-5-pro-251215'])) {
+            $data['generate_audio'] = false;
+            $data['draft'] = false;
+        }
+        if (in_array($data['model'], ['doubao-seedance-1-5-pro-251215'])) {
+            if ($data['video_duration'] < 4) $data['video_duration'] = 4;
+            if (!isset($data['ratio'])) $data['ratio'] = 'adaptive';
+        }
+
         // 验证 content 数组内容
         $this->validateSeedanceContent($data['content']);
     

+ 9 - 9
app/Services/AIGeneration/AIVideoGenerationService.php

@@ -342,7 +342,7 @@ class AIVideoGenerationService
                 'execution_expires_after' => $params['execution_expires_after'] ?? 172800,
                 'generate_audio' => $params['generate_audio'] ?? true,
                 'draft' => $params['draft'] ?? false,
-                'ratio' => $params['ratio'] ?? 'adaptive',
+                'ratio' => $params['ratio'] ?? '16:9',
                 'duration' => $params['video_duration'] ?? 5,
                 'camera_fixed' => $params['camera_fixed'] ?? false,
                 'watermark' => $params['watermark'] ?? false,
@@ -364,7 +364,7 @@ class AIVideoGenerationService
     private function submitSeedanceTaskToApi(MpGenerateVideoTask $task): void
     {
         $client = new Client(['verify'=>false,'timeout'=>120]);
-        try {
+        // try {
             // 验证环境变量配置
             $apiKey = env('VOLC_AI_API_KEY');
                 
@@ -458,13 +458,13 @@ class AIVideoGenerationService
                     'extra_params' => array_merge($task->extra_params, ['api_response' => $responseData])
                 ]);
             }
-        } catch (\Exception $e) {
-            // 记录错误
-            $task->updateStatus(MpGenerateVideoTask::STATUS_FAILED, [
-                'error_message' => 'API请求失败: ' . $e->getMessage()
-            ]);
-            Utils::throwError('1001:'.$e->getMessage());
-        }
+        // } catch (\Exception $e) {
+        //     // 记录错误
+        //     $task->updateStatus(MpGenerateVideoTask::STATUS_FAILED, [
+        //         'error_message' => 'API请求失败: ' . $e->getMessage()
+        //     ]);
+        //     Utils::throwError('1001:'.$e->getMessage());
+        // }
     }
 
     // 更新即梦AI视频任务状态