惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
MyScale Blog
MyScale Blog
雷峰网
雷峰网
量子位
小众软件
小众软件
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
T
Tailwind CSS Blog
月光博客
月光博客
博客园 - 【当耐特】
博客园_首页
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
IT之家
IT之家
爱范儿
爱范儿
阮一峰的网络日志
阮一峰的网络日志
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
The Cloudflare Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
SegmentFault 最新的问题
人人都是产品经理
人人都是产品经理
V
V2EX
酷 壳 – CoolShell
酷 壳 – CoolShell

博客园 - lincats

3Blue1Brown:一个斯坦福毕业生的业余项目,如何成了全球最火的数学课堂 Caveman vs Ponytail:AI 编程圈"懒人哲学"两大门派正面交锋 /handoff,只有几行,却是Matt Pocock调用频率最高的 skill Matt Pocock 演讲逐帧拆解:好 Skill 和坏 Skill 的差距就在这 4 个维度 Remotion Skill vs HyperFrames Skill:AI视频圈两大技能包正面交锋,最好的对手,最好的搭档? grill-me 从入门到精通:Matt Pocock 技能宇宙中最出圈的那个"追问机器" Claude Code 最强Skills路由器:/ask-matt 完全上手指南(入门篇) 你的 AI 编程工具里,缺一个“专家团队“,一人公司必备的Agents合集 106 张镜头配方卡、161 段样片:这个 AI 技能让你的产品视频一秒拥有电影感 69万星、263万安装:一个「让 AI 别画得那么丑」的技能,怎么成了 Claude Code 设计类第一? SuperPower vs grill-me:AI编程圈两大skill正面交锋,你站哪边? Token 和上下文窗口——AI 记性的秘密 全球 AI 大佬都在用的“AI 使用说明书“:Andrej Karpathy 的 CLAUDE.md 究竟是什么? 上下文工程:AI 智能体为什么离不开它? 5个Claude Code Skill,把产品经理的反馈分析从45分钟压到了10分钟 Claude Code项目越写越乱?这套清理流程能救你 Claude Code再强,也有这7件事做不了 Skill用得好,下班走得早:一文讲透Skill的结构与设计 谷歌 75% 代码是 AI 写的,但 83% 的人记不住它写了什么AI 编程的效率神话背后,是一场集体认知的悄然退化 [COZE]文本分段提求词 [Coze]根据音频时间轴生成 [Coze] 剪映小助手整理时间线和素材的脚本 [扣子工作流一] 通过编程为米核剪映小助手添加关键帧 一步一步学习使用FireMonkey动画(6) 用实例理解动画的运行状态 一步一步学习使用FireMonkey动画(5) 动画图解11种动画插值类型 一步一步学习使用FireMonkey动画(4) 使用Delphi的基本动画组件类,路径和位图列表动画 弹跳小球和奔跑的小人示例 一步一步学习使用FireMonkey动画(3) 使用Delphi的基本动画组件类 一步一步学习使用FireMonkey动画(2) 使用TAnimator类创建动画 一步一步学习使用FireMonkey动画(1) 使用动画组件为窗体添加动态效果 一步一步学习使用LiveBindings(16)使用代码创建LiveBindings绑定
[Coze] 手工构建Coze时间线相关的代码
lincats · 2026-02-26 · via 博客园 - lincats

/**

  • 主处理函数:根据输入的参数,生成视频编辑所需的所有素材时间线和配置信息

  • 这个函数接收前端传递的视频制作参数,然后生成后端或视频渲染引擎

  • 能够理解的数据结构,包括:视频片段、背景音乐、配音、字幕等

  • @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;
    }

/**

  • 总结:这个函数的核心作用是将用户友好的视频制作参数,
  • 转换为视频渲染引擎需要的精确配置格式。
  • 主要功能包括:
    1. 自动处理时间单位的统一(秒/微秒的智能转换)
    1. 为每个视频片段添加3秒的标准时长和转场效果
    1. 配置背景音乐(延迟2秒开始,音量降低)
    1. 将字幕文字和时间线配对
    1. 添加标题字幕(0-2秒显示)
    1. 将所有配置序列化为JSON格式,便于传输
  • 时间单位说明:
    • 视频处理通常使用微秒(1秒 = 1,000,000微秒)来实现更精确的控制
    • 函数会智能判断前端传入的时间单位,统一转换为微秒
      */