












/**
主处理函数:根据输入的参数,生成视频编辑所需的所有素材时间线和配置信息
这个函数接收前端传递的视频制作参数,然后生成后端或视频渲染引擎
能够理解的数据结构,包括:视频片段、背景音乐、配音、字幕等
@param params - 包含所有视频制作参数的对象,结构为
@returns 返回一个包含所有视频配置的Promise对象,这些配置将被用于最终生成视频
*/
async function main({ params }: { params: Record<string, any> }): Promise<Record<string, any>> {
// ==================== 第一步:从输入参数中提取所有需要的数据 ====================
// 使用 ?? 操作符来设置默认值,这样即使前端没有传递某个参数,程序也不会报错
const bgm = params.bgm ?? ''; // 背景音乐文件的URL地址,默认为空字符串
const texts = params.texts ?? []; // 字幕文本数组,每个元素是一句字幕的文字内容,默认为空数组
const video_urls = params.video_urls ?? []; // 视频素材URL数组,每个元素是一个视频片段的地址,默认为空数组
const audioUrl = params.audioUrl ?? ''; // 配音音频文件的URL地址,默认为空字符串
const durationInput = Number(params.duration) || 0; // 原始输入的配音时长,可能以秒或微秒为单位,默认为0
const timelines = params.timelines ?? []; // 字幕时间线数组,定义了每句字幕出现的时间段,默认为空数组
const title = params.title ?? ''; // 视频标题文字,将作为开头字幕显示,默认为空字符串
// ==================== 第二步:初始化变量,准备构建视频配置 ====================
let common_timelines = []; // 公共时间线(暂时未明确用途,可能是预留的全局配置)
let video_start = 0; // 当前视频片段的开始时间(微秒),初始为0
let video_end = 0; // 当前视频片段的结束时间(微秒),会随着遍历不断更新
let videos = []; // 存储所有视频片段配置的数组
// ==================== 第三步:处理视频素材 ====================
// 遍历每一个视频URL,为每个视频片段生成详细的时间线配置
video_urls.forEach((item) => {
// 每个视频片段固定播放3秒(转换为微秒:3 * 1,000,000 = 3,000,000微秒)
video_end = video_start + 3 * 1000000;
// 为当前视频片段创建配置对象
videos.push({
"video_url": item, // 视频文件的URL地址
"duration": 3 * 1000000, // 视频片段的持续时间(3秒,单位微秒)
"start": video_start, // 在最终视频中的开始时间点
"end": video_end, // 在最终视频中的结束时间点
"width": 576, // 视频宽度(像素)
"height": 1024, // 视频高度(像素)
"transition": "叠化", // 转场效果类型:叠化(淡入淡出)
"transition_duration": 1000000 // 转场效果的持续时间(1秒,单位微秒)
});
// 更新开始时间,为下一个视频片段做准备
// 注意:因为有转场效果,下一个视频的开始时间应该等于当前视频的结束时间
if (video_end > video_start) {
video_start = video_end;
}
});
// 循环结束后,video_end 等于所有视频片段的总时长(视频个数 × 3秒)
// ==================== 第四步:配置背景音乐 ====================
// 背景音乐将从2秒后开始播放,持续到视频结束
const audioBgm = [{
"audio_url": bgm, // 背景音乐文件的URL
"start": 2000000, // 开始时间:2秒(单位微秒)- 给片头标题留出空间
"end": video_end, // 结束时间:与最后一个视频结束时间同步
"volume": 0.2 // 音量:0.2(范围0-1,0.2表示20%音量,较小背景音)
}];
// ==================== 第五步:配置公共时间线 ====================
// 这可能是为视频编辑器准备的一个通用时间区间,表示从2秒到视频结束
common_timelines.push({
"start": 2000000, // 开始时间:2秒
"end": video_end // 结束时间:视频结束
});
// ==================== 第六步:初始化字幕和配音数组 ====================
let captions = []; // 存储主要字幕(视频中的对白或解说)
let audios = []; // 存储配音音频配置
// ==================== 第七步:处理配音时长单位 ====================
// 这是一个智能兼容逻辑:前端可能传秒也可能传微秒,自动判断并转换
// 规则:
// 1. 如果数值大于0但小于1,000,000 → 认为单位是"秒",需要乘以1,000,000转换为微秒
// 2. 如果数值大于等于1,000,000 → 认为已经是微秒,直接使用
// 3. 如果数值为0 → 保持不变(没有配音)
const durationUs = durationInput < 1000000 && durationInput > 0
? durationInput * 1000000 // 秒转微秒
: durationInput; // 已经是微秒或为0
// ==================== 第八步:配置配音音频 ====================
audios.push({
"audio_url": audioUrl, // 配音文件的URL
"duration": durationUs, // 配音时长(已统一为微秒)
"start": 0, // 从视频一开始就播放
"end": durationUs // 结束时间等于配音时长
});
// ==================== 第九步:配置主要字幕(对白/解说) ====================
// 遍历每条时间线,为每条时间线匹配对应的字幕文字
timelines.forEach((item, idx) => {
// 提取当前时间线的开始和结束时间,如果没有则默认为0
const start = item.start ?? 0;
const end = item.end ?? 0;
// 获取对应的文字内容,按顺序匹配
// 如果texts数组长度小于timelines,超出的部分显示为空字符串
const text = texts[idx] ?? "";
// 创建字幕配置
captions.push({
'text': text, // 字幕文字内容
'start': start, // 出现时间
'end': end, // 消失时间
"in_animation": "渐显", // 入场动画效果
"out_animation": "渐隐" // 出场动画效果
});
});
// ==================== 第十步:配置标题字幕 ====================
// 标题字幕单独处理,显示在视频开头0-2秒
const captionsTitle = [{
'text': title, // 标题文字
'start': 0, // 从0秒开始
'end': 2000000, // 到2秒结束
"in_animation": "", // 无入场动画(直接显示)
"out_animation": "渐隐" // 出场时渐隐
}];
// ==================== 第十一步:组装最终输出对象 ====================
// 将所有配置转换成JSON字符串格式,方便传输和后续处理
// 这样视频渲染引擎可以直接解析使用
const ret = {
"captions": JSON.stringify(captions), // 主要字幕(JSON字符串)
"audios": JSON.stringify(audios), // 配音(JSON字符串)
"videos": JSON.stringify(videos), // 视频素材(JSON字符串)
"audioBgm": JSON.stringify(audioBgm), // 背景音乐(JSON字符串)
"captionsTitle": JSON.stringify(captionsTitle), // 标题字幕(JSON字符串)
"common_timelines": common_timelines // 公共时间线(普通对象)
};
// ==================== 第十二步:返回最终结果 ====================
return ret;
}
/**
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。