coze

张开发
2026/4/11 22:29:09 15 分钟阅读

分享文章

coze
整合数据​ async function main({ params }: Args): PromiseOutput { const { image_list, audio_list, duration_list, scenes } params; // 处理音频数据 const audioData []; let audioStartTime 0; const aideoTimelines []; let maxDuration 0; const imageData []; for (let i 0; i audio_list.length i duration_list.length; i) { const duration duration_list[i]; audioData.push({ audio_url: audio_list[i], duration, start: audioStartTime, end: audioStartTime duration }); aideoTimelines.push({ start: audioStartTime, end: audioStartTime duration }); if((i-1)%20){ imageData.push({ image_url: image_list[i], start: audioStartTime, end: audioStartTime duration, width: 1440, height: 1080, in_animation: 轻微放大, in_animation_duration: 100000 }); } else{ imageData.push({ image_url: image_list[i], start: audioStartTime, end: audioStartTime duration, width: 1440, height: 1080 }); } audioStartTime duration; maxDuration audioStartTime; } const roleImgData []; roleImgData.push({ image_url: params.role_img_url, start: 0, end: duration_list[0], width: 1440, height: 1080 }); const captions scenes.map(item item.cap); const subtitleDurations duration_list; const { textTimelines, processedSubtitles } processSubtitles( captions, subtitleDurations ); // 开场2个字 const title params.title; // 标题 const title_list []; title_list.push(title); const title_timelimes [ { start: 0, end: duration_list[0] } ]; // 开场音效 4884897 var kc_audio_url https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/c04e7b48586a48f1863e421be4b10cf1.MP3~tplv-mdko3gqilj-image.image?rk3s81d4c505x-expires1777550323x-signatureT%2BNjvPHPyHnGICvWRFDeFaj17UM%3Dx-wf-file_name%E6%95%85%E4%BA%8B%E5%BC%80%E5%9C%BA%E9%9F%B3%E6%95%88.MP3; // 背景音乐 343666938 var bg_audio_url https://p3-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/5603dc783a6c4b75a4bf4e1b44086ad5.MP3~tplv-mdko3gqilj-image.image?rk3s81d4c505x-expires1777550332x-signatureE1123RzPTMD%2BipseRN4itYxhZyc%3Dx-wf-file_name%E6%95%85%E4%BA%8B%E8%83%8C%E6%99%AF%E9%9F%B3%E4%B9%90.MP3; const bg_audio_data []; bg_audio_data.push({ audio_url: bg_audio_url, duraion: maxDuration, start: 0, end: maxDuration }); const kc_audio_data []; kc_audio_data.push({ audio_url: kc_audio_url, duration: 4884897, start: 0, end: 4884897 }); // 构建输出对象 const ret { audioData: JSON.stringify(audioData), bgAudioData: JSON.stringify(bg_audio_data), kcAudioData: JSON.stringify(kc_audio_data), imageData: JSON.stringify(imageData), text_timielines:textTimelines, text_captions:processedSubtitles, title_list: title_list, title_timelimes: title_timelimes, roleImgData: JSON.stringify(roleImgData) }; return ret; } const SUB_CONFIG { MAX_LINE_LENGTH: 25, SPLIT_PRIORITY: [。,,,,,,,:,、,,;, ], // 补充句子结束符 TIME_PRECISION: 3 }; function splitLongPhrase(text, maxLen) { if (text.length maxLen) return [text]; // 严格在maxLen范围内查找分隔符 for (const delimiter of SUB_CONFIG.SPLIT_PRIORITY) { const pos text.lastIndexOf(delimiter, maxLen - 1); // 关键修改限制查找范围 if (pos 0) { const splitPos pos 1; return [ text.substring(0, splitPos).trim(), ...splitLongPhrase(text.substring(splitPos).trim(), maxLen) ]; } } // 汉字边界检查防止越界 const startPos Math.min(maxLen, text.length) - 1; for (let i startPos; i 0; i--) { if (/[\p{Unified_Ideograph}]/u.test(text[i])) { return [ text.substring(0, i 1).trim(), ...splitLongPhrase(text.substring(i 1).trim(), maxLen) ]; } } // 强制分割时保证不超过maxLen const splitPos Math.min(maxLen, text.length); return [ text.substring(0, splitPos).trim(), ...splitLongPhrase(text.substring(splitPos).trim(), maxLen) ]; } const processSubtitles ( captions, subtitleDurations, startTimeμs 0 // 新增参数起始时间单位微秒默认0 ) { const cleanRegex /[\u3000\u3002-\u303F\uff00-\uffef\u2000-\u206F!#$%()*\-./?\\^_{|}~]/g; let processedSubtitles []; let processedSubtitleDurations []; captions.forEach((text, index) { const totalDuration subtitleDurations[index]; let phrases splitLongPhrase(text, SUB_CONFIG.MAX_LINE_LENGTH); phrases phrases.map(p p.replace(cleanRegex, ).trim()) .filter(p p.length 0); if (phrases.length 0) { processedSubtitles.push([无内容]); processedSubtitleDurations.push(totalDuration); return; } const totalChars phrases.reduce((sum, p) sum p.length, 0); let accumulatedμs 0; phrases.forEach((phrase, i) { const ratio phrase.length / totalChars; let durationμs i phrases.length - 1 ? totalDuration - accumulatedμs : Math.round(totalDuration * ratio); processedSubtitles.push(phrase); processedSubtitleDurations.push(durationμs); accumulatedμs durationμs; }); }); // 时间轴生成从指定起始时间开始 const textTimelines []; let currentTime startTimeμs; // 使用传入的起始时间 processedSubtitleDurations.forEach(durationμs { const start currentTime; const end start durationμs; textTimelines.push({ start: start, // 直接使用整数 end: end }); currentTime end; // 自动累计到下一段 }); return { textTimelines, processedSubtitles }; }; ​关键帧import json async def main(args: Args) - Output: params args.params segment_ids params[segment_ids] times params[duration_list] seg params[segment_infos] # 验证参数长度一致性 if len(segment_ids) ! len(times): raise ValueError(segment_ids与times数组长度不一致) keyframes [] for idx, seg_id in enumerate(segment_ids): if idx 0: # 跳过第一张图片 continue # 获取对应音频时长并转换微秒 audio_duration int(float(times[idx])) # 根据循环索引决定缩放方向 cycle_idx idx - 1 # 计算排除第一个元素后的循环索引 if cycle_idx % 2 0: # 偶数索引1.0 - 1.5 start_scale 1.0 end_scale 1.5 else: # 奇数索引1.5 - 1.0 start_scale 1.5 end_scale 1.0 # 起始关键帧0秒位置 keyframes.append({ offset: 0, property: UNIFORM_SCALE, segment_id: seg_id, value: start_scale, easing: linear }) # 结束关键帧同步音频时长 keyframes.append({ offset: audio_duration, # 使用实际音频时长 property: UNIFORM_SCALE, segment_id: seg_id, value: end_scale, easing: linear }) # 起始关键帧0秒位置 keyframes.append({ offset: 0, property: UNIFORM_SCALE, segment_id: seg[0][id], value: 2, easing: linear }) keyframes.append({ offset: 533333, property: UNIFORM_SCALE, segment_id: seg[0][id], value: 1.2, easing: linear }) # 结束关键帧同步音频时长 keyframes.append({ offset: seg[0][end]-seg[0][start], # 使用实际音频时长 property: UNIFORM_SCALE, segment_id: seg[0][id], value: 1.0, easing: linear }) return { keyFrames: json.dumps(keyframes) }

更多文章