Просмотр исходного кода

1.创建视频生成任务兼容多模型参数2.视频时长根据音频时长调整3.特殊模型支持带音频创建视频生成任务

lh 3 месяцев назад
Родитель
Сommit
4ddb1bb942

+ 66 - 90
app/Http/Controllers/Anime/AnimeController.php

@@ -347,7 +347,14 @@ class AnimeController extends BaseController
                     
                     // 如果任务还在处理中,查询最新状态
                     if ($task->status === 'processing') {
-                        $statusResult = $this->AIVideoGenerationService->querySeedanceTaskStatus($task);
+                        // 根据任务类型查询不同的状态
+                        if ($task->task_type === 'jimeng') {
+                            $statusResult = $this->AIVideoGenerationService->queryJimengTaskStatus($task);
+                        } elseif ($task->task_type === 'keling') {
+                            $statusResult = $this->AIVideoGenerationService->queryKelingOmniTaskStatus($task);
+                        } else {
+                            $statusResult = $this->AIVideoGenerationService->querySeedanceTaskStatus($task);
+                        }
                         if (isset($statusResult['status'])) {
                             // 更新任务状态
                             $task->update([
@@ -361,7 +368,7 @@ class AnimeController extends BaseController
                                 ]) ? now() : null
                             ]);
                             
-                            // 如果任务成功,使用事务更新分镜表并创建配音任务
+                            // 如果任务成功,更新分镜表
                             if ($statusResult['status'] === 'success' && isset($statusResult['result_url'])) {
                                 try {
                                     DB::beginTransaction();
@@ -393,45 +400,6 @@ class AnimeController extends BaseController
                                         Utils::throwError('20003:更新分镜表失败');
                                     }
                                     
-                                    // 获取分镜信息用于创建配音任务
-                                    $segmentInfo = DB::table('mp_episode_segments')
-                                        ->where('segment_id', $segmentId)
-                                        ->select('voice_actor', 'dialogue', 'voice_type', 'voice_name', 'emotion', 'emotion_type', 'gender', 'speed_ratio', 'loudness_ratio', 'emotion_scale', 'pitch')
-                                        ->first();
-                                    
-                                    // 如果分镜有对话内容,创建视频配音合成任务
-                                    $dubTaskId = null;
-                                    if ($segmentInfo && !empty($segmentInfo->dialogue)) {
-                                        $generate_json = [
-                                            'text' => $segmentInfo->dialogue,
-                                            'role' => $segmentInfo->voice_actor,
-                                            'voice_type' => $segmentInfo->voice_type,
-                                            'voice_name' => $segmentInfo->voice_name,
-                                            'emotion' => $segmentInfo->emotion,
-                                            'emotion_type' => $segmentInfo->emotion_type,
-                                            'gender' => $segmentInfo->gender,
-                                            'speed_ratio' => $segmentInfo->speed_ratio ?? 0,
-                                            'loudness_ratio' => $segmentInfo->loudness_ratio ?? 0,
-                                            'emotion_scale' => $segmentInfo->emotion_scale ?? 0,
-                                            'pitch' => $segmentInfo->pitch ?? 0,
-                                        ];
-                                        
-                                        // 插入视频配音合成任务
-                                        $dubTaskId = DB::table('mp_dub_video_tasks')->insertGetId([
-                                            'alias_segment_id' => $segmentId,
-                                            'video_url' => $statusResult['result_url'],
-                                            'generate_status' => '执行中',
-                                            'dub_video_url' => '',
-                                            'generate_json' => json_encode($generate_json, 256),
-                                            'created_at' => $now,
-                                            'updated_at' => $now,
-                                        ]);
-                                        
-                                        if (!$dubTaskId) {
-                                            Utils::throwError('20003:创建配音任务失败');
-                                        }
-                                    }
-                                    
                                     DB::commit();
                                     
                                 } catch (\Exception $e) {
@@ -587,9 +555,12 @@ class AnimeController extends BaseController
                 // $videoDuration = $this->AnimeService->calculateOptimalVideoDuration($segmentContent, $tailFrame);
                 $videoDuration = -1;
                 
+                // 默认模型
+                $model = getProp($data, 'model', 'doubao-seedance-1-0-pro-250528');
+                
                 // 构建视频生成参数
                 $videoParams = [
-                    'model' => 'doubao-seedance-1-0-pro-250528',
+                    'model' => $model,
                     'alias_segment_id' => $segment->segment_id,
                     'prompt' => $fullPrompt,
                     'video_duration' => $videoDuration,
@@ -627,8 +598,48 @@ class AnimeController extends BaseController
                     ];
                 }
                 
-                // 创建视频任务
-                $task = $this->AIVideoGenerationService->createSeedanceTask($videoParams);
+                // 获取配音音频URL和时长
+                $audioUrl = $segment->audio_url ?? '';
+                $audioDuration = $segment->audio_duration ?? 0;
+                
+                // 根据模型选择不同的视频生成方法
+                if (strpos($model, 'jimeng') !== false) {
+                    // 即梦模型参数调整
+                    $videoParams['video_duration'] = $audioDuration > 5 ? 10 : 5; // 即梦只支持5s或10s
+                    $videoParams['aspect_ratio'] = $videoParams['ratio']; // 即梦使用aspect_ratio
+                    unset($videoParams['ratio']);
+                    unset($videoParams['content']); // 即梦不使用content格式
+                    $task = $this->AIVideoGenerationService->createJimengTask($videoParams);
+                } elseif (strpos($model, 'kling') !== false) {
+                    // Keling模型参数调整
+                    $videoParams['video_duration'] = max(3, min(15, ceil($audioDuration))); // Keling支持3-15秒
+                    $videoParams['aspect_ratio'] = $videoParams['ratio']; // Keling使用aspect_ratio
+                    unset($videoParams['ratio']);
+                    unset($videoParams['content']); // Keling不使用content格式
+                    $task = $this->AIVideoGenerationService->createKelingOmniTask($videoParams);
+                } else {
+                    // 检查是否为 Seedance 2.0 模型,如果是则需要处理配音音频
+                    if (in_array($model, ['doubao-seedance-2-0-260128', 'doubao-seedance-2-0-fast-260128'])) {
+                        // 添加配音音频到content中
+                        $videoParams['content'][] = [
+                            'type' => 'audio_url',
+                            'audio_url' => [
+                                'url' => $audioUrl,
+                            ],
+                            'role' => 'reference_audio',
+                        ];
+                        
+                        // 优化提示词,增加音频相关描述
+                        $audioPrompt = "全程使用音频1作为视频配音。" . $fullPrompt;
+                        $videoParams['prompt'] = $audioPrompt;
+                        $videoParams['content'][0]['text'] = $audioPrompt;
+                    }else if ($audioDuration) {
+                        // 有音频时长则需将视频时长设置为比音频时长更长的整数
+                        $videoParams['video_duration'] = max(2, min(12, ceil($audioDuration)));   // seedance支持2-12s
+                    }
+                    // Seedance模型(默认)
+                    $task = $this->AIVideoGenerationService->createSeedanceTask($videoParams);
+                }
                 $taskIds[] = $task->id;
                 
                 // 更新分镜表的视频任务信息
@@ -711,7 +722,14 @@ class AnimeController extends BaseController
                         
                         // 如果任务还在处理中,查询最新状态
                         if ($task->status === 'processing') {
-                            $statusResult = $this->AIVideoGenerationService->querySeedanceTaskStatus($task);
+                            // 根据任务类型查询不同的状态
+                            if ($task->task_type === 'jimeng') {
+                                $statusResult = $this->AIVideoGenerationService->queryJimengTaskStatus($task);
+                            } elseif ($task->task_type === 'keling') {
+                                $statusResult = $this->AIVideoGenerationService->queryKelingOmniTaskStatus($task);
+                            } else {
+                                $statusResult = $this->AIVideoGenerationService->querySeedanceTaskStatus($task);
+                            }
                             if (isset($statusResult['status'])) {
                                 // 更新任务状态
                                 $task->update([
@@ -726,7 +744,7 @@ class AnimeController extends BaseController
                                     ]) ? now() : null
                                 ]);
                                 
-                                // 如果任务成功,使用事务更新分镜表并创建配音任务
+                                // 如果任务成功,更新分镜表
                                 if ($statusResult['status'] === 'success' && isset($statusResult['result_url'])) {
                                     try {
                                         DB::beginTransaction();
@@ -743,48 +761,7 @@ class AnimeController extends BaseController
                                             ]);
                                         
                                         if (!$updateResult) {
-                                            if (!$dubTaskId) {
-                                                Utils::throwError('20003:更新分镜表失败');
-                                            }
-                                        }
-                                        
-                                        // 获取分镜信息用于创建配音任务
-                                        $segment = DB::table('mp_episode_segments')
-                                            ->where('segment_id', $segmentId)
-                                            ->select('voice_actor', 'dialogue', 'voice_type', 'voice_name', 'emotion', 'emotion_type', 'gender', 'speed_ratio', 'loudness_ratio', 'emotion_scale', 'pitch')
-                                            ->first();
-                                        
-                                        // 如果分镜有对话内容,创建视频配音合成任务
-                                        $dubTaskId = null;
-                                        if ($segment && !empty($segment->dialogue)) {
-                                            $generate_json = [
-                                                'text' => $segment->dialogue,
-                                                'role' => $segment->voice_actor,
-                                                'voice_type' => $segment->voice_type,
-                                                'voice_name' => $segment->voice_name,
-                                                'emotion' => $segment->emotion,
-                                                'emotion_type' => $segment->emotion_type,
-                                                'gender' => $segment->gender,
-                                                'speed_ratio' => $segment->speed_ratio ?? 0,
-                                                'loudness_ratio' => $segment->loudness_ratio ?? 0,
-                                                'emotion_scale' => $segment->emotion_scale ?? 0,
-                                                'pitch' => $segment->pitch ?? 0,
-                                            ];
-                                            
-                                            // 插入视频配音合成任务
-                                            $dubTaskId = DB::table('mp_dub_video_tasks')->insertGetId([
-                                                'alias_segment_id' => $segmentId,
-                                                'video_url' => $statusResult['result_url'],
-                                                'generate_status' => '执行中',
-                                                'dub_video_url' => '',
-                                                'generate_json' => json_encode($generate_json, 256),
-                                                'created_at' => $now,
-                                                'updated_at' => $now,
-                                            ]);
-                                            
-                                            if (!$dubTaskId) {
-                                                Utils::throwError('20003:创建配音任务失败');
-                                            }
+                                            Utils::throwError('20003:更新分镜表失败');
                                         }
                                         
                                         DB::commit();
@@ -802,8 +779,7 @@ class AnimeController extends BaseController
                                                 'video_url' => $statusResult['result_url'],
                                                 'last_frame_url' => $statusResult['last_frame_url'] ?? '',
                                                 'completed_count' => count($completedTasks),
-                                                'total_count' => count($segmentTasks),
-                                                'has_dub_task' => $dubTaskId > 0
+                                                'total_count' => count($segmentTasks)
                                             ]
                                         ]) . "\n\n";
                                         ob_flush();

+ 0 - 102
app/Services/AIGeneration/AIVideoGenerationService.php

@@ -303,40 +303,6 @@ class AIVideoGenerationService
                         'updated_at' => $now
                     ]);
                     
-                    // 获取分镜信息用于创建配音任务
-                    $segment = DB::table('mp_episode_segments')
-                        ->where('segment_id', $segment_id)
-                        ->select('voice_actor', 'dialogue', 'voice_type', 'voice_name', 'emotion', 'emotion_type', 'gender', 'speed_ratio', 'loudness_ratio', 'emotion_scale', 'pitch')
-                        ->first();
-                    
-                    // 如果分镜有对话内容,创建视频配音合成任务
-                    if ($segment && !empty($segment->dialogue)) {
-                        $generate_json = [
-                            'text' => $segment->dialogue,
-                            'role' => $segment->voice_actor,
-                            'voice_type' => $segment->voice_type,
-                            'voice_name' => $segment->voice_name,
-                            'emotion' => $segment->emotion,
-                            'emotion_type' => $segment->emotion_type,
-                            'gender' => $segment->gender,
-                            'speed_ratio' => $segment->speed_ratio ?? 0,
-                            'loudness_ratio' => $segment->loudness_ratio ?? 0,
-                            'emotion_scale' => $segment->emotion_scale ?? 0,
-                            'pitch' => $segment->pitch ?? 0,
-                        ];
-                        
-                        // 插入视频配音合成任务
-                        DB::table('mp_dub_video_tasks')->insert([
-                            'alias_segment_id' => $segment_id,
-                            'video_url' => $statusInfo['result_url'],
-                            'generate_status' => '执行中',
-                            'dub_video_url' => '',
-                            'generate_json' => json_encode($generate_json, 256),
-                            'created_at' => $now,
-                            'updated_at' => $now,
-                        ]);
-                    }
-                    
                     DB::commit();
                     
                 } catch (\Exception $e) {
@@ -577,40 +543,6 @@ class AIVideoGenerationService
                         'updated_at' => $now
                     ]);
                     
-                    // 获取分镜信息用于创建配音任务
-                    $segment = DB::table('mp_episode_segments')
-                        ->where('segment_id', $segment_id)
-                        ->select('voice_actor', 'dialogue', 'voice_type', 'voice_name', 'emotion', 'emotion_type', 'gender', 'speed_ratio', 'loudness_ratio', 'emotion_scale', 'pitch')
-                        ->first();
-                    
-                    // 如果分镜有对话内容,创建视频配音合成任务
-                    if ($segment && !empty($segment->dialogue)) {
-                        $generate_json = [
-                            'text' => $segment->dialogue,
-                            'role' => $segment->voice_actor,
-                            'voice_type' => $segment->voice_type,
-                            'voice_name' => $segment->voice_name,
-                            'emotion' => $segment->emotion,
-                            'emotion_type' => $segment->emotion_type,
-                            'gender' => $segment->gender,
-                            'speed_ratio' => $segment->speed_ratio ?? 0,
-                            'loudness_ratio' => $segment->loudness_ratio ?? 0,
-                            'emotion_scale' => $segment->emotion_scale ?? 0,
-                            'pitch' => $segment->pitch ?? 0,
-                        ];
-                        
-                        // 插入视频配音合成任务
-                        DB::table('mp_dub_video_tasks')->insert([
-                            'alias_segment_id' => $segment_id,
-                            'video_url' => $statusInfo['result_url'],
-                            'generate_status' => '执行中',
-                            'dub_video_url' => '',
-                            'generate_json' => json_encode($generate_json, 256),
-                            'created_at' => $now,
-                            'updated_at' => $now,
-                        ]);
-                    }
-                    
                     DB::commit();
                     
                 } catch (\Exception $e) {
@@ -1299,40 +1231,6 @@ class AIVideoGenerationService
                         'updated_at' => $now
                     ]);
                     
-                    // 获取分镜信息用于创建配音任务
-                    $segment = DB::table('mp_episode_segments')
-                        ->where('segment_id', $segment_id)
-                        ->select('voice_actor', 'dialogue', 'voice_type', 'voice_name', 'emotion', 'emotion_type', 'gender', 'speed_ratio', 'loudness_ratio', 'emotion_scale', 'pitch')
-                        ->first();
-                    
-                    // 如果分镜有对话内容,创建视频配音合成任务
-                    if ($segment && !empty($segment->dialogue)) {
-                        $generate_json = [
-                            'text' => $segment->dialogue,
-                            'role' => $segment->voice_actor,
-                            'voice_type' => $segment->voice_type,
-                            'voice_name' => $segment->voice_name,
-                            'emotion' => $segment->emotion,
-                            'emotion_type' => $segment->emotion_type,
-                            'gender' => $segment->gender,
-                            'speed_ratio' => $segment->speed_ratio ?? 0,
-                            'loudness_ratio' => $segment->loudness_ratio ?? 0,
-                            'emotion_scale' => $segment->emotion_scale ?? 0,
-                            'pitch' => $segment->pitch ?? 0,
-                        ];
-                        
-                        // 插入视频配音合成任务
-                        DB::table('mp_dub_video_tasks')->insert([
-                            'alias_segment_id' => $segment_id,
-                            'video_url' => $statusInfo['result_url'],
-                            'generate_status' => '执行中',
-                            'dub_video_url' => '',
-                            'generate_json' => json_encode($generate_json, 256),
-                            'created_at' => $now,
-                            'updated_at' => $now,
-                        ]);
-                    }
-                    
                     DB::commit();
                     
                 } catch (\Exception $e) {

+ 45 - 78
app/Services/Anime/AnimeService.php

@@ -1423,39 +1423,6 @@ class AnimeService
                 Utils::throwError('20003:新增分镜失败!');
             }
 
-            // 如果有视频URL且有对话内容,创建视频配音合成任务
-            if ($video_url && !empty($insert_data['dialogue'])) {
-                $now = date('Y-m-d H:i:s');
-                $generate_json = [
-                    'text' => $insert_data['dialogue'],
-                    'role' => getProp($insert_data, 'voice_actor'),
-                    'voice_type' => getProp($insert_data, 'voice_type'),
-                    'voice_name' => getProp($insert_data, 'voice_name'),
-                    'emotion' => getProp($insert_data, 'emotion'),
-                    'emotion_type' => getProp($insert_data, 'emotion_type'),
-                    'gender' => getProp($insert_data, 'gender'),
-                    'speed_ratio' => getProp($insert_data, 'speed_ratio', 0),
-                    'loudness_ratio' => getProp($insert_data, 'loudness_ratio', 0),
-                    'emotion_scale' => getProp($insert_data, 'emotion_scale', 0),
-                    'pitch' => getProp($insert_data, 'pitch', 0),
-                ];
-                
-                // 插入视频配音合成任务
-                $dubTaskId = DB::table('mp_dub_video_tasks')->insertGetId([
-                    'alias_segment_id' => $segment_id,
-                    'video_url' => $video_url,
-                    'generate_status' => '执行中',
-                    'dub_video_url' => '',
-                    'generate_json' => json_encode($generate_json, 256),
-                    'created_at' => $now,
-                    'updated_at' => $now,
-                ]);
-                
-                if (!$dubTaskId) {
-                    Utils::throwError('20003:创建配音任务失败!');
-                }
-            }
-
             // 如果是第一集的首帧图片,则存入待更新数组
             if ($boolen && (int)$episode_number === 1 && (int)$new_segment_number === 1) {
                 Redis::sadd('anime_first_frame_urls', $segment_id);
@@ -1810,48 +1777,6 @@ class AnimeService
             // 去重
             $segment_ids_to_create_task = array_unique($segment_ids_to_create_task);
 
-            // 为所有需要更新的分镜创建音频合成任务
-            if (!empty($segment_ids_to_create_task)) {
-                foreach ($segment_ids_to_create_task as $sid) {
-                    // 从已获取的数据中取出分镜信息
-                    if (!isset($segments_data[$sid])) continue;
-                    
-                    $segment = $segments_data[$sid];
-                    $video_url = getProp($segment, 'video_url');
-                    if (!$video_url) continue;
-
-                    // 构建音频生成参数
-                    $generate_json = [
-                        'text' => getProp($segment, 'dialogue'),
-                        'role' => getProp($segment, 'voice_actor'),
-                        'voice_type' => getProp($segment, 'voice_type'),
-                        'voice_name' => getProp($segment, 'voice_name'),
-                        'emotion' => getProp($segment, 'emotion'),
-                        'emotion_type' => getProp($segment, 'emotion_type'),
-                        'gender' => getProp($segment, 'gender'),
-                        'speed_ratio' => getProp($segment, 'speed_ratio', 0),
-                        'loudness_ratio' => getProp($segment, 'loudness_ratio', 0),
-                        'emotion_scale' => getProp($segment, 'emotion_scale', 0),
-                        'pitch' => getProp($segment, 'pitch', 0),
-                    ];
-
-                    // 插入视频配音合成任务
-                    $task_id = DB::table('mp_dub_video_tasks')->insertGetId([
-                        'alias_segment_id' => $sid,
-                        'video_url' => $video_url,
-                        'generate_status' => '执行中',
-                        'dub_video_url' => '',
-                        'generate_json' => json_encode($generate_json, 256),
-                        'created_at' => $now,
-                        'updated_at' => $now,
-                    ]);
-
-                    if (!$task_id) {
-                        Utils::throwError('20003:创建音频合成任务失败');
-                    }
-                }
-            }
-
             DB::commit();
 
         } catch (\Exception $e) {
@@ -2390,9 +2315,12 @@ class AnimeService
         // $videoDuration = $this->calculateOptimalVideoDuration($segmentContent, $tail_frame);
         $videoDuration = -1;
         
+        // 默认使用 Seedance 1.0 Pro 模型
+        $model = getProp($data, 'model', 'doubao-seedance-1-0-pro-250528');
+        
         // 构建视频生成参数
         $videoParams = [
-            'model' => 'doubao-seedance-1-0-pro-250528',
+            'model' => $model,
             'alias_segment_id' => $segment_id,
             'prompt' => $fullPrompt,
             'video_duration' => $videoDuration,
@@ -2429,11 +2357,50 @@ class AnimeService
                 'role' => 'first_frame',
             ];
         }
+        
+        // 获取配音音频URL
+        $audioUrl = getProp($segment, 'audio_url');
+        $audioDuration = getProp($segment, 'audio_duration');
 
         // dd($videoParams);
         
-        // 创建视频生成任务
-        $task = $this->aiVideoGenerationService->createSeedanceTask($videoParams);
+        // 根据模型选择不同的视频生成方法
+        if (strpos($model, 'jimeng') !== false) {
+            // 即梦模型参数调整
+            $videoParams['video_duration'] = $audioDuration > 5 ? 10 : 5; // 即梦只支持5s或10s
+            unset($videoParams['content']); // 即梦不使用content格式
+            $task = $this->aiVideoGenerationService->createJimengTask($videoParams);
+        } elseif (strpos($model, 'kling') !== false) {
+            // Keling模型参数调整
+            $videoParams['video_duration'] = max(3, min(15, ceil($audioDuration))); // Keling支持3-15秒
+            $videoParams['aspect_ratio'] = $videoParams['ratio']; // Keling使用aspect_ratio
+            unset($videoParams['ratio']);
+            unset($videoParams['content']); // Keling不使用content格式
+            $task = $this->aiVideoGenerationService->createKelingOmniTask($videoParams);
+        } else {
+            // 检查是否为 Seedance 2.0 模型,如果是则需要处理配音音频
+            if ($audioUrl) {
+                if (in_array($model, ['doubao-seedance-2-0-260128', 'doubao-seedance-2-0-fast-260128'])) {
+                    // 添加配音音频到content中
+                    $videoParams['content'][] = [
+                        'type' => 'audio_url',
+                        'audio_url' => [
+                            'url' => $audioUrl,
+                        ],
+                        'role' => 'reference_audio',
+                    ];
+                    
+                    // 优化提示词,增加音频相关描述
+                    $audioPrompt = "全程使用音频1作为视频配音。" . $fullPrompt;
+                    $videoParams['prompt'] = $audioPrompt;
+                    $videoParams['content'][0]['text'] = $audioPrompt;
+                }else if ($audioDuration) {    // 有音频时长则需将视频时长设置为比音频时长更长的整数
+                    $videoParams['video_duration'] = max(2, min(12, ceil($audioDuration)));   // seedance支持2-12s
+                }
+            }
+            // Seedance模型(默认)
+            $task = $this->aiVideoGenerationService->createSeedanceTask($videoParams);
+        }
         
         // 更新分镜表的视频任务信息
         DB::table('mp_episode_segments')->where('segment_id', $segment_id)->update([