|
|
@@ -137,12 +137,14 @@ class AIVideoGenerationService
|
|
|
}
|
|
|
|
|
|
// 根据任务类型选择对应的req_key
|
|
|
+ // sr_1080p(超分1080p)按720p生成,本地再超分到1080p
|
|
|
+ $is720Like = in_array(strtolower((string)$task->video_resolution), ['720p', 'sr_1080p'], true);
|
|
|
if ($task->first_frame_url && $task->tail_frame_url) {
|
|
|
- $req_key = $task->video_resolution == '720P' ? 'jimeng_i2v_first_tail_v30' : 'jimeng_i2v_first_tail_v30_1080';
|
|
|
+ $req_key = $is720Like ? 'jimeng_i2v_first_tail_v30' : 'jimeng_i2v_first_tail_v30_1080';
|
|
|
}else if($task->first_frame_url){
|
|
|
- $req_key = $task->video_resolution == '720P' ? 'jimeng_i2v_first_v30' : 'jimeng_i2v_first_v30_1080';
|
|
|
+ $req_key = $is720Like ? 'jimeng_i2v_first_v30' : 'jimeng_i2v_first_v30_1080';
|
|
|
}else{
|
|
|
- $req_key = $task->video_resolution == '720P' ? 'jimeng_t2v_v30' : 'jimeng_t2v_v30_1080p';
|
|
|
+ $req_key = $is720Like ? 'jimeng_t2v_v30' : 'jimeng_t2v_v30_1080p';
|
|
|
}
|
|
|
|
|
|
// 构建即梦AI 3.0 视频生成API请求参数
|
|
|
@@ -235,12 +237,14 @@ class AIVideoGenerationService
|
|
|
}
|
|
|
|
|
|
// 根据任务类型选择对应的req_key
|
|
|
+ // sr_1080p(超分1080p)按720p生成,本地再超分到1080p
|
|
|
+ $is720Like = in_array(strtolower((string)$task->video_resolution), ['720p', 'sr_1080p'], true);
|
|
|
if ($task->first_frame_url && $task->tail_frame_url) {
|
|
|
- $req_key = $task->video_resolution == '720P' ? 'jimeng_i2v_first_tail_v30' : 'jimeng_i2v_first_tail_v30_1080';
|
|
|
+ $req_key = $is720Like ? 'jimeng_i2v_first_tail_v30' : 'jimeng_i2v_first_tail_v30_1080';
|
|
|
}else if($task->first_frame_url){
|
|
|
- $req_key = $task->video_resolution == '720P' ? 'jimeng_i2v_first_v30' : 'jimeng_i2v_first_v30_1080';
|
|
|
+ $req_key = $is720Like ? 'jimeng_i2v_first_v30' : 'jimeng_i2v_first_v30_1080';
|
|
|
}else{
|
|
|
- $req_key = $task->video_resolution == '720P' ? 'jimeng_t2v_v30' : 'jimeng_t2v_v30_1080p';
|
|
|
+ $req_key = $is720Like ? 'jimeng_t2v_v30' : 'jimeng_t2v_v30_1080p';
|
|
|
}
|
|
|
|
|
|
// 构建查询参数
|
|
|
@@ -299,14 +303,14 @@ class AIVideoGenerationService
|
|
|
$videoContent = file_get_contents($result['video_url']);
|
|
|
|
|
|
// 从任务中获取视频分辨率,仅480p视频执行480p->720p超分
|
|
|
- if (strpos(strtoupper((string)$task->video_resolution), '480') !== false) {
|
|
|
+ if ($this->shouldUpgradeVideoResolution($task)) {
|
|
|
dLog('generate')->info('即梦检测到480p视频,开始480p->720p超分', [
|
|
|
'original_url' => $result['video_url'],
|
|
|
'video_resolution' => $task->video_resolution,
|
|
|
'size' => round(strlen($videoContent) / 1024 / 1024, 2) . 'MB'
|
|
|
]);
|
|
|
|
|
|
- $url = upgrade480pTo720p($videoContent, 'video', true);
|
|
|
+ $url = upgrade480pTo720p($videoContent, 'video', true, $this->getVideoUpgradeTarget($task));
|
|
|
if (!$url) {
|
|
|
// 超分失败,上传原视频
|
|
|
dLog('generate')->warning('即梦视频超分失败,使用原视频');
|
|
|
@@ -787,7 +791,7 @@ class AIVideoGenerationService
|
|
|
$apiParams['draft'] = $extraParams['draft'];
|
|
|
}
|
|
|
if (!empty($extraParams['video_resolution'])) {
|
|
|
- $apiParams['resolution'] = strtolower($task->video_resolution);
|
|
|
+ $apiParams['resolution'] = $this->apiRequestResolution($task->video_resolution);
|
|
|
}
|
|
|
if (!empty($extraParams['ratio'])) {
|
|
|
$apiParams['ratio'] = $extraParams['ratio'];
|
|
|
@@ -1017,8 +1021,8 @@ class AIVideoGenerationService
|
|
|
$watermark = !empty($params['watermark']);
|
|
|
$generateAudio = isset($params['generate_audio']) ? (bool)$params['generate_audio'] : true;
|
|
|
|
|
|
- // 分辨率归一化:480p / 720p / 1080p / 4k
|
|
|
- $resolution = strtolower((string)($params['resolution'] ?? $params['video_resolution'] ?? '720p'));
|
|
|
+ // 分辨率归一化:480p / 720p / 1080p / 4k(sr_1080p 请求时按 720p 生成,本地再超分)
|
|
|
+ $resolution = $this->apiRequestResolution((string)($params['resolution'] ?? $params['video_resolution'] ?? '720p'));
|
|
|
if (in_array($resolution, ['4k', '2160p', '2160'], true)) {
|
|
|
$resolution = '4k';
|
|
|
} else {
|
|
|
@@ -1104,9 +1108,9 @@ class AIVideoGenerationService
|
|
|
/**
|
|
|
* 快快AI请求接口模型名适配(仅外部接口调用传参,系统记录保持原模型名)
|
|
|
* 规则:
|
|
|
- * - seed-2:480p/720p -> seed-2;1080p -> seed-2-1080;4k -> seed-2-4k
|
|
|
- * 带参考视频时分别对应 seed-2-vision / seed-2-vision-1080 / seed-2-vision-4k
|
|
|
- * - seed-2-fast / seed-2-mini / seed-2.5:仅支持 -vision(不带分辨率变体)
|
|
|
+ * - seed-2 / seed-2.5:480p/720p -> 原模型;1080p -> -1080;4k -> -4k
|
|
|
+ * 带参考视频时分别对应 -vision / -vision-1080 / -vision-4k
|
|
|
+ * - seed-2-fast / seed-2-mini:仅支持 -vision(不带分辨率变体)
|
|
|
*
|
|
|
* @param string $model 系统内模型名
|
|
|
* @param string $resolution 归一化分辨率(480p/720p/1080p/4k)
|
|
|
@@ -1115,9 +1119,9 @@ class AIVideoGenerationService
|
|
|
*/
|
|
|
private function kuaikuaiRequestModel(string $model, string $resolution, bool $hasReferenceVideo): string
|
|
|
{
|
|
|
- // seed-2 支持 1080p / 4k 分辨率变体
|
|
|
- if ($model === 'seed-2') {
|
|
|
- $base = 'seed-2' . ($hasReferenceVideo ? '-vision' : '');
|
|
|
+ // seed-2 / seed-2.5 支持 1080p / 4k 分辨率变体(与参考视频组合 -vision)
|
|
|
+ if (in_array($model, ['seed-2', 'seed-2.5'], true)) {
|
|
|
+ $base = $model . ($hasReferenceVideo ? '-vision' : '');
|
|
|
if ($resolution === '1080p') {
|
|
|
return $base . '-1080';
|
|
|
}
|
|
|
@@ -1127,12 +1131,11 @@ class AIVideoGenerationService
|
|
|
return $base;
|
|
|
}
|
|
|
|
|
|
- // seed-2-fast / seed-2-mini / seed-2.5 仅适配 -vision,不带分辨率
|
|
|
+ // seed-2-fast / seed-2-mini 仅适配 -vision,不带分辨率
|
|
|
if ($hasReferenceVideo) {
|
|
|
$map = [
|
|
|
'seed-2-fast' => 'seed-2-fast-vision',
|
|
|
'seed-2-mini' => 'seed-2-mini-vision',
|
|
|
- 'seed-2.5' => 'seed-2.5-vision',
|
|
|
];
|
|
|
return $map[$model] ?? $model;
|
|
|
}
|
|
|
@@ -1158,6 +1161,54 @@ class AIVideoGenerationService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 请求外部API时的分辨率映射
|
|
|
+ * sr_1080p(超分1080p)模式:外部按720p生成,本地再超分到1080p,因此请求分辨率统一改为720p
|
|
|
+ *
|
|
|
+ * @param string $resolution
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ private function apiRequestResolution(string $resolution): string
|
|
|
+ {
|
|
|
+ $resolution = strtolower(trim($resolution));
|
|
|
+ if (in_array($resolution, ['sr_1080p', 'sr1080p'], true)) {
|
|
|
+ return '720p';
|
|
|
+ }
|
|
|
+ return $resolution;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断任务是否需要本地超分(480p -> 720p;sr_1080p -> 1080p)
|
|
|
+ * 超分统一走 upgrade480pTo720p(内部按源档位自动选择目标分辨率)
|
|
|
+ *
|
|
|
+ * @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;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取任务本地超分目标档位(显式传给 upgrade480pTo720p)
|
|
|
+ * 480p -> 720p;sr_1080p -> 1080p
|
|
|
+ *
|
|
|
+ * @param object $task
|
|
|
+ * @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 '';
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 将 Seedance 2.0 参考图上传为百度AI网关素材
|
|
|
* 失败处理与智帧AI的processReferenceImagesToAssets一致:删除参考图的同时清理提示词中的<图片N>标记
|
|
|
*
|
|
|
@@ -2610,14 +2661,14 @@ class AIVideoGenerationService
|
|
|
$videoContent = file_get_contents($video_url);
|
|
|
|
|
|
// 从任务中获取视频分辨率,仅480p视频执行480p->720p超分
|
|
|
- if (strpos(strtoupper((string)$task->video_resolution), '480') !== false) {
|
|
|
+ if ($this->shouldUpgradeVideoResolution($task)) {
|
|
|
dLog('generate')->info('Seedance检测到480p视频,开始480p->720p超分', [
|
|
|
'original_url' => $video_url,
|
|
|
'video_resolution' => $task->video_resolution,
|
|
|
'size' => round(strlen($videoContent) / 1024 / 1024, 2) . 'MB'
|
|
|
]);
|
|
|
|
|
|
- $url = upgrade480pTo720p($videoContent, 'video', true);
|
|
|
+ $url = upgrade480pTo720p($videoContent, 'video', true, $this->getVideoUpgradeTarget($task));
|
|
|
if (!$url) {
|
|
|
// 超分失败,上传原视频
|
|
|
dLog('generate')->warning('Seedance视频超分失败,使用原视频');
|
|
|
@@ -2879,14 +2930,14 @@ class AIVideoGenerationService
|
|
|
$videoContent = file_get_contents($video_url);
|
|
|
|
|
|
// 从任务中获取视频分辨率,仅480p视频执行480p->720p超分
|
|
|
- if (strpos(strtoupper((string)$task->video_resolution), '480') !== false) {
|
|
|
+ if ($this->shouldUpgradeVideoResolution($task)) {
|
|
|
dLog('generate')->info('Seedance检测到480p视频,开始480p->720p超分', [
|
|
|
'original_url' => $video_url,
|
|
|
'video_resolution' => $task->video_resolution,
|
|
|
'size' => round(strlen($videoContent) / 1024 / 1024, 2) . 'MB'
|
|
|
]);
|
|
|
|
|
|
- $url = upgrade480pTo720p($videoContent, 'video', true);
|
|
|
+ $url = upgrade480pTo720p($videoContent, 'video', true, $this->getVideoUpgradeTarget($task));
|
|
|
if (!$url) {
|
|
|
// 超分失败,上传原视频
|
|
|
dLog('generate')->warning('Seedance视频超分失败,使用原视频');
|
|
|
@@ -3034,14 +3085,14 @@ class AIVideoGenerationService
|
|
|
$videoContent = file_get_contents($video_url);
|
|
|
|
|
|
// 从任务中获取视频分辨率,仅480p视频执行480p->720p超分
|
|
|
- if (strpos(strtoupper((string)$task->video_resolution), '480') !== false) {
|
|
|
+ if ($this->shouldUpgradeVideoResolution($task)) {
|
|
|
dLog('generate')->info('Seedance回调检测到480p视频,开始480p->720p超分', [
|
|
|
'original_url' => $video_url,
|
|
|
'video_resolution' => $task->video_resolution,
|
|
|
'size' => round(strlen($videoContent) / 1024 / 1024, 2) . 'MB'
|
|
|
]);
|
|
|
|
|
|
- $url = upgrade480pTo720p($videoContent, 'video', true);
|
|
|
+ $url = upgrade480pTo720p($videoContent, 'video', true, $this->getVideoUpgradeTarget($task));
|
|
|
if (!$url) {
|
|
|
// 超分失败,上传原视频
|
|
|
dLog('generate')->warning('Seedance回调视频超分失败,使用原视频');
|
|
|
@@ -3592,14 +3643,14 @@ class AIVideoGenerationService
|
|
|
$videoContent = file_get_contents($video_url);
|
|
|
|
|
|
// 从任务中获取视频分辨率,仅480p视频执行480p->720p超分
|
|
|
- if (strpos(strtoupper((string)$task->video_resolution), '480') !== false) {
|
|
|
+ if ($this->shouldUpgradeVideoResolution($task)) {
|
|
|
dLog('generate')->info('可灵检测到480p视频,开始480p->720p超分', [
|
|
|
'original_url' => $video_url,
|
|
|
'video_resolution' => $task->video_resolution,
|
|
|
'size' => round(strlen($videoContent) / 1024 / 1024, 2) . 'MB'
|
|
|
]);
|
|
|
|
|
|
- $url = upgrade480pTo720p($videoContent, 'video', true);
|
|
|
+ $url = upgrade480pTo720p($videoContent, 'video', true, $this->getVideoUpgradeTarget($task));
|
|
|
if (!$url) {
|
|
|
// 超分失败,上传原视频
|
|
|
dLog('generate')->warning('可灵视频超分失败,使用原视频');
|
|
|
@@ -4698,7 +4749,7 @@ class AIVideoGenerationService
|
|
|
'model_code' => $extraParams['model_code'] ?? 'zhizhen-20',
|
|
|
'prompt' => $task->prompt,
|
|
|
'video_duration' => $extraParams['video_duration'] ?? 5,
|
|
|
- 'video_resolution' => $task->video_resolution,
|
|
|
+ 'video_resolution' => $this->apiRequestResolution((string)$task->video_resolution),
|
|
|
'video_ratio' => $extraParams['video_ratio'] ?? '9:16',
|
|
|
];
|
|
|
|
|
|
@@ -4709,7 +4760,12 @@ class AIVideoGenerationService
|
|
|
|
|
|
// 添加parameters参数
|
|
|
if (!empty($extraParams['parameters'])) {
|
|
|
- $apiParams['parameters'] = $extraParams['parameters'];
|
|
|
+ $parameters = $extraParams['parameters'];
|
|
|
+ // sr_1080p 请求时按 720p 生成,本地再超分
|
|
|
+ if (isset($parameters['resolution'])) {
|
|
|
+ $parameters['resolution'] = $this->apiRequestResolution((string)$parameters['resolution']);
|
|
|
+ }
|
|
|
+ $apiParams['parameters'] = $parameters;
|
|
|
}
|
|
|
|
|
|
dLog('generate')->info('统一API视频生成参数: ', $apiParams);
|
|
|
@@ -4880,14 +4936,14 @@ class AIVideoGenerationService
|
|
|
$videoContent = file_get_contents($videoUrl);
|
|
|
|
|
|
// 从任务中获取视频分辨率,仅480p视频执行480p->720p超分
|
|
|
- if (strpos(strtoupper((string)$task->video_resolution), '480') !== false) {
|
|
|
+ if ($this->shouldUpgradeVideoResolution($task)) {
|
|
|
dLog('generate')->info('检测到480p视频,开始480p->720p超分', [
|
|
|
'original_url' => $videoUrl,
|
|
|
'video_resolution' => $task->video_resolution,
|
|
|
'size' => round(strlen($videoContent) / 1024 / 1024, 2) . 'MB'
|
|
|
]);
|
|
|
|
|
|
- $enhancedUrl = upgrade480pTo720p($videoContent, 'video', true);
|
|
|
+ $enhancedUrl = upgrade480pTo720p($videoContent, 'video', true, $this->getVideoUpgradeTarget($task));
|
|
|
if ($enhancedUrl) {
|
|
|
dLog('generate')->info('视频超分成功', ['enhanced_url' => $enhancedUrl]);
|
|
|
$url = $enhancedUrl;
|
|
|
@@ -5274,7 +5330,7 @@ class AIVideoGenerationService
|
|
|
*/
|
|
|
private function ensureStandardVideoResolution($videoUrl, $targetResolution = '720p')
|
|
|
{
|
|
|
- if (empty($videoUrl) || !in_array($targetResolution, ['720p', '1080p'])) {
|
|
|
+ if (empty($videoUrl) || !in_array($targetResolution, ['720p', '1080p', 'sr_1080p'])) {
|
|
|
return $videoUrl;
|
|
|
}
|
|
|
|
|
|
@@ -5330,10 +5386,12 @@ class AIVideoGenerationService
|
|
|
return $videoUrl;
|
|
|
}
|
|
|
|
|
|
- // 3. 档位校验:仅处理实际属于720p/1080p档位的视频(短边接近目标值),其他分辨率不处理
|
|
|
+ // 3. 档位校验:仅处理实际属于目标档位的视频(短边接近目标值),其他分辨率不处理
|
|
|
$shortSide = min($width, $height);
|
|
|
+ // 兜底标准化:仅处理已属于目标档位的视频(超分由 upgrade480pTo720p 负责,这里不做放大)
|
|
|
$targetShortSide = $targetResolution === '720p' ? 720 : 1080;
|
|
|
- if (abs($shortSide - $targetShortSide) > 40) {
|
|
|
+ $isMatch = abs($shortSide - $targetShortSide) <= 40;
|
|
|
+ if (!$isMatch) {
|
|
|
dLog('video_standard')->info('视频不属于目标分辨率档位,跳过处理', [
|
|
|
'url' => $videoUrl,
|
|
|
'source' => $width . 'x' . $height,
|
|
|
@@ -5348,6 +5406,7 @@ class AIVideoGenerationService
|
|
|
$targetWidth = $isPortrait ? 720 : 1280;
|
|
|
$targetHeight = $isPortrait ? 1280 : 720;
|
|
|
} else {
|
|
|
+ // 1080p / sr_1080p 统一目标:16:9 -> 1920x1080,9:16 -> 1080x1920
|
|
|
$targetWidth = $isPortrait ? 1080 : 1920;
|
|
|
$targetHeight = $isPortrait ? 1920 : 1080;
|
|
|
}
|
|
|
@@ -5419,6 +5478,9 @@ class AIVideoGenerationService
|
|
|
private function getTaskTargetResolution($task)
|
|
|
{
|
|
|
$resolution = strtoupper((string)getProp($task, 'video_resolution', ''));
|
|
|
+ if (strpos($resolution, 'SR_1080') !== false) {
|
|
|
+ return 'sr_1080p';
|
|
|
+ }
|
|
|
if (strpos($resolution, '480') !== false) {
|
|
|
return '720p';
|
|
|
}
|