Преглед на файлове

1.视频新增480p模式2.对原来的480p模式更改为超分720p模式

lh преди 2 седмици
родител
ревизия
44d6ec0e95

+ 4 - 4
app/Http/Controllers/AIGeneration/VideoGenerationController.php

@@ -303,7 +303,7 @@ class VideoGenerationController extends BaseController
             'execution_expires_after' => 'nullable|integer|min:3600|max:259200',
             'generate_audio' => 'nullable|boolean',
             'draft' => 'nullable|boolean',
-            'video_resolution' => 'required|in:480P,720P,1080P',
+            'video_resolution' => 'required|in:480P,SR_720P,720P,1080P',
             'ratio' => 'nullable|in:16:9,4:3,1:1,3:4,9:16,21:9,adaptive',
             'video_duration' => 'required|integer|min:2|max:12',
             'frames' => 'nullable|integer|min:29|max:289',
@@ -319,7 +319,7 @@ class VideoGenerationController extends BaseController
             'execution_expires_after.min' => '任务超时时间不能少于3600秒',
             'execution_expires_after.max' => '任务超时时间不能超过259200秒',
             'video_resolution.required' => '请选择视频分辨率',
-            'video_resolution.in' => '分辨率只能是 480P、720P 或 1080P',
+            'video_resolution.in' => '分辨率只能是 480P、SR_720P、720P 或 1080P',
             'ratio.in' => '宽高比参数不正确',
             'video_duration.required' => '请填写视频时长',
             'video_duration.integer' => '视频时长必须是整数',
@@ -743,7 +743,7 @@ class VideoGenerationController extends BaseController
             'generate_audio' => 'nullable|boolean',
             'webhook_url' => 'nullable|url',
             'seed' => 'nullable|integer|min:-1|max:4294967295',
-            'video_resolution' => 'nullable|in:480P,720P,1080P',
+            'video_resolution' => 'nullable|in:720P,1080P',
         ];
         
         $optionalMessages = [
@@ -755,7 +755,7 @@ class VideoGenerationController extends BaseController
             'seed.integer' => '随机种子必须是整数',
             'seed.min' => '随机种子不能小于-1',
             'seed.max' => '随机种子不能超过4294967295',
-            'video_resolution.in' => '分辨率只能是 480P、720P 或 1080P',
+            'video_resolution.in' => '分辨率只能是 720P 或 1080P',
         ];
 
         // 检查是否有首帧URL

+ 12 - 6
app/Http/Controllers/Anime/AnimeController.php

@@ -150,10 +150,16 @@ class AnimeController extends BaseController
             ];
         };
 
-        $resolutions = function (array $values, string $default = '720p') {
+        $resolutions = function (array $values, string $default = 'sr_720p') {
             $options = [];
             foreach ($values as $value) {
-                $options[] = ['key' => $value, 'value' => $value];
+                if ($value == 'sr_720p') {
+                    $options[] = ['key' => '超分720p', 'value' => $value];
+                }else if ($value == 'sr_1080p'){
+                    $options[] = ['key' => '超分1080p', 'value' => $value];
+                }else {
+                    $options[] = ['key' => $value, 'value' => $value];
+                }
             }
             return [
                 'default' => $default,
@@ -168,28 +174,28 @@ class AnimeController extends BaseController
                 'name' => 'Seedance 2.0',
                 'duration' => $duration(4, 15),
                 'ratios' => $commonRatios,
-                'resolutions' => $resolutions(['480p', '720p', '1080p', '4k']),
+                'resolutions' => $resolutions(['480p', 'sr_720p', '720p', '1080p', '4k']),
             ],
             [
                 'model' => 'baidu-doubao-seedance-2-0-fast-260128',
                 'name' => 'Seedance 2.0 Fast',
                 'duration' => $duration(4, 15),
                 'ratios' => $commonRatios,
-                'resolutions' => $resolutions(['480p', '720p']),
+                'resolutions' => $resolutions(['480p', 'sr_720p', '720p']),
             ],
             [
                 'model' => 'baidu-doubao-seedance-2-0-mini-260615',
                 'name' => 'Seedance 2.0 Mini',
                 'duration' => $duration(4, 15),
                 'ratios' => $commonRatios,
-                'resolutions' => $resolutions(['480p', '720p']),
+                'resolutions' => $resolutions(['480p', 'sr_720p', '720p']),
             ],
             [
                 'model' => 'baidu-doubao-seedance-2-5-260628',
                 'name' => 'Seedance 2.5',
                 'duration' => $duration(4, 30, -1),
                 'ratios' => $commonRatios,
-                'resolutions' => $resolutions(['480p', '720p', '1080p']),
+                'resolutions' => $resolutions(['480p', 'sr_720p', '720p', '1080p']),
             ],
         ]);
 

+ 83 - 46
app/Services/AIGeneration/AIVideoGenerationService.php

@@ -93,6 +93,9 @@ class AIVideoGenerationService
      */
     public function createJimengTask(array $params): MpGenerateVideoTask
     {
+        // 分辨率统一规范化为小写(480p=原始档;sr_720p=480p生成+本地超分到720p)
+        $params['video_resolution'] = strtolower(trim((string)($params['video_resolution'] ?? '720p')));
+
         // 生成唯一的任务ID
         $taskId = 'vid_gen_' . time() . '_' . uniqid();
 
@@ -305,7 +308,7 @@ class AIVideoGenerationService
                     // 下载视频内容
                     $videoContent = file_get_contents($result['video_url']);
 
-                    // 从任务中获取视频分辨率,按目标档位执行本地超分(480p->720p;sr_1080p->1080p)
+                    // 从任务中获取视频分辨率,按目标档位执行本地超分(sr_720p->720p;sr_1080p->1080p)
                     if ($this->shouldUpgradeVideoResolution($task)) {
                         $upgradeTarget = $this->getVideoUpgradeTarget($task);
                         dLog('generate')->info('即梦检测到需超分视频,开始超分(' . strtolower((string)$task->video_resolution) . ' -> ' . $upgradeTarget . ')', [
@@ -324,8 +327,8 @@ class AIVideoGenerationService
                             $url = uploadStreamByTos('video', $videoContent, $video_name);
                         }
                     } else {
-                        // 非480p视频,直接保存原视频
-                        dLog('generate')->info('即梦视频非480p,直接保存', [
+                        // 非超分档视频,直接保存原视频
+                        dLog('generate')->info('即梦视频无需本地超分,直接保存', [
                             'original_url' => $result['video_url'],
                             'video_resolution' => $task->video_resolution
                         ]);
@@ -585,6 +588,9 @@ class AIVideoGenerationService
      */
     public function createSeedanceTask(array $params): MpGenerateVideoTask
     {
+        // 分辨率统一规范化为小写(480p=原始档;sr_720p=480p生成+本地超分到720p)
+        $params['video_resolution'] = strtolower(trim((string)($params['video_resolution'] ?? '720p')));
+
         // 生成唯一的任务ID
         $taskId = 'seedance_' . time() . '_' . uniqid();
 
@@ -634,6 +640,9 @@ class AIVideoGenerationService
      */
     public function createSeedance20Task(array $params): MpGenerateVideoTask
     {
+        // 分辨率统一规范化为小写(480p=原始档;sr_720p=480p生成+本地超分到720p)
+        $params['video_resolution'] = strtolower(trim((string)($params['video_resolution'] ?? '720p')));
+
         // 生成唯一的任务ID
         $taskId = 'seedance20_' . time() . '_' . uniqid();
 
@@ -908,6 +917,9 @@ class AIVideoGenerationService
      */
     public function createKuaikuaiVideoTask(array $params): MpGenerateVideoTask
     {
+        // 分辨率统一规范化为小写(480p=原始档;sr_720p=480p生成+本地超分到720p)
+        $params['video_resolution'] = strtolower(trim((string)($params['video_resolution'] ?? '720p')));
+
         // 生成唯一的任务ID
         $taskId = 'kuaikuai_' . time() . '_' . uniqid();
 
@@ -1213,6 +1225,7 @@ class AIVideoGenerationService
 
     /**
      * 请求外部API时的分辨率映射
+     * sr_720p(超分720p)模式:外部按480p生成,本地再超分到720p,因此请求分辨率统一改为480p
      * sr_1080p(超分1080p)模式:外部按720p生成,本地再超分到1080p,因此请求分辨率统一改为720p
      *
      * @param string $resolution
@@ -1221,6 +1234,9 @@ class AIVideoGenerationService
     private function apiRequestResolution(string $resolution): string
     {
         $resolution = strtolower(trim($resolution));
+        if (in_array($resolution, ['sr_720p', 'sr720p'], true)) {
+            return '480p';
+        }
         if (in_array($resolution, ['sr_1080p', 'sr1080p'], true)) {
             return '720p';
         }
@@ -1228,35 +1244,48 @@ class AIVideoGenerationService
     }
 
     /**
-     * 判断任务是否需要本地超分(480p -> 720p;sr_1080p -> 1080p)
-     * 超分统一走 upgrade480pTo720p(内部按源档位自动选择目标分辨率)
+     * 解析任务分辨率的本地超分目标档位
+     * 档位语义:
+     * - 480p:原始480p,生成480p并直接交付,不做本地超分
+     * - sr_720p:按480p生成,本地超分到720p
+     * - sr_1080p:按720p生成,本地超分到1080p
+     * - 720p / 1080p / 4k:直接按目标档位生成,不做本地超分
+     *
+     * @param string $resolution
+     * @return string '720p'|'1080p'|''(空表示无需本地超分)
+     */
+    private function resolutionUpscaleTarget(string $resolution): string
+    {
+        $resolution = strtolower(trim($resolution));
+        if (in_array($resolution, ['sr_720p', 'sr720p'], true)) {
+            return '720p';
+        }
+        if (in_array($resolution, ['sr_1080p', 'sr1080p'], true)) {
+            return '1080p';
+        }
+        return '';
+    }
+
+    /**
+     * 判断任务是否需要本地超分(仅 sr_720p / sr_1080p 档触发)
      *
      * @param object $task
      * @return bool
      */
     private function shouldUpgradeVideoResolution($task): bool
     {
-        $resolution = strtoupper((string)getProp($task, 'video_resolution', ''));
-        return strpos($resolution, '480') !== false || strpos($resolution, 'SR_1080') !== false;
+        return $this->resolutionUpscaleTarget((string)getProp($task, 'video_resolution', '')) !== '';
     }
 
     /**
      * 获取任务本地超分目标档位(显式传给 upgrade480pTo720p)
-     * 480p -> 720p;sr_1080p -> 1080p
      *
      * @param object $task
-     * @return string '720p'|'1080p'|''(空表示由超分函数自动识别)
+     * @return string '720p'|'1080p'|''(空表示无需本地超分
      */
     private function getVideoUpgradeTarget($task): string
     {
-        $resolution = strtoupper((string)getProp($task, 'video_resolution', ''));
-        if (strpos($resolution, 'SR_1080') !== false) {
-            return '1080p';
-        }
-        if (strpos($resolution, '480') !== false) {
-            return '720p';
-        }
-        return '';
+        return $this->resolutionUpscaleTarget((string)getProp($task, 'video_resolution', ''));
     }
 
     /**
@@ -2754,7 +2783,7 @@ class AIVideoGenerationService
                     // 下载视频内容
                     $videoContent = file_get_contents($video_url);
 
-                    // 从任务中获取视频分辨率,按目标档位执行本地超分(480p->720p;sr_1080p->1080p)
+                    // 从任务中获取视频分辨率,按目标档位执行本地超分(sr_720p->720p;sr_1080p->1080p)
                     if ($this->shouldUpgradeVideoResolution($task)) {
                         $upgradeTarget = $this->getVideoUpgradeTarget($task);
                         dLog('generate')->info('Seedance检测到需超分视频,开始超分(' . strtolower((string)$task->video_resolution) . ' -> ' . $upgradeTarget . ')', [
@@ -2773,8 +2802,8 @@ class AIVideoGenerationService
                             $url = uploadStreamByTos('video', $videoContent, $video_name);
                         }
                     } else {
-                        // 非480p视频,直接保存原视频
-                        dLog('generate')->info('Seedance视频非480p,直接保存', [
+                        // 非超分档视频,直接保存原视频
+                        dLog('generate')->info('Seedance视频无需本地超分,直接保存', [
                             'original_url' => $video_url,
                             'video_resolution' => $task->video_resolution
                         ]);
@@ -3024,7 +3053,7 @@ class AIVideoGenerationService
             // 下载视频内容
             $videoContent = file_get_contents($video_url);
 
-            // 从任务中获取视频分辨率,按目标档位执行本地超分(480p->720p;sr_1080p->1080p)
+            // 从任务中获取视频分辨率,按目标档位执行本地超分(sr_720p->720p;sr_1080p->1080p)
             if ($this->shouldUpgradeVideoResolution($task)) {
                 $upgradeTarget = $this->getVideoUpgradeTarget($task);
                 dLog('generate')->info('Seedance检测到需超分视频,开始超分(' . strtolower((string)$task->video_resolution) . ' -> ' . $upgradeTarget . ')', [
@@ -3043,8 +3072,8 @@ class AIVideoGenerationService
                     $url = uploadStreamByTos('video', $videoContent, $video_name);
                 }
             } else {
-                // 非480p视频,直接保存原视频
-                dLog('generate')->info('Seedance视频非480p,直接保存', [
+                // 非超分档视频,直接保存原视频
+                dLog('generate')->info('Seedance视频无需本地超分,直接保存', [
                     'original_url' => $video_url,
                     'video_resolution' => $task->video_resolution
                 ]);
@@ -3180,7 +3209,7 @@ class AIVideoGenerationService
                         // 下载视频内容
                         $videoContent = file_get_contents($video_url);
 
-                        // 从任务中获取视频分辨率,按目标档位执行本地超分(480p->720p;sr_1080p->1080p)
+                        // 从任务中获取视频分辨率,按目标档位执行本地超分(sr_720p->720p;sr_1080p->1080p)
                         if ($this->shouldUpgradeVideoResolution($task)) {
                             $upgradeTarget = $this->getVideoUpgradeTarget($task);
                             dLog('generate')->info('Seedance回调检测到需超分视频,开始超分(' . strtolower((string)$task->video_resolution) . ' -> ' . $upgradeTarget . ')', [
@@ -3199,8 +3228,8 @@ class AIVideoGenerationService
                                 $url = uploadStreamByTos('video', $videoContent, $video_name);
                             }
                         } else {
-                            // 非480p视频,直接保存原视频
-                            dLog('generate')->info('Seedance回调视频非480p,直接保存', [
+                            // 非超分档视频,直接保存原视频
+                            dLog('generate')->info('Seedance回调视频无需本地超分,直接保存', [
                                 'original_url' => $video_url,
                                 'video_resolution' => $task->video_resolution
                             ]);
@@ -3542,6 +3571,9 @@ class AIVideoGenerationService
      */
     public function createKelingOmniTask(array $params): MpGenerateVideoTask
     {
+        // 分辨率统一规范化为小写(480p=原始档;sr_720p=480p生成+本地超分到720p)
+        $params['video_resolution'] = strtolower(trim((string)($params['video_resolution'] ?? '720p')));
+
         // 生成唯一的任务ID
         $taskId = 'keling_omni_' . time() . '_' . uniqid();
 
@@ -3742,7 +3774,7 @@ class AIVideoGenerationService
                     // 下载视频内容
                     $videoContent = file_get_contents($video_url);
 
-                    // 从任务中获取视频分辨率,按目标档位执行本地超分(480p->720p;sr_1080p->1080p)
+                    // 从任务中获取视频分辨率,按目标档位执行本地超分(sr_720p->720p;sr_1080p->1080p)
                     if ($this->shouldUpgradeVideoResolution($task)) {
                         $upgradeTarget = $this->getVideoUpgradeTarget($task);
                         dLog('generate')->info('可灵检测到需超分视频,开始超分(' . strtolower((string)$task->video_resolution) . ' -> ' . $upgradeTarget . ')', [
@@ -3761,8 +3793,8 @@ class AIVideoGenerationService
                             $url = uploadStreamByTos('video', $videoContent, $video_name);
                         }
                     } else {
-                        // 非480p视频,直接保存原视频
-                        dLog('generate')->info('可灵视频非480p,直接保存', [
+                        // 非超分档视频,直接保存原视频
+                        dLog('generate')->info('可灵视频无需本地超分,直接保存', [
                             'original_url' => $video_url,
                             'video_resolution' => $task->video_resolution
                         ]);
@@ -4787,6 +4819,9 @@ class AIVideoGenerationService
      */
     public function createUnifiedApiTask(array $params): MpGenerateVideoTask
     {
+        // 分辨率统一规范化为小写(480p=原始档;sr_720p=480p生成+本地超分到720p)
+        $params['video_resolution'] = strtolower(trim((string)($params['video_resolution'] ?? '720p')));
+
         // 生成唯一的任务ID
         $taskId = 'unified_' . time() . '_' . uniqid();
 
@@ -5028,12 +5063,12 @@ class AIVideoGenerationService
                 }
                 
                 if ($videoUrl) {
-                    // 保存视频到TOS,仅480p视频超分到720p,其余分辨率直接保存
+                    // 保存视频到TOS,超分档(sr_720p/sr_1080p)本地超分后保存,其余分辨率直接保存
                     try {
                         // 下载视频内容
                         $videoContent = file_get_contents($videoUrl);
 
-                        // 从任务中获取视频分辨率,按目标档位执行本地超分(480p->720p;sr_1080p->1080p)
+                        // 从任务中获取视频分辨率,按目标档位执行本地超分(sr_720p->720p;sr_1080p->1080p)
                         if ($this->shouldUpgradeVideoResolution($task)) {
                             $upgradeTarget = $this->getVideoUpgradeTarget($task);
                             dLog('generate')->info('检测到需超分视频,开始超分(' . strtolower((string)$task->video_resolution) . ' -> ' . $upgradeTarget . ')', [
@@ -5057,8 +5092,8 @@ class AIVideoGenerationService
                                 $returnData['result_url'] = $url;
                             }
                         } else {
-                            // 非480p视频,直接保存原视频
-                            dLog('generate')->info('视频非480p,直接保存', [
+                            // 非超分档视频,直接保存原视频
+                            dLog('generate')->info('视频无需本地超分,直接保存', [
                                 'original_url' => $videoUrl,
                                 'video_resolution' => $task->video_resolution
                             ]);
@@ -5569,26 +5604,28 @@ class AIVideoGenerationService
     /**
      * 根据任务的分辨率字段确定标准化目标档位
      *
-     * 480P(需超分)目标为720p;720P/720p 目标为720p;1080P/1080p 目标为1080p;其他返回空(不处理)
+     * sr_720p(超分720p)目标为720p;sr_1080p(超分1080p)目标为sr_1080p;
+     * 720p 目标为720p;1080p 目标为1080p;480p(原始档,不做超分与标准化)与其他档位返回空(不处理)
      *
      * @param MpGenerateVideoTask|object $task
-     * @return string ''|'720p'|'1080p'
+     * @return string ''|'720p'|'1080p'|'sr_1080p'
      */
     private function getTaskTargetResolution($task)
     {
-        $resolution = strtoupper((string)getProp($task, 'video_resolution', ''));
-        if (strpos($resolution, 'SR_1080') !== false) {
+        $resolution = strtolower(trim((string)getProp($task, 'video_resolution', '')));
+        $upscaleTarget = $this->resolutionUpscaleTarget($resolution);
+        if ($upscaleTarget === '1080p') {
             return 'sr_1080p';
         }
-        if (strpos($resolution, '480') !== false) {
+        if ($upscaleTarget === '720p') {
             return '720p';
         }
-        if (strpos($resolution, '1080') !== false) {
-            return '1080p';
-        }
-        if (strpos($resolution, '720') !== false) {
+        if ($resolution === '720p') {
             return '720p';
         }
+        if ($resolution === '1080p') {
+            return '1080p';
+        }
         return '';
     }
 
@@ -5677,11 +5714,11 @@ class AIVideoGenerationService
                 ];
             }
 
-            // 检查分辨率是否为480p
-            if ($originalTask->video_resolution !== '480P') {
+            // 检查分辨率是否为480p(不区分大小写;480p为原始档,可再手动提交超分到720p)
+            if (strtolower(trim((string)$originalTask->video_resolution)) !== '480p') {
                 return [
                     'success' => false,
-                    'message' => '只支持480P视频超分到720P'
+                    'message' => '只支持480p视频超分到720p'
                 ];
             }
 
@@ -5755,7 +5792,7 @@ class AIVideoGenerationService
                 $enhanceTask = MpGenerateVideoTask::create([
                     'task_id' => $responseData['task_id'],
                     'prompt' => $originalTask->prompt,
-                    'video_resolution' => '720P', // 目标分辨率
+                    'video_resolution' => '720p', // 目标分辨率
                     'status' => MpGenerateVideoTask::STATUS_PROCESSING,
                     'api_type' => 'video_enhance',
                     'extra_params' => [

+ 2 - 1
app/Services/Anime/AnimeService.php

@@ -5269,7 +5269,8 @@ class AnimeService
         }
 
         $video_duration = getProp($data, 'video_duration', 5);
-        $video_resolution = getProp($data, 'video_resolution', '480p');
+        // 默认超分720p档(按480p生成后本地超分到720p);480p为原始档需前端显式指定
+        $video_resolution = getProp($data, 'video_resolution', 'sr_720p');
         $ratio = getProp($data, 'ratio', '9:16');
         $generate_audio = getProp($data, 'generate_audio', 1);
         $seed = getProp($data, 'seed', -1);

+ 9 - 4
app/Services/PointsService.php

@@ -120,7 +120,8 @@ class PointsService
      * 计费规则从 mp_video_models 表读取:
      * - 按秒计费(per_second):积分 = 单价/秒 × 视频时长(秒)
      * - 按次计费(per_call):积分 = 固定单价(如 Gemini 视频理解,暂未接入)
-     * 分辨率会归一化为计费档位;“超分720p”档对应生成分辨率 480p(任务更新代码会对 480p 直接超分到 720p)。
+     * 分辨率会归一化为计费档位;480p(原始档)与 sr_720p(480p生成+本地超分720p)的生成请求均为480p,
+     * 默认共用 480p 档;price_json 配置了 sr_720p 独立单价后按独立档计费(未配置时回退480p档)。
      *
      * @param array $chargeInfo 计费信息(model、video_resolution、video_duration、mode 等)
      * @return int
@@ -165,6 +166,10 @@ class PointsService
         if ($pricePerSecond === null && $resKey === 'sr_1080p') {
             $pricePerSecond = $prices['720p'] ?? null;
         }
+        // sr_720p 无单独定价时回退 480p 档(两者对外请求均为 480p 生成)
+        if ($pricePerSecond === null && $resKey === 'sr_720p') {
+            $pricePerSecond = $prices['480p'] ?? null;
+        }
         if ($pricePerSecond === null || (float)$pricePerSecond <= 0) {
             return self::DEFAULT_VIDEO_CHARGE_POINTS;
         }
@@ -175,8 +180,8 @@ class PointsService
     /**
      * 将分辨率归一化为计费档位
      *
-     * “超分720p”档对应生成分辨率 480p(任务更新代码会对 480p 直接超分到 720p)
-     * 因此 480p / sr_720p / 超分720p 均归一化为 480p 档
+     * 480p(原始档)对应 480p 档;sr_720p / 超分720p 为独立档位
+     * price_json 未配置 sr_720p 单价时由调用方回退 480p 档(两者生成请求均为 480p)
      *
      * @param string $resolution
      * @return string
@@ -198,7 +203,7 @@ class PointsService
             case 'sr_720p':
             case 'sr720p':
             case '超分720p':
-                return '480p';
+                return 'sr_720p';
             case 'sr_1080p':
             case 'sr1080p':
             case '超分1080p':

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
resources/views/animeIndex.blade.php