多轨道字幕分组代码|生成字幕轨道与画面提示词

多轨道字幕分组代码

这是一段J扣子工作流代码节点 avaScript代码,接收分组文案时间轴、单双行组等参数,按类型分单句/双行/推荐/书名轨道,处理时间信息,生成各轨道数据及画面提示词数组。

📝 提示词原文

累计复制 0
// 定义异步主函数main,接收参数对象{params}(无显式类型,简化写法),返回Promise包裹的输出结果
async function main({ params }) {
    // 从参数中解构提取变量,设默认值避免报错:wenan_group_timeline(分组文案时间轴)、singleLineGroups(单行组)、keywordsList(关键词列表)、doubleLineGroups(双行组)
    const {
      wenan_group_timeline = [],
      singleLineGroups = [],
      keywordsList = [],
      doubleLineGroups = []
    } = params;
  
    // 创建时间映射对象:键=文案内容,值={start, end}时间信息(方便快速查时间)
    const timelineMap = {};
    for (const { content, start, end } of wenan_group_timeline) {
      timelineMap[content] = { start, end };  // 用文案内容当“钥匙”存时间
    }
  
    // 处理关键词列表:提取每个item的keywords字段,转成数组后用|拼接成字符串(如["A","B"]→"A|B")
    const keywordArr = keywordsList.map(item => item.keywords);
    const keywordStr = keywordArr.join('|');
  
    // === 轨道1:单句字幕(处理单行组文案)===
    const track_1_texts = [];       // 存单句文案内容
    const track_1_timelines = [];    // 存单句时间{start,end}
    const track_1_otherInfo = [];    // 存单句样式(对齐、颜色等)
  
    // 遍历单行组每个文案text
    for (const text of singleLineGroups) {
      const time = timelineMap[text];  // 从timelineMap查text的时间
      if (!time) continue;             // 没找到时间就跳过(不处理)
  
      track_1_texts.push(text);         // 加内容到轨道1文本
      track_1_timelines.push(time);     // 加时间到轨道1时间
      track_1_otherInfo.push({          // 加样式:居中对齐、绿色、无偏移
        alignment: 1, text_color: "#61862b", transform_x: 0, transform_y: 0
      });
    }
  
    // === 轨道2/3:普通双行字幕(处理双行组文案)===
    const track_2_texts = []; const track_2_timelines = []; const track_2_otherInfo = [];  // 轨道2(双行上句)
    const track_3_texts = []; const track_3_timelines = []; const track_3_otherInfo = [];  // 轨道3(双行下句)
    const track_4_texts = []; const track_4_timelines = []; const track_4_otherInfo = [];  // 轨道4(推荐文案)
    const track_5_texts = []; const track_5_timelines = []; const track_5_otherInfo = [];  // 轨道5(书名文案)
    const doubleLinePairs = [];  // 存普通双行字幕配对(用于生成画面提示词)
  
    // 遍历双行组(每个组含wenan数组,如["上句","下句"])
    for (const { wenan } of doubleLineGroups) {
      const [line1, line2] = wenan;  // 拆成上句line1、下句line2
      const time1 = timelineMap[line1];  // 查上句时间
      const time2 = timelineMap[line2];  // 查下句时间
      if (!time1 || !time2) continue;    // 任一时间缺失则跳过
  
      // 定义判断“书籍推荐文案”的关键词(推荐/孩子/读一读等短语)
      const recommendPhrases = ['推荐', '强烈推荐', '建议', '安利', '一定要试试', '必须看看', '良心推荐', '超适合', '很适合', '值得一读', '分享', '别错过', '可以入手'];
      const childrenPhrases = ['孩子', '宝贝', '小朋友', '宝宝', '小宝', '小孩', '娃', '娃娃', '儿童', '幼儿', '学龄前', '小男孩', '小女孩', '小弟弟', '小妹妹', '小公主', '小王子'];
      const actionPhrases = ['读一读', '看一看', '读读看', '看看', '共读', '阅读'];
      const unitPhrases = ['这套', '这一套', '这本', '这一册', '这册'];
  
      // 判断line1是否为书籍推荐文案(用正则组合关键词)
      function isBookRecommendation(line) {
        const pattern = new RegExp(  // 正则:推荐词+(陪/给)+孩子词+动作词+单位词(灵活匹配)
          `(?:${recommendPhrases.join('|')}).*?(?:陪|给)?.*?(?:${childrenPhrases.join('|')})?.*?(?:${actionPhrases.join('|')}).{0,5}(?:${unitPhrases.join('|')})`
        );
        return pattern.test(line);  // 匹配成功则返回true
      }
  
      if (isBookRecommendation(line1)) {
        // 若为推荐文案:line1→轨道4(推荐),line2→轨道5(书名)
        track_4_texts.push(line1); track_4_timelines.push(time1); track_4_otherInfo.push({ alignment:1, text_color:"#000000", transform_x:0, transform_y:100 });
        track_5_texts.push(line2); track_5_timelines.push(time2); track_5_otherInfo.push({ alignment:1, text_color:"#db7431", transform_x:0, transform_y:-100 });
      } else {
        // 普通双行:line1→轨道2(上句),line2→轨道3(下句)
        track_2_texts.push(line1); track_2_timelines.push({ start: time1.start, end: time1.end }); track_2_otherInfo.push({ alignment:1, text_color:"#61862b", transform_x:0, transform_y:140 });
        track_3_texts.push(line2); track_3_timelines.push({ start: time2.start, end: time2.end }); track_3_otherInfo.push({ alignment:1, text_color:"#db7431", transform_x:0, transform_y:-140 });
        doubleLinePairs.push({ line1: { text: line1, time: time1 }, line2: { text: line2, time: time2 } });  // 存配对用于画面提示词
      }
    }
    
    // === 生成画面提示词数据(visualPromptGroups)===
    const visualPromptGroups = [];
    // 加单句字幕提示词(轨道1内容)
    for (let i = 0; i < track_1_texts.length; i++) {
      visualPromptGroups.push({ start: track_1_timelines[i].start, end: track_1_timelines[i].end, content: track_1_texts[i] });
    }
    // 加双行字幕提示词(普通双行配对,用\n分隔上下句)
    for (const pair of doubleLinePairs) {
      visualPromptGroups.push({ start: pair.line1.time.start, end: pair.line2.time.end, content: `${pair.line1.text}\n${pair.line2.text}` });
    }
  
    // 返回所有轨道数据+画面提示词
    return {
      track_1: { texts: track_1_texts, timelines: track_1_timelines, otherInfo: track_1_otherInfo, keywords: track_1_texts.map(() => keywordStr), keyword_color: "#db7431" },
      track_2: { texts: track_2_texts, timelines: track_2_timelines, otherInfo: track_2_otherInfo },
      track_3: { texts: track_3_texts, timelines: track_3_timelines, otherInfo: track_3_otherInfo },
      track_4: { texts: track_4_texts, timelines: track_4_timelines, otherInfo: track_4_otherInfo },
      track_5: { texts: track_5_texts, timelines: track_5_timelines, otherInfo: track_5_otherInfo },
      visualPromptGroups  // 画面提示词数组(含start/end/content)
    };
}

扣子工作流代码节点常见问题

代码节点支持哪些编程语言?
目前扣子工作流代码节点主要支持 JavaScript(Node.js 环境)和 Python。您可以在节点设置中选择语言,推荐使用 JavaScript 以更好地与前端交互。
如何在代码节点中引入第三方库?
扣子代码节点内置了常用库(如 axios、lodash),无需额外安装。如果需要其他库,可使用动态导入(ES6)或通过在线依赖注入。具体可参考官方文档的“允许的依赖列表”。
代码节点如何获取上游节点的输出数据?
通过代码节点的输入参数对象 inputs 获取,例如 const data = inputs.user_query。确保上游节点的输出字段名与代码中引用的名称一致。
代码节点如何返回数据给下游节点?
使用 return 语句返回一个对象,对象的属性将成为输出字段。例如 return { result: "处理完成" };。下游节点可通过 {{节点名.result}} 引用。
代码节点执行超时或内存不足怎么办?
扣子代码节点默认超时时间较短(通常 5-10 秒),避免在代码中执行大量同步循环或大数据处理。建议将复杂任务拆分为多个节点,或使用异步流处理。如果必须处理大数据,考虑分批或调用外部API。
代码节点能访问环境变量或工作流全局变量吗?
可以通过 process.env 访问系统环境变量(仅限内置变量)。工作流全局变量(如工作流ID、用户ID)可通过 inputs 中的特定字段获取,具体需查看平台文档。
代码节点出错后如何定位问题?
利用 console.log() 打印关键变量,然后在工作流运行日志中查看输出。也可以使用 try-catch 捕获错误并返回自定义错误信息,便于调试。