剪辑计划加入重试机制最长重试时间为10分钟

This commit is contained in:
qikongjian 2025-09-17 14:51:34 +08:00
parent 8836138283
commit 62404f4063

View File

@ -151,25 +151,83 @@ export class VideoExportService {
} }
} }
/**
*
* 810
*/
private async getEditingPlanWithRetry(episodeId: string, progressCallback?: ExportProgressCallback['onProgress']): Promise<any> {
const maxRetryTime = 10 * 60 * 1000; // 10分钟
const retryInterval = 8 * 1000; // 8秒
const maxAttempts = Math.floor(maxRetryTime / retryInterval); // 75次
console.log('🎬 开始获取剪辑计划(带重试机制)...');
console.log(`⏰ 重试配置: ${retryInterval/1000}秒间隔,最多${maxAttempts}次,总时长${maxRetryTime/1000/60}分钟`);
let attempts = 0;
while (attempts < maxAttempts) {
attempts++;
try {
console.log(`🔄 第${attempts}次尝试获取剪辑计划...`);
// 触发进度回调
if (progressCallback) {
// 剪辑计划获取占总进度的80%,因为可能需要很长时间
const progressPercent = Math.min(Math.round((attempts / maxAttempts) * 80), 75);
progressCallback({
status: 'processing',
percentage: progressPercent,
message: `正在获取剪辑计划... (第${attempts}次尝试,预计${Math.ceil((maxAttempts - attempts) * retryInterval / 1000 / 60)}分钟)`,
stage: 'fetching_editing_plan'
});
}
const editPlanResponse = await getGenerateEditPlan({ project_id: episodeId });
if (editPlanResponse.successful && editPlanResponse.data.editing_plan) {
console.log(`✅ 第${attempts}次尝试成功获取剪辑计划`);
return editPlanResponse.data.editing_plan;
} else {
console.log(`⚠️ 第${attempts}次尝试失败: ${editPlanResponse.message || '剪辑计划未生成'}`);
if (attempts >= maxAttempts) {
throw new Error(`获取剪辑计划失败,已重试${maxAttempts}次: ${editPlanResponse.message}`);
}
console.log(`${retryInterval/1000}秒后进行第${attempts + 1}次重试...`);
await new Promise(resolve => setTimeout(resolve, retryInterval));
}
} catch (error) {
console.log(`❌ 第${attempts}次尝试出现错误:`, error);
if (attempts >= maxAttempts) {
throw new Error(`获取剪辑计划失败,已重试${maxAttempts}次: ${error instanceof Error ? error.message : '未知错误'}`);
}
console.log(`${retryInterval/1000}秒后进行第${attempts + 1}次重试...`);
await new Promise(resolve => setTimeout(resolve, retryInterval));
}
}
throw new Error(`获取剪辑计划超时,已重试${maxAttempts}`);
}
/** /**
* *
*/ */
private async generateExportDataFromEditingPlan(episodeId: string, taskObject: any): Promise<{ private async generateExportDataFromEditingPlan(
episodeId: string,
taskObject: any,
progressCallback?: ExportProgressCallback['onProgress']
): Promise<{
exportRequest: ExportRequest; exportRequest: ExportRequest;
editingPlan: any; editingPlan: any;
}> { }> {
console.log('🎬 开始获取剪辑计划...');
try { try {
// 1. 首先获取剪辑计划 // 1. 首先获取剪辑计划(带重试机制)
const editPlanResponse = await getGenerateEditPlan({ project_id: episodeId }); const editingPlan = await this.getEditingPlanWithRetry(episodeId, progressCallback);
console.log('📋 最终获取到剪辑计划:', editingPlan);
if (!editPlanResponse.successful || !editPlanResponse.data.editing_plan) {
throw new Error('获取剪辑计划失败: ' + editPlanResponse.message);
}
const editingPlan = editPlanResponse.data.editing_plan;
console.log('📋 获取到剪辑计划:', editingPlan);
// 2. 检查是否有可用的视频数据 // 2. 检查是否有可用的视频数据
if (!taskObject.videos?.data || taskObject.videos.data.length === 0) { if (!taskObject.videos?.data || taskObject.videos.data.length === 0) {
@ -570,22 +628,28 @@ export class VideoExportService {
// 重试循环 // 重试循环
while (currentAttempt <= this.config.maxRetries) { while (currentAttempt <= this.config.maxRetries) {
try { try {
// 第一步:获取剪辑计划(只在第一次尝试时获取 // 第一步:获取剪辑计划(只在第一次尝试时获取,或缓存不存在时重新获取
let exportRequest: ExportRequest; let exportRequest: ExportRequest;
if (currentAttempt === 1) { if (currentAttempt === 1 || !this.cachedExportRequest) {
console.log('🎬 步骤1: 获取剪辑计划...'); console.log('🎬 步骤1: 获取剪辑计划...');
const { exportRequest: generatedExportRequest, editingPlan: generatedEditingPlan } = await this.generateExportDataFromEditingPlan(episodeId, taskObject); try {
exportRequest = generatedExportRequest; const { exportRequest: generatedExportRequest, editingPlan: generatedEditingPlan } = await this.generateExportDataFromEditingPlan(episodeId, taskObject, progressCallback);
exportRequest = generatedExportRequest;
console.log('📤 生成的导出请求数据:', exportRequest); console.log('📤 生成的导出请求数据:', exportRequest);
console.log(`📊 包含 ${exportRequest.ir.video.length} 个视频片段,总时长: ${exportRequest.ir.duration}ms`); console.log(`📊 包含 ${exportRequest.ir.video.length} 个视频片段,总时长: ${exportRequest.ir.duration}ms`);
console.log('🎬 使用的剪辑计划:', generatedEditingPlan); console.log('🎬 使用的剪辑计划:', generatedEditingPlan);
// 缓存exportRequest以便重试时使用 // 缓存exportRequest以便重试时使用
this.cachedExportRequest = exportRequest; this.cachedExportRequest = exportRequest;
} catch (editPlanError) {
console.error('❌ 获取剪辑计划失败,无法继续导出:', editPlanError);
// 剪辑计划获取失败是致命错误,直接抛出,不进行导出重试
throw editPlanError;
}
} else { } else {
// 重试时使用缓存的请求数据 // 重试时使用缓存的请求数据
exportRequest = this.cachedExportRequest!; exportRequest = this.cachedExportRequest;
console.log(`🔄 第${currentAttempt}次重试,使用缓存的导出请求数据`); console.log(`🔄 第${currentAttempt}次重试,使用缓存的导出请求数据`);
} }