|
|
@@ -1237,15 +1237,23 @@ class AIVideoGenerationService
|
|
|
// 上传素材(已存在则直接复用,不重复上传)
|
|
|
$createResult = $this->createSeedance20Asset($imageUrl, "参考图片_{$imageIndex}_" . time());
|
|
|
|
|
|
+ // 网关素材异步处理为间歇性故障,失败后间隔重试,避免因网关临时故障误判
|
|
|
+ for ($retry = 1; $retry <= 5 && $createResult['code'] !== 0; $retry++) {
|
|
|
+ sleep($retry <= 3 ? 10 : 30);
|
|
|
+ dLog('generate')->warning("图片 {$imageIndex} Seedance 2.0素材第 {$retry} 次重试上传");
|
|
|
+ $createResult = $this->createSeedance20Asset($imageUrl, "参考图片_{$imageIndex}_" . time());
|
|
|
+ }
|
|
|
+
|
|
|
if ($createResult['code'] !== 0) {
|
|
|
- dLog('generate')->warning("图片 {$imageIndex} 创建Seedance 2.0素材失败: " . $createResult['msg']);
|
|
|
- logDB('generate', 'warning', 'Seedance2.0创建素材失败', [
|
|
|
+ $errorMessage = (string)($createResult['msg'] ?? '素材创建失败');
|
|
|
+ dLog('generate')->error("图片 {$imageIndex} 创建Seedance 2.0素材失败: " . $errorMessage);
|
|
|
+ logDB('generate', 'error', 'Seedance2.0创建素材失败', [
|
|
|
'image_url' => $imageUrl,
|
|
|
'index' => $imageIndex,
|
|
|
- 'error' => $createResult['msg']
|
|
|
+ 'error' => $errorMessage
|
|
|
]);
|
|
|
- $failedIndexes[] = $imageIndex;
|
|
|
- continue;
|
|
|
+ // 素材不可用会直接影响视频效果,且任务会扣费,失败直接中断任务创建
|
|
|
+ Utils::throwError('20003:参考图片' . $imageIndex . '上传素材失败:' . $errorMessage);
|
|
|
}
|
|
|
|
|
|
$assetIds[] = $createResult['data']['asset_id'];
|
|
|
@@ -1290,10 +1298,6 @@ class AIVideoGenerationService
|
|
|
|
|
|
if ($needAdjust) {
|
|
|
dLog('generate')->info('Seedance 2.0提示词图片序号调整完成');
|
|
|
- logDB('generate', 'info', 'Seedance2.0提示词调整', [
|
|
|
- 'failed_indexes' => $failedIndexes,
|
|
|
- 'adjusted_prompt' => $fullPrompt
|
|
|
- ]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1358,16 +1362,24 @@ class AIVideoGenerationService
|
|
|
// 上传素材(已存在则直接复用,不重复上传)
|
|
|
$createResult = $this->createSeedance20Asset($url, "{$label}_{$mediaIndex}_" . time(), $assetType);
|
|
|
|
|
|
+ // 网关素材异步处理为间歇性故障,失败后间隔重试,避免因网关临时故障误判
|
|
|
+ for ($retry = 1; $retry <= 5 && $createResult['code'] !== 0; $retry++) {
|
|
|
+ sleep($retry <= 3 ? 10 : 30);
|
|
|
+ dLog('generate')->warning("{$label} {$mediaIndex} Seedance 2.0素材第 {$retry} 次重试上传");
|
|
|
+ $createResult = $this->createSeedance20Asset($url, "{$label}_{$mediaIndex}_" . time(), $assetType);
|
|
|
+ }
|
|
|
+
|
|
|
if ($createResult['code'] !== 0) {
|
|
|
- dLog('generate')->warning("{$label} {$mediaIndex} 创建Seedance 2.0素材失败: " . $createResult['msg']);
|
|
|
- logDB('generate', 'warning', 'Seedance2.0创建素材失败', [
|
|
|
+ $errorMessage = (string)($createResult['msg'] ?? '素材创建失败');
|
|
|
+ dLog('generate')->error("{$label} {$mediaIndex} 创建Seedance 2.0素材失败: " . $errorMessage);
|
|
|
+ logDB('generate', 'error', 'Seedance2.0创建素材失败', [
|
|
|
'url' => $url,
|
|
|
'asset_type' => $assetType,
|
|
|
'index' => $mediaIndex,
|
|
|
- 'error' => $createResult['msg']
|
|
|
+ 'error' => $errorMessage
|
|
|
]);
|
|
|
- $failedIndexes[] = $mediaIndex;
|
|
|
- continue;
|
|
|
+ // 素材不可用会直接影响视频效果,且任务会扣费,失败直接中断任务创建
|
|
|
+ Utils::throwError('20003:' . $label . $mediaIndex . '上传素材失败:' . $errorMessage);
|
|
|
}
|
|
|
|
|
|
$assetIds[] = $createResult['data']['asset_id'];
|
|
|
@@ -1413,10 +1425,6 @@ class AIVideoGenerationService
|
|
|
|
|
|
if ($needAdjust) {
|
|
|
dLog('generate')->info('Seedance 2.0提示词' . $label . '序号调整完成');
|
|
|
- logDB('generate', 'info', 'Seedance2.0提示词调整', [
|
|
|
- 'failed_indexes' => $failedIndexes,
|
|
|
- 'adjusted_prompt' => $fullPrompt
|
|
|
- ]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1453,15 +1461,22 @@ class AIVideoGenerationService
|
|
|
$name = 'seedance20_' . time() . '_' . uniqid();
|
|
|
$createResult = $this->createSeedance20Asset($imageUrl, $name);
|
|
|
|
|
|
+ // 网关素材异步处理为间歇性故障,失败后间隔重试,避免因网关临时故障误判
|
|
|
+ for ($retry = 1; $retry <= 5 && $createResult['code'] !== 0; $retry++) {
|
|
|
+ sleep($retry <= 3 ? 10 : 30);
|
|
|
+ dLog('generate')->warning('Seedance 2.0 图片上传素材第 ' . $retry . ' 次重试: ' . $imageUrl);
|
|
|
+ $createResult = $this->createSeedance20Asset($imageUrl, $name);
|
|
|
+ }
|
|
|
+
|
|
|
if ($createResult['code'] !== 0) {
|
|
|
- // 上传失败:移除该图片,继续处理其他图片
|
|
|
- dLog('generate')->warning('Seedance 2.0 图片上传素材失败,已从content中移除: ' . $imageUrl . ',原因: ' . $createResult['msg']);
|
|
|
- logDB('generate', 'warning', 'Seedance2.0图片转素材失败', [
|
|
|
+ $errorMessage = (string)($createResult['msg'] ?? '素材创建失败');
|
|
|
+ dLog('generate')->error('Seedance 2.0 图片上传素材失败: ' . $imageUrl . ',原因: ' . $errorMessage);
|
|
|
+ logDB('generate', 'error', 'Seedance2.0图片转素材失败', [
|
|
|
'image_url' => $imageUrl,
|
|
|
- 'error' => $createResult['msg']
|
|
|
+ 'error' => $errorMessage
|
|
|
]);
|
|
|
- unset($content[$index]);
|
|
|
- continue;
|
|
|
+ // 素材不可用会直接影响视频效果,且任务会扣费,失败直接中断任务创建
|
|
|
+ Utils::throwError('20003:图片上传素材失败:' . $errorMessage);
|
|
|
}
|
|
|
|
|
|
$item['image_url']['url'] = 'asset://' . $createResult['data']['asset_id'];
|
|
|
@@ -1492,18 +1507,29 @@ class AIVideoGenerationService
|
|
|
];
|
|
|
}
|
|
|
|
|
|
- // 先获取表中是否已有该url(仅限百度网关来源的素材)
|
|
|
- $asset = DB::table('mp_assets')->where('url', $url)->where('source_type', 'baidu')->first();
|
|
|
+ // 先获取表中是否已有该url(仅限百度网关来源且状态可用的素材)
|
|
|
+ // 只复用百度网关上传成功的素材,避免复用 Failed 记录或其它网关(ark/kuaikuai)的素材 ID
|
|
|
+ $asset = DB::table('mp_assets')
|
|
|
+ ->where('url', $url)
|
|
|
+ ->where('source_type', 'baidu')
|
|
|
+ ->where('status', MpAsset::STATUS_ACTIVE)
|
|
|
+ ->orderBy('id', 'desc')
|
|
|
+ ->first();
|
|
|
if ($asset) {
|
|
|
- dLog('generate')->info('Seedance 2.0 素材已存在,直接复用: ' . $url . ' => ' . $asset->asset_id);
|
|
|
- return [
|
|
|
- 'code' => 0,
|
|
|
- 'msg' => '创建成功',
|
|
|
- 'data' => [
|
|
|
- 'asset_id' => $asset->asset_id,
|
|
|
- 'group_id' => $asset->group_id,
|
|
|
- ]
|
|
|
- ];
|
|
|
+ $extraParams = is_array($asset->extra_params) ? $asset->extra_params : json_decode((string)$asset->extra_params, true);
|
|
|
+ $isBaiduGatewayAsset = is_array($extraParams) && isset($extraParams['Result']);
|
|
|
+ if ($isBaiduGatewayAsset) {
|
|
|
+ dLog('generate')->info('Seedance 2.0 素材已存在,直接复用: ' . $url . ' => ' . $asset->asset_id);
|
|
|
+ return [
|
|
|
+ 'code' => 0,
|
|
|
+ 'msg' => '创建成功',
|
|
|
+ 'data' => [
|
|
|
+ 'asset_id' => $asset->asset_id,
|
|
|
+ 'group_id' => $asset->group_id,
|
|
|
+ 'status' => 'ready',
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
$groupId = $this->ensureSeedance20AssetGroup();
|
|
|
@@ -1573,10 +1599,6 @@ class AIVideoGenerationService
|
|
|
dLog('generate')->info("Seedance 2.0 素材 {$assetId} 状态查询第 {$attempt} 次,状态: {$assetStatus}");
|
|
|
|
|
|
if ($assetStatus === 'Active') {
|
|
|
- logDB('generate', 'info', 'Seedance2.0素材处理成功', [
|
|
|
- 'asset_id' => $assetId,
|
|
|
- 'url' => $url
|
|
|
- ]);
|
|
|
return [
|
|
|
'code' => 0,
|
|
|
'msg' => '创建成功',
|
|
|
@@ -1776,7 +1798,6 @@ class AIVideoGenerationService
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
- logDB('generate', 'info', 'Seedance2.0素材组创建成功', ['group_id' => $groupId]);
|
|
|
return $groupId;
|
|
|
}
|
|
|
|
|
|
@@ -1805,7 +1826,6 @@ class AIVideoGenerationService
|
|
|
|
|
|
$responseData = json_decode($response->getBody(), true);
|
|
|
dLog('generate')->info('Seedance 2.0 网关 ' . $action . ' 响应: ', $responseData);
|
|
|
- logDB('generate', 'info', 'Seedance2.0网关' . $action, ['params' => $body, 'response' => $responseData]);
|
|
|
|
|
|
return $responseData;
|
|
|
}
|
|
|
@@ -1849,7 +1869,6 @@ class AIVideoGenerationService
|
|
|
}
|
|
|
|
|
|
dLog('generate')->info('快快AI网关 ' . $method . ' ' . $path . ' 响应: ', $responseData);
|
|
|
- logDB('generate', 'info', '快快AI素材网关' . $method . $path, ['params' => $body, 'response' => $responseData]);
|
|
|
|
|
|
return $responseData;
|
|
|
}
|
|
|
@@ -2050,19 +2069,29 @@ class AIVideoGenerationService
|
|
|
return ['code' => 1, 'msg' => '素材URL不能为空', 'data' => null];
|
|
|
}
|
|
|
|
|
|
- // 先获取表中是否已有该url(仅限快快AI来源的素材)
|
|
|
- $asset = DB::table('mp_assets')->where('url', $url)->where('source_type', 'kuaikuai')->first();
|
|
|
+ // 先获取表中是否已有该url(仅限快快AI来源且状态可用的素材)
|
|
|
+ // 只复用网关上传成功的素材,避免复用 Failed 记录或其它网关(ark)的素材 ID
|
|
|
+ $asset = DB::table('mp_assets')
|
|
|
+ ->where('url', $url)
|
|
|
+ ->where('source_type', 'kuaikuai')
|
|
|
+ ->where('status', MpAsset::STATUS_ACTIVE)
|
|
|
+ ->orderBy('id', 'desc')
|
|
|
+ ->first();
|
|
|
if ($asset) {
|
|
|
- dLog('generate')->info('快快AI素材已存在,直接复用: ' . $url . ' => ' . $asset->asset_id);
|
|
|
- return [
|
|
|
- 'code' => 0,
|
|
|
- 'msg' => '创建成功',
|
|
|
- 'data' => [
|
|
|
- 'asset_id' => $asset->asset_id,
|
|
|
- 'group_id' => $asset->group_id,
|
|
|
- 'status' => $asset->status === MpAsset::STATUS_ACTIVE ? 'ready' : ($asset->status === MpAsset::STATUS_FAILED ? 'failed' : 'pending'),
|
|
|
- ],
|
|
|
- ];
|
|
|
+ $extraParams = is_array($asset->extra_params) ? $asset->extra_params : json_decode((string)$asset->extra_params, true);
|
|
|
+ $isKuaikuaiGatewayAsset = is_array($extraParams) && isset($extraParams['success']);
|
|
|
+ if ($isKuaikuaiGatewayAsset) {
|
|
|
+ dLog('generate')->info('快快AI素材已存在,直接复用: ' . $url . ' => ' . $asset->asset_id);
|
|
|
+ return [
|
|
|
+ 'code' => 0,
|
|
|
+ 'msg' => '创建成功',
|
|
|
+ 'data' => [
|
|
|
+ 'asset_id' => $asset->asset_id,
|
|
|
+ 'group_id' => $asset->group_id,
|
|
|
+ 'status' => 'ready',
|
|
|
+ ],
|
|
|
+ ];
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
$groupId = $this->ensureKuaikuaiAssetGroup();
|
|
|
@@ -2109,7 +2138,6 @@ class AIVideoGenerationService
|
|
|
|
|
|
// 网关已就绪/失败,直接返回
|
|
|
if (in_array($status, ['ready', 'success'], true)) {
|
|
|
- logDB('generate', 'info', '快快AI素材上传成功', ['asset_id' => $assetId, 'url' => $url]);
|
|
|
return [
|
|
|
'code' => 0,
|
|
|
'msg' => '创建成功',
|
|
|
@@ -2142,7 +2170,6 @@ class AIVideoGenerationService
|
|
|
dLog('generate')->info("快快AI素材 {$assetId} 状态查询第 {$attempt} 次,状态: {$lastStatus}");
|
|
|
|
|
|
if (in_array($lastStatus, ['ready', 'success'], true)) {
|
|
|
- logDB('generate', 'info', '快快AI素材处理成功', ['asset_id' => $assetId, 'url' => $url]);
|
|
|
return [
|
|
|
'code' => 0,
|
|
|
'msg' => '创建成功',
|
|
|
@@ -2301,14 +2328,22 @@ class AIVideoGenerationService
|
|
|
$name = 'kuaikuai_' . time() . '_' . uniqid();
|
|
|
$createResult = $this->createKuaikuaiAsset($imageUrl, $name, MpAsset::TYPE_IMAGE, '视频内容图片');
|
|
|
|
|
|
- if ($createResult['code'] !== 0) {
|
|
|
- dLog('generate')->warning('快快AI图片上传素材失败,已从content中移除: ' . $imageUrl . ',原因: ' . $createResult['msg']);
|
|
|
- logDB('generate', 'warning', '快快AI图片转素材失败', [
|
|
|
+ // 网关素材异步处理为间歇性故障,失败后间隔重试,避免因网关临时故障误判
|
|
|
+ for ($retry = 1; $retry <= 5 && ($createResult['code'] !== 0 || ($createResult['data']['status'] ?? '') !== 'ready'); $retry++) {
|
|
|
+ sleep($retry <= 3 ? 10 : 30);
|
|
|
+ dLog('generate')->warning('快快AI图片上传素材第 ' . $retry . ' 次重试: ' . $imageUrl);
|
|
|
+ $createResult = $this->createKuaikuaiAsset($imageUrl, $name, MpAsset::TYPE_IMAGE, '视频内容图片');
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($createResult['code'] !== 0 || ($createResult['data']['status'] ?? '') !== 'ready') {
|
|
|
+ $errorMessage = (string)($createResult['msg'] ?? '素材创建失败');
|
|
|
+ dLog('generate')->error('快快AI图片上传素材失败: ' . $imageUrl . ',原因: ' . $errorMessage);
|
|
|
+ logDB('generate', 'error', '快快AI图片转素材失败', [
|
|
|
'image_url' => $imageUrl,
|
|
|
- 'error' => $createResult['msg'],
|
|
|
+ 'error' => $errorMessage,
|
|
|
]);
|
|
|
- unset($content[$index]);
|
|
|
- continue;
|
|
|
+ // 素材不可用会直接影响视频效果,且任务会扣费,失败直接中断任务创建
|
|
|
+ Utils::throwError('20003:图片上传素材失败:' . $errorMessage);
|
|
|
}
|
|
|
|
|
|
$item['image_url']['url'] = 'asset://' . $createResult['data']['asset_id'];
|
|
|
@@ -2380,16 +2415,24 @@ class AIVideoGenerationService
|
|
|
// 上传素材(已存在则直接复用,不重复上传)
|
|
|
$createResult = $this->createKuaikuaiAsset($url, "{$label}_{$mediaIndex}_" . time(), $assetType, $label);
|
|
|
|
|
|
- if ($createResult['code'] !== 0) {
|
|
|
- dLog('generate')->warning("{$label} {$mediaIndex} 创建快快AI素材失败: " . $createResult['msg']);
|
|
|
- logDB('generate', 'warning', '快快AI创建素材失败', [
|
|
|
+ // 网关素材异步处理为间歇性故障,失败后间隔重试,避免因网关临时故障误判
|
|
|
+ for ($retry = 1; $retry <= 5 && ($createResult['code'] !== 0 || ($createResult['data']['status'] ?? '') !== 'ready'); $retry++) {
|
|
|
+ sleep($retry <= 3 ? 10 : 30);
|
|
|
+ dLog('generate')->warning("{$label} {$mediaIndex} 快快AI素材第 {$retry} 次重试上传");
|
|
|
+ $createResult = $this->createKuaikuaiAsset($url, "{$label}_{$mediaIndex}_" . time(), $assetType, $label);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($createResult['code'] !== 0 || ($createResult['data']['status'] ?? '') !== 'ready') {
|
|
|
+ $errorMessage = (string)($createResult['msg'] ?? '素材创建失败');
|
|
|
+ dLog('generate')->error("{$label} {$mediaIndex} 创建快快AI素材失败: " . $errorMessage);
|
|
|
+ logDB('generate', 'error', '快快AI创建素材失败', [
|
|
|
'url' => $url,
|
|
|
'asset_type' => $assetType,
|
|
|
'index' => $mediaIndex,
|
|
|
- 'error' => $createResult['msg'],
|
|
|
+ 'error' => $errorMessage,
|
|
|
]);
|
|
|
- $failedIndexes[] = $mediaIndex;
|
|
|
- continue;
|
|
|
+ // 素材不可用会直接影响视频效果,且任务会扣费,失败直接中断任务创建
|
|
|
+ Utils::throwError('20003:' . $label . $mediaIndex . '上传素材失败:' . $errorMessage);
|
|
|
}
|
|
|
|
|
|
$assetIds[] = $createResult['data']['asset_id'];
|
|
|
@@ -2434,10 +2477,6 @@ class AIVideoGenerationService
|
|
|
|
|
|
if ($needAdjust) {
|
|
|
dLog('generate')->info('快快AI提示词' . $label . '序号调整完成');
|
|
|
- logDB('generate', 'info', '快快AI提示词调整', [
|
|
|
- 'failed_indexes' => $failedIndexes,
|
|
|
- 'adjusted_prompt' => $fullPrompt,
|
|
|
- ]);
|
|
|
}
|
|
|
}
|
|
|
|