|
|
@@ -313,6 +313,9 @@ class AIVideoGenerationService
|
|
|
case 'zzengine':
|
|
|
$this->updateUnifiedApiTask($task);
|
|
|
break;
|
|
|
+ case 'video_enhance':
|
|
|
+ $this->updateVideoEnhanceTask($task);
|
|
|
+ break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
@@ -2260,7 +2263,7 @@ class AIVideoGenerationService
|
|
|
'api_type' => 'zzengine',
|
|
|
'extra_params' => [
|
|
|
'task_type' => 'video',
|
|
|
- 'model_code' => $params['model_code'] ?? 'zhizhen-20-mini',
|
|
|
+ 'model_code' => $params['model_code'] ?? 'zhizhen-20',
|
|
|
'callback_url' => $params['callback_url'] ?? '',
|
|
|
'video_duration' => $params['video_duration'] ?? 5,
|
|
|
'video_ratio' => $params['video_ratio'] ?? '9:16',
|
|
|
@@ -2300,7 +2303,7 @@ class AIVideoGenerationService
|
|
|
// 构建统一API请求参数
|
|
|
$apiParams = [
|
|
|
'task_type' => 'video',
|
|
|
- 'model_code' => $extraParams['model_code'] ?? 'zhizhen-20-mini',
|
|
|
+ 'model_code' => $extraParams['model_code'] ?? 'zhizhen-20',
|
|
|
'prompt' => $task->prompt,
|
|
|
'video_duration' => $extraParams['video_duration'] ?? 5,
|
|
|
'video_resolution' => $task->video_resolution,
|
|
|
@@ -2479,17 +2482,40 @@ class AIVideoGenerationService
|
|
|
}
|
|
|
|
|
|
if ($videoUrl) {
|
|
|
- // 保存视频到TOS
|
|
|
+ // 保存视频到TOS并超分
|
|
|
try {
|
|
|
- $video_name = 'ai_generation_' . time() . '_' . uniqid();
|
|
|
- $video_ext = getVideoExtFromUrl($videoUrl);
|
|
|
- $video_name = $video_name . $video_ext;
|
|
|
- $url = uploadStreamByTos('video', file_get_contents($videoUrl), $video_name);
|
|
|
- $returnData['result_url'] = $url;
|
|
|
+ // 下载视频内容
|
|
|
+ $videoContent = file_get_contents($videoUrl);
|
|
|
|
|
|
- // 压缩视频
|
|
|
- $compressed_video_url = compressVideo($url);
|
|
|
- $returnData['compressed_url'] = $compressed_video_url ?: $url;
|
|
|
+ // 使用upgrade480pTo720p方法进行超分(传入视频内容)
|
|
|
+ dLog('generate')->info('开始对视频进行480p->720p超分', [
|
|
|
+ 'original_url' => $videoUrl,
|
|
|
+ 'size' => round(strlen($videoContent) / 1024 / 1024, 2) . 'MB'
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $url = upgrade480pTo720p($videoContent, 'video', true);
|
|
|
+
|
|
|
+ if ($url) {
|
|
|
+ // 超分成功
|
|
|
+ dLog('generate')->info('视频超分成功', ['enhanced_url' => $url]);
|
|
|
+ $returnData['result_url'] = $url;
|
|
|
+
|
|
|
+ // 压缩视频
|
|
|
+ $compressed_video_url = compressVideo($url);
|
|
|
+ $returnData['compressed_url'] = $compressed_video_url ?: $url;
|
|
|
+ } else {
|
|
|
+ // 超分失败,使用原视频
|
|
|
+ dLog('generate')->warning('视频超分失败,使用原视频');
|
|
|
+ $video_name = 'ai_generation_' . time() . '_' . uniqid();
|
|
|
+ $video_ext = getVideoExtFromUrl($videoUrl);
|
|
|
+ $video_name = $video_name . $video_ext;
|
|
|
+ $url = uploadStreamByTos('video', $videoContent, $video_name);
|
|
|
+ $returnData['result_url'] = $url;
|
|
|
+
|
|
|
+ // 压缩视频
|
|
|
+ $compressed_video_url = compressVideo($url);
|
|
|
+ $returnData['compressed_url'] = $compressed_video_url ?: $url;
|
|
|
+ }
|
|
|
} catch (\Exception $e) {
|
|
|
dLog('generate')->error('保存视频到TOS失败', ['error' => $e->getMessage()]);
|
|
|
$returnData['result_url'] = $videoUrl; // 如果保存失败,使用原URL
|
|
|
@@ -2563,7 +2589,37 @@ class AIVideoGenerationService
|
|
|
if ($statusInfo['status'] === 'success') {
|
|
|
logDB('generate', 'info', '统一API视频生成任务成功', ['id' => $task->id, 'result_url' => $statusInfo['result_url']]);
|
|
|
|
|
|
- // 同步调整分镜视频状态和结果(兼容全能模式)
|
|
|
+ // // 判断是否为480p视频,如果是则触发超分逻辑
|
|
|
+ // if ($task->video_resolution === '480P') {
|
|
|
+ // logDB('video_enhance', 'info', '检测到480p视频生成成功,准备自动触发超分', [
|
|
|
+ // 'task_id' => $task->id
|
|
|
+ // ]);
|
|
|
+
|
|
|
+ // // 先更新任务状态为成功
|
|
|
+ // $task->updateStatus(MpGenerateVideoTask::STATUS_SUCCESS, $statusInfo);
|
|
|
+
|
|
|
+ // // 调用超分任务提交方法
|
|
|
+ // $enhanceResult = $this->submitVideoEnhanceTask($task->id);
|
|
|
+
|
|
|
+ // if ($enhanceResult['success']) {
|
|
|
+ // logDB('video_enhance', 'info', '480p视频超分任务已自动提交', [
|
|
|
+ // 'original_task_id' => $task->id,
|
|
|
+ // 'enhance_task_id' => $enhanceResult['enhance_task_id']
|
|
|
+ // ]);
|
|
|
+ // } else {
|
|
|
+ // logDB('video_enhance', 'warning', '480p视频超分任务提交失败,保持原480p视频', [
|
|
|
+ // 'task_id' => $task->id,
|
|
|
+ // 'error' => $enhanceResult['message']
|
|
|
+ // ]);
|
|
|
+
|
|
|
+ // // 超分失败时,仍然更新分镜表为480p视频
|
|
|
+ // $this->update480pVideoToSegment($task, $statusInfo);
|
|
|
+ // }
|
|
|
+
|
|
|
+ // // 480p视频已触发超分,直接返回,不继续后续更新操作
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+
|
|
|
$segment_id = $this->getSegmentIdFromTask($task);
|
|
|
if ($segment_id && isset($statusInfo['result_url'])) {
|
|
|
try {
|
|
|
@@ -2679,5 +2735,505 @@ class AIVideoGenerationService
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新480p视频到分镜表(超分失败时的降级处理)
|
|
|
+ *
|
|
|
+ * @param MpGenerateVideoTask $task
|
|
|
+ * @param array $statusInfo
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ private function update480pVideoToSegment($task, $statusInfo): void
|
|
|
+ {
|
|
|
+ $segment_id = $this->getSegmentIdFromTask($task);
|
|
|
+ if (!$segment_id || !isset($statusInfo['result_url'])) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ $now = date('Y-m-d H:i:s');
|
|
|
+
|
|
|
+ // 构建更新数据
|
|
|
+ $segmentUpdateData = [
|
|
|
+ 'origin_video_url' => $statusInfo['result_url'],
|
|
|
+ 'video_task_status' => '已完成',
|
|
|
+ 'current_type' => 2,
|
|
|
+ 'last_frame_url' => $statusInfo['last_frame_url'] ?? '',
|
|
|
+ 'updated_at' => $now
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 使用查询任务时已压缩的视频URL,避免重复压缩
|
|
|
+ $segmentUpdateData['video_url'] = $statusInfo['compressed_url'] ?? $statusInfo['result_url'];
|
|
|
+
|
|
|
+ // 只有当video_duration存在且大于0时才更新
|
|
|
+ if (isset($statusInfo['video_duration']) && $statusInfo['video_duration'] > 0) {
|
|
|
+ $segmentUpdateData['video_duration'] = $statusInfo['video_duration'];
|
|
|
+ $segmentUpdateData['video_time_point_start'] = 0;
|
|
|
+
|
|
|
+ // 获取audio_duration(兼容全能模式)
|
|
|
+ $audio_duration = $this->getAudioDuration($task, $segment_id, $statusInfo['video_duration'] ?? null);
|
|
|
+ $segmentUpdateData['video_time_point_end'] = $audio_duration ?? 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新分镜表(兼容act模式)
|
|
|
+ $this->updateSegmentTable($task, $segmentUpdateData);
|
|
|
+
|
|
|
+ // 添加视频生成对话记录
|
|
|
+ $this->addVideoGenerationRecords($task, $segment_id, $statusInfo['result_url']);
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ dLog('generate')->error('480p视频更新分镜表失败', [
|
|
|
+ 'segment_id' => $segment_id,
|
|
|
+ 'task_id' => $task->id,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 提交视频超分任务(480p -> 720p)
|
|
|
+ *
|
|
|
+ * @param int $taskId mp_generate_video_tasks表的任务ID
|
|
|
+ * @return array 包含成功状态和新任务ID或错误信息
|
|
|
+ */
|
|
|
+ public function submitVideoEnhanceTask(int $taskId): array
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ // 查询原任务
|
|
|
+ $originalTask = MpGenerateVideoTask::find($taskId);
|
|
|
+ if (!$originalTask) {
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => '原任务不存在'
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查任务是否已完成
|
|
|
+ if ($originalTask->status !== MpGenerateVideoTask::STATUS_SUCCESS) {
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => '只能对已成功完成的任务进行超分处理'
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查分辨率是否为480p
|
|
|
+ if ($originalTask->video_resolution !== '480P') {
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => '只支持480P视频超分到720P'
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否有视频URL
|
|
|
+ if (empty($originalTask->result_url)) {
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => '原任务没有视频URL'
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取API Key
|
|
|
+ $apiKey = env('VOLC_AI_MEDIAKIT_KEY');
|
|
|
+ if (empty($apiKey)) {
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => '火山引擎 MediaKit API Key 未配置'
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建请求参数
|
|
|
+ $requestParams = [
|
|
|
+ 'video_url' => $originalTask->result_url,
|
|
|
+ 'resolution' => '720p',
|
|
|
+ 'bitrate_level' => 'medium'
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 调用超分API
|
|
|
+ $client = new Client(['verify' => false, 'timeout' => 120]);
|
|
|
+ $response = $client->post('https://mediakit.cn-beijing.volces.com/api/v1/tools/enhance-video-fast', [
|
|
|
+ 'headers' => [
|
|
|
+ 'Authorization' => 'Bearer ' . $apiKey,
|
|
|
+ 'Content-Type' => 'application/json',
|
|
|
+ ],
|
|
|
+ 'json' => $requestParams
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $responseData = json_decode($response->getBody(), true);
|
|
|
+
|
|
|
+ dLog('generate')->info('视频超分任务提交响应', [
|
|
|
+ 'original_task_id' => $taskId,
|
|
|
+ 'response' => $responseData
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 检查API响应
|
|
|
+ if (!isset($responseData['success']) || $responseData['success'] !== true) {
|
|
|
+ $errorMsg = '超分任务提交失败';
|
|
|
+ if (isset($responseData['error'])) {
|
|
|
+ $errorMsg .= ': ' . ($responseData['error']['message'] ?? json_encode($responseData['error']));
|
|
|
+ }
|
|
|
+
|
|
|
+ logDB('video_enhance', 'error', $errorMsg, [
|
|
|
+ 'original_task_id' => $taskId,
|
|
|
+ 'response' => $responseData
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => $errorMsg
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用事务创建新的超分任务记录并更新原任务
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ // 创建新的超分任务记录
|
|
|
+ $enhanceTask = MpGenerateVideoTask::create([
|
|
|
+ 'task_id' => $responseData['task_id'],
|
|
|
+ 'prompt' => $originalTask->prompt,
|
|
|
+ 'video_resolution' => '720P', // 目标分辨率
|
|
|
+ 'status' => MpGenerateVideoTask::STATUS_PROCESSING,
|
|
|
+ 'api_type' => 'video_enhance',
|
|
|
+ 'extra_params' => [
|
|
|
+ 'original_task_id' => $originalTask->id,
|
|
|
+ 'original_video_url' => $originalTask->result_url,
|
|
|
+ 'enhance_type' => '480p_to_720p',
|
|
|
+ 'request_id' => $responseData['request_id'] ?? '',
|
|
|
+ 'api_response' => $responseData
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 更新原任务的video_enhance_id字段
|
|
|
+ $originalTask->update([
|
|
|
+ 'video_enhance_id' => $enhanceTask->id
|
|
|
+ ]);
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+
|
|
|
+ logDB('video_enhance', 'info', '视频超分任务创建成功', [
|
|
|
+ 'original_task_id' => $taskId,
|
|
|
+ 'enhance_task_id' => $enhanceTask->id,
|
|
|
+ 'api_task_id' => $responseData['task_id']
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => true,
|
|
|
+ 'message' => '超分任务提交成功',
|
|
|
+ 'enhance_task_id' => $enhanceTask->id,
|
|
|
+ 'api_task_id' => $responseData['task_id']
|
|
|
+ ];
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ logDB('video_enhance', 'error', '创建超分任务失败', [
|
|
|
+ 'original_task_id' => $taskId,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => '创建超分任务失败: ' . $e->getMessage()
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (\GuzzleHttp\Exception\RequestException $e) {
|
|
|
+ $errorMsg = 'API请求失败';
|
|
|
+ if ($e->hasResponse()) {
|
|
|
+ $errorResponse = json_decode($e->getResponse()->getBody()->getContents(), true);
|
|
|
+ $errorMsg .= ': ' . ($errorResponse['msg'] ?? $errorResponse['message'] ?? $e->getMessage());
|
|
|
+ } else {
|
|
|
+ $errorMsg .= ': ' . $e->getMessage();
|
|
|
+ }
|
|
|
+
|
|
|
+ logDB('video_enhance', 'error', $errorMsg, ['task_id' => $taskId]);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => $errorMsg
|
|
|
+ ];
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ logDB('video_enhance', 'error', '超分任务提交异常', [
|
|
|
+ 'task_id' => $taskId,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => '系统错误: ' . $e->getMessage()
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询视频超分任务状态
|
|
|
+ *
|
|
|
+ * @param MpGenerateVideoTask $task
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public function queryVideoEnhanceTaskStatus(MpGenerateVideoTask $task): array
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ $apiKey = env('VOLC_AI_MEDIAKIT_KEY');
|
|
|
+ if (empty($apiKey)) {
|
|
|
+ return [
|
|
|
+ 'status' => 'failed',
|
|
|
+ 'error_message' => 'API Key 未配置'
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 调用查询任务信息API
|
|
|
+ $client = new Client(['verify' => false, 'timeout' => 120]);
|
|
|
+ $response = $client->get('https://mediakit.cn-beijing.volces.com/api/v1/tasks/' . $task->task_id, [
|
|
|
+ 'headers' => [
|
|
|
+ 'Authorization' => 'Bearer ' . $apiKey,
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $responseData = json_decode($response->getBody(), true);
|
|
|
+
|
|
|
+ dLog('generate')->info('视频超分任务状态查询', [
|
|
|
+ 'task_id' => $task->id,
|
|
|
+ 'api_task_id' => $task->task_id,
|
|
|
+ 'response' => $responseData
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 检查响应
|
|
|
+ if (!isset($responseData['success']) || $responseData['success'] !== true) {
|
|
|
+ return [
|
|
|
+ 'status' => 'failed',
|
|
|
+ 'error_message' => isset($responseData['error']) ?
|
|
|
+ ($responseData['error']['message'] ?? '查询失败') : '查询失败'
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $taskData = $responseData;
|
|
|
+ $taskStatus = $taskData['status'] ?? '';
|
|
|
+
|
|
|
+ $returnData = [
|
|
|
+ 'status' => 'processing',
|
|
|
+ 'error_message' => null,
|
|
|
+ 'result_url' => null,
|
|
|
+ 'result_json' => $responseData
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 解析任务状态
|
|
|
+ if ($taskStatus === 'completed' && isset($taskData['result']['video_url'])) {
|
|
|
+ // 任务成功,保存视频
|
|
|
+ $videoUrl = $taskData['result']['video_url'];
|
|
|
+
|
|
|
+ // 将视频保存到TOS
|
|
|
+ $videoName = 'enhanced_video_' . time() . '_' . uniqid() . '.mp4';
|
|
|
+ $savedUrl = uploadStreamByTos('video', file_get_contents($videoUrl), $videoName);
|
|
|
+
|
|
|
+ $returnData['status'] = 'success';
|
|
|
+ $returnData['result_url'] = $savedUrl;
|
|
|
+
|
|
|
+ // 视频时长
|
|
|
+ if (isset($taskData['result']['duration'])) {
|
|
|
+ $returnData['video_duration'] = (int)$taskData['result']['duration'];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 压缩视频(可选)
|
|
|
+ $compressedUrl = compressVideo($savedUrl);
|
|
|
+ $returnData['compressed_url'] = $compressedUrl ?: $savedUrl;
|
|
|
+
|
|
|
+ } elseif ($taskStatus === 'failed') {
|
|
|
+ $returnData['status'] = 'failed';
|
|
|
+ $returnData['error_message'] = '视频超分失败';
|
|
|
+ } elseif (in_array($taskStatus, ['pending', 'processing', 'queued'])) {
|
|
|
+ $returnData['status'] = 'processing';
|
|
|
+ }
|
|
|
+
|
|
|
+ return $returnData;
|
|
|
+
|
|
|
+ } catch (\GuzzleHttp\Exception\RequestException $e) {
|
|
|
+ $errorMsg = 'API查询失败';
|
|
|
+ if ($e->hasResponse()) {
|
|
|
+ $errorResponse = json_decode($e->getResponse()->getBody()->getContents(), true);
|
|
|
+ $errorMsg .= ': ' . ($errorResponse['msg'] ?? $errorResponse['message'] ?? $e->getMessage());
|
|
|
+ } else {
|
|
|
+ $errorMsg .= ': ' . $e->getMessage();
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'status' => 'processing',
|
|
|
+ 'error_message' => $errorMsg
|
|
|
+ ];
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ return [
|
|
|
+ 'status' => 'processing',
|
|
|
+ 'error_message' => $e->getMessage()
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新视频超分任务状态
|
|
|
+ *
|
|
|
+ * @param MpGenerateVideoTask $task
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ private function updateVideoEnhanceTask($task): void
|
|
|
+ {
|
|
|
+ $statusInfo = $this->queryVideoEnhanceTaskStatus($task);
|
|
|
+ if (!isset($statusInfo['status'])) return;
|
|
|
+
|
|
|
+ if ($statusInfo['status'] === 'success') {
|
|
|
+ logDB('video_enhance', 'info', '视频超分任务成功', [
|
|
|
+ 'id' => $task->id,
|
|
|
+ 'result_url' => $statusInfo['result_url']
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 获取原始480p任务
|
|
|
+ $extraParams = is_array($task->extra_params) ? $task->extra_params : json_decode($task->extra_params, true);
|
|
|
+ $originalTaskId = $extraParams['original_task_id'] ?? null;
|
|
|
+
|
|
|
+ if (!$originalTaskId) {
|
|
|
+ // 如果没有原始任务ID,只更新超分任务本身
|
|
|
+ $task->updateStatus(MpGenerateVideoTask::STATUS_SUCCESS, $statusInfo);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ $originalTask = MpGenerateVideoTask::find($originalTaskId);
|
|
|
+ if (!$originalTask) {
|
|
|
+ logDB('video_enhance', 'warning', '原始480p任务不存在', [
|
|
|
+ 'enhance_task_id' => $task->id,
|
|
|
+ 'original_task_id' => $originalTaskId
|
|
|
+ ]);
|
|
|
+ $task->updateStatus(MpGenerateVideoTask::STATUS_SUCCESS, $statusInfo);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用与updateUnifiedApiTask完全一致的逻辑
|
|
|
+ $segment_id = $this->getSegmentIdFromTask($originalTask);
|
|
|
+ if ($segment_id && isset($statusInfo['result_url'])) {
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ // 更新超分任务状态
|
|
|
+ $task->updateStatus(MpGenerateVideoTask::STATUS_SUCCESS, $statusInfo);
|
|
|
+
|
|
|
+ // 更新原始480p任务状态
|
|
|
+ $originalTask->updateStatus(MpGenerateVideoTask::STATUS_SUCCESS, $statusInfo);
|
|
|
+
|
|
|
+ $now = date('Y-m-d H:i:s');
|
|
|
+
|
|
|
+ // 构建更新数据(使用超分后的720p视频)
|
|
|
+ $segmentUpdateData = [
|
|
|
+ 'origin_video_url' => $statusInfo['result_url'],
|
|
|
+ 'video_task_status' => '已完成',
|
|
|
+ 'current_type' => 2,
|
|
|
+ 'last_frame_url' => $statusInfo['last_frame_url'] ?? '',
|
|
|
+ 'updated_at' => $now
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 使用查询任务时已压缩的视频URL,避免重复压缩
|
|
|
+ $segmentUpdateData['video_url'] = $statusInfo['compressed_url'] ?? $statusInfo['result_url'];
|
|
|
+
|
|
|
+ // 只有当video_duration存在且大于0时才更新
|
|
|
+ if (isset($statusInfo['video_duration']) && $statusInfo['video_duration'] > 0) {
|
|
|
+ $segmentUpdateData['video_duration'] = $statusInfo['video_duration'];
|
|
|
+ $segmentUpdateData['video_time_point_start'] = 0;
|
|
|
+
|
|
|
+ // 获取audio_duration(兼容全能模式)
|
|
|
+ $audio_duration = $this->getAudioDuration($originalTask, $segment_id, $statusInfo['video_duration'] ?? null);
|
|
|
+ $segmentUpdateData['video_time_point_end'] = $audio_duration ?? 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新分镜表(兼容act模式)
|
|
|
+ $this->updateSegmentTable($originalTask, $segmentUpdateData);
|
|
|
+
|
|
|
+ // 添加视频生成对话记录
|
|
|
+ $this->addVideoGenerationRecords($originalTask, $segment_id, $statusInfo['result_url']);
|
|
|
+
|
|
|
+ // 如果是全能模式的首帧图,则提取视频第一帧并更新anime表
|
|
|
+ $act_id = getProp($originalTask, 'alias_act_id');
|
|
|
+ if (!empty($act_id) && Redis::sismember('anime_act_first_frame_urls', $act_id)) {
|
|
|
+ $anime_id = DB::table('mp_episode_segments')->where('id', $act_id)->value('anime_id');
|
|
|
+ if ($anime_id) {
|
|
|
+ // 提取视频第一帧
|
|
|
+ $videoUrl = $segmentUpdateData['video_url'];
|
|
|
+ $firstFrameUrl = getVideoFirstFrame($videoUrl, 'anime_first_frames', 'tos');
|
|
|
+
|
|
|
+ if ($firstFrameUrl) {
|
|
|
+ // 更新anime表
|
|
|
+ DB::table('mp_animes')->where('id', $anime_id)->update([
|
|
|
+ 'first_frame_url' => $firstFrameUrl,
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s')
|
|
|
+ ]);
|
|
|
+
|
|
|
+ dLog('video_frame')->info('全能模式首帧图更新成功(超分任务)', [
|
|
|
+ 'act_id' => $act_id,
|
|
|
+ 'anime_id' => $anime_id,
|
|
|
+ 'first_frame_url' => $firstFrameUrl
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ // 从Redis中移除
|
|
|
+ Redis::srem('anime_act_first_frame_urls', $act_id);
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ dLog('video_enhance')->error('超分任务处理失败', [
|
|
|
+ 'segment_id' => $segment_id,
|
|
|
+ 'enhance_task_id' => $task->id,
|
|
|
+ 'original_task_id' => $originalTaskId,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 没有segment_id的情况下,只更新任务状态
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ $task->updateStatus(MpGenerateVideoTask::STATUS_SUCCESS, $statusInfo);
|
|
|
+ $originalTask->updateStatus(MpGenerateVideoTask::STATUS_SUCCESS, $statusInfo);
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ dLog('video_enhance')->error('超分任务状态更新失败', [
|
|
|
+ 'enhance_task_id' => $task->id,
|
|
|
+ 'original_task_id' => $originalTaskId,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } elseif ($statusInfo['status'] === 'failed') {
|
|
|
+ logDB('video_enhance', 'error', '视频超分任务失败', [
|
|
|
+ 'id' => $task->id,
|
|
|
+ 'error' => $statusInfo['error_message']
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $task->updateStatus(MpGenerateVideoTask::STATUS_FAILED, [
|
|
|
+ 'error_message' => $statusInfo['error_message'],
|
|
|
+ 'result_json' => $statusInfo['result_json'] ?? []
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 不更新原始任务状态,保留480p任务的成功状态
|
|
|
+ }
|
|
|
+
|
|
|
+ // 超时检查:48小时
|
|
|
+ $processingTime = now()->diffInHours($task->created_at);
|
|
|
+ if ($processingTime > 48 && $task->status === MpGenerateVideoTask::STATUS_PROCESSING) {
|
|
|
+ logDB('video_enhance', 'warning', '视频超分任务超时', [
|
|
|
+ 'id' => $task->id,
|
|
|
+ 'processing_hours' => $processingTime
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $task->updateStatus(MpGenerateVideoTask::STATUS_FAILED, [
|
|
|
+ 'error_message' => '任务处理超时(超过48小时)'
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|