批量剪辑执行脚本优化

This commit is contained in:
qikongjian 2025-09-29 15:09:14 +08:00
parent 346cf5233e
commit 8cc118b460
2 changed files with 78 additions and 47 deletions

View File

@ -232,9 +232,9 @@ class BatchVideoExporter {
}
/** 调用导出流接口 */
async callExportStream(exportRequest) {
async callExportStream(exportRequest, attemptNumber = 1) {
const projectId = exportRequest.project_id;
this.log(`项目 ${projectId}: 开始调用导出流接口...`);
this.log(`项目 ${projectId}: 开始调用导出流接口(第${attemptNumber}次尝试)...`);
// 使用fetch APINode.js 18+支持)
let fetch;
@ -361,9 +361,11 @@ class BatchVideoExporter {
export_id: progress && progress.export_id
};
} else if (status === 'failed') {
throw new Error(`导出任务失败: ${(progress && progress.message) || '未知错误'}`);
const errorMessage = `导出任务失败: ${(progress && progress.message) || '未知错误'}`;
throw new Error(errorMessage);
} else if (status === 'error') {
throw new Error(`导出任务错误: ${(progress && progress.message) || '未知错误'}`);
const errorMessage = `导出任务错误: ${(progress && progress.message) || '未知错误'}`;
throw new Error(errorMessage);
} else {
const percentage = (progress && progress.percentage) || 0;
const message = (progress && progress.message) || '处理中...';
@ -374,6 +376,14 @@ class BatchVideoExporter {
await new Promise(resolve => setTimeout(resolve, 5000)); // 5秒间隔
} catch (error) {
this.log(`项目 ${projectId}: 轮询进度出错: ${error.message}`, 'error');
// 对于明确的失败/错误状态,立即抛出,让上层进行重新导出重试
if (
typeof error?.message === 'string' &&
(error.message.includes('导出任务失败') || error.message.includes('导出任务错误'))
) {
throw error;
}
// 其他网络类错误,继续有限次数的轮询重试
attempts++;
if (attempts >= maxAttempts) {
throw error;
@ -385,6 +395,67 @@ class BatchVideoExporter {
throw new Error(`轮询超时,已尝试${maxAttempts}`);
}
/** 导出任务处理(包含重试逻辑) */
async processExportWithRetry(exportRequest) {
const projectId = exportRequest.project_id;
const maxExportRetries = 3; // 导出重试3次
for (let attempt = 1; attempt <= maxExportRetries; attempt++) {
try {
this.log(`项目 ${projectId}: 开始第${attempt}次导出尝试...`);
// 1. 调用导出流接口
let exportResult = await this.callExportStream(exportRequest, attempt);
// 2. 如果SSE没有返回完整结果使用轮询
let taskId = null;
if (!exportResult || !exportResult.video_url) {
taskId = (exportResult && exportResult.export_id) || (exportResult && exportResult.task_id);
if (!taskId) {
throw new Error('无法获取任务ID无法轮询进度');
}
try {
exportResult = await this.pollExportProgress(taskId, projectId);
} catch (pollError) {
// 如果轮询过程中发现任务失败,并且还有重试机会,则重新导出
if (pollError.message.includes('导出任务失败') || pollError.message.includes('导出任务错误')) {
this.log(`项目 ${projectId}: 第${attempt}次导出失败 - ${pollError.message}`, 'warn');
if (attempt < maxExportRetries) {
this.log(`项目 ${projectId}: 准备重新导出(剩余${maxExportRetries - attempt}次重试机会)...`);
await new Promise(resolve => setTimeout(resolve, 3000)); // 等待3秒后重试
continue;
} else {
throw new Error(`导出失败,已重试${maxExportRetries}次: ${pollError.message}`);
}
} else {
// 其他错误(如网络错误、超时等)直接抛出
throw pollError;
}
}
}
// 3. 导出成功,返回结果
this.log(`项目 ${projectId}: 第${attempt}次导出尝试成功!`);
return exportResult;
} catch (error) {
// 如果是导出接口调用失败(如网络错误、服务器错误等)
this.log(`项目 ${projectId}: 第${attempt}次导出尝试失败 - ${error.message}`, 'warn');
if (attempt < maxExportRetries) {
this.log(`项目 ${projectId}: 准备重新导出(剩余${maxExportRetries - attempt}次重试机会)...`);
await new Promise(resolve => setTimeout(resolve, 3000)); // 等待3秒后重试
} else {
throw new Error(`导出失败,已重试${maxExportRetries}次: ${error.message}`);
}
}
}
throw new Error(`导出失败,已达到最大重试次数${maxExportRetries}`);
}
/** 处理单个项目 */
async processProject(projectId) {
const status = {
@ -411,23 +482,13 @@ class BatchVideoExporter {
// 2. 构建导出请求
const exportRequest = this.buildExportRequest(projectId, editingPlan);
// 3. 调用导出接口
// 3. 调用导出接口(包含重试逻辑)
status.status = 'exporting';
status.exportStarted = true;
let exportResult = await this.callExportStream(exportRequest);
const exportResult = await this.processExportWithRetry(exportRequest);
// 4. 如果SSE没有返回完整结果使用轮询
if (!exportResult || !exportResult.video_url) {
const taskId = (exportResult && exportResult.export_id) || (exportResult && exportResult.task_id);
if (taskId) {
exportResult = await this.pollExportProgress(taskId, projectId);
} else {
throw new Error('无法获取任务ID无法轮询进度');
}
}
// 5. 处理完成
// 4. 处理完成
status.status = 'completed';
status.exportCompleted = true;
status.videoUrl = exportResult.video_url;

View File

@ -1,36 +1,6 @@
# 项目ID列表示例文件
# 每行一个项目ID以#开头的行为注释
107c5fcc-8348-4c3b-b9f3-f7474e24295d
6243a491-d8cd-46cf-8d11-933300f27569
2b296c0f-dcc3-4141-8977-b9f3579bdb04
2238ca87-1c6a-484a-9405-9e25d0999072
481e672d-3a00-454f-bee0-71797d40ea17
de805e6c-2374-4a5d-9f8a-f0b6baa3fad5
64f137e0-06e5-4d30-86e7-28c6b8644de1
8a132503-456a-462f-83e3-367636cd0286
8d81241b-ae7c-431a-b953-85cfd6af77f3
98b53d49-a02d-4fed-aa4e-62b6cc45fae8
f23d558c-6f18-43f3-a373-8e3d1e8d278a
12daaba2-79c0-4fe8-bdc8-5b746b6bee3b
6b7ca8b9-5760-4908-aac6-b7388402652d
19db2b3e-9fb7-408c-90d5-35f9969b3d01
89c20909-4ebf-4ccc-a5e7-401ef91ef242
4de9ef61-cefd-4027-b07e-a2520a62f218
d2e23eaf-e806-44c9-a241-7fc1af53dab4
64941470-7689-4ea1-872c-672f2b5e4628
469c5792-aa1a-4489-bfea-779d3782218c
7c55bd8e-8f16-4caa-a001-1a34497a9711
86dcc7cf-f116-429f-b298-fe0878aa25ef
ded3ed74-b6fa-48fd-ad7e-fbfa717d54f5
96da7e21-7284-4056-900e-59835e99b651
892083d2-a7e7-4436-aac9-91cfdf24feae
52543696-fbe0-4fd9-bbe2-ef31e642fb8e
675ae612-d6ac-4017-98a6-ac9c4fd4eac9
e430dfe1-3cb8-40bd-a6a9-f6b223052ff7
3b12c5d3-7899-4ef6-97c4-8ff07ee5bc8e
35abfaba-d5b8-4caf-bbb7-89feaa007415
71d52c66-b83b-4d51-91a2-be26f88f9eba
8013eeb8-6938-43e1-b5e1-91f68d860eb8
30c8582f-5231-4a31-af08-5bba4b6171f3
0cece1ba-ea3b-43cb-a7f2-10ce0de96936