100个爆火Coze工作流系列(一):假如书籍会说话(下篇),视频剪辑合成

581 阅读6分钟

这期教大家工作流第二部分,视频剪辑合成的制作

重点学习

核心知识点:视频合成

涉及节点:代码

涉及插件:剪映小助手

下面来手把手教大家如何制作~

先来看一下视频合成的工作流整体流程

在这里插入图片描述

视频剪辑合成

1、数据整合

首先我们需要把前面生成的所以素材的数据整合成剪映小助手插件需要的数据格式,这一步非常重要,这一步出错了,后面用合成视频是不可能成功的。

数据整合我们用代码节点来完成。

添加一个代码节点,然后把前面生成素材节点的线都连接到代码节点上

在这里插入图片描述

然后点开代码节点,把前面生成的素材全部传进来

在这里插入图片描述

我们一个个来看

text_list1、text_list2、text_list3:对话文案列表

在这里插入图片描述

audio_list1、audio_list2、audio_list3:对话音频列表

在这里插入图片描述

duration_list1、duration_list2、duration_list3:对话音频的音频时长列表

在这里插入图片描述

start_texts:开场白文案

在这里插入图片描述

start_audio_list:开场白音频

在这里插入图片描述

start_duration_list:开场白音频时长

在这里插入图片描述

bg_image:背景图

在这里插入图片描述

keywords:文案关键词

在这里插入图片描述

代码我也准备好了,直接复制过来,节点的输出参数和代码的输出对象一一对应

在这里插入图片描述 在这里插入图片描述

我们试运行一下看看输出结果

在这里插入图片描述

代码:

async function main({ params }: Args): Promise<Output> {

    let {
        start_texts,
        start_audio_list,
        start_duration_list,
        audio_list1,
        audio_list2,
        audio_list3,
        duration_list1,
        duration_list2,
        duration_list3,
        text_list1,
        text_list2,
        text_list3,
        bg_image,
        keywords
    } = params
    let start = 0
    let end = 0

    // 开场镜头
    let start_text_infos_1 = []
    let start_text_infos_2 = []
    let start_text_infos_3 = []
    let start_audio_infos = []
    let start_audio_effect_1 = []
    let start_audio_effect_2 = []
    // 主体内容
    let text_infos_1 = []
    let text_infos_2 = []
    let audio_infos = []
    let host_images = []
    let book_images = []
    let bg_image_infos = []

    // 开场镜头数据组装
    start_audio_list.forEach((ele, i) => {
        let audio_url = ele.output
        let duration = start_duration_list[i].output
        let text = start_texts[i]
        end = start + duration * 1000000

        // 音频
        start_audio_infos.push({
            audio_url,
            start,
            end,
            volume: 4
        })

        // 音效
        if (i === 0) {
            start_audio_effect_1.push({
                audio_url: "https://p6-bot-sign.byteimg.com/tos-cn-i-v4nquku3lp/0562121f72f943f2802c7e8dc49e0e7b.MP3~tplv-v4nquku3lp-image.image?rk3s=68e6b6b5&x-expires=1749305401&x-signature=ZiBfMBfiHBWUnk6iqQPFe%2FFdfDM%3D",
                volume: 2,
                start,
                end: 548571
            })
        } else if (i === 1) {
            start_audio_effect_2.push({
                audio_url: "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/2ae7ccd877ea4c79b4fcbcfe38170b54.MP3~tplv-mdko3gqilj-image.image?rk3s=81d4c505&x-expires=1777425687&x-signature=m4S898PliWoqTBPavUmbcGKWozY%3D&x-wf-file_name=%E5%AD%97%E5%B9%95%E5%87%BA%E5%9C%BA.MP3",
                volume: 2,
                start,
                end: start + 862040
            })
        }

        // 字幕
        if (i === 0) {
            start_text_infos_1.push({
                text,
                start,
                end,
                in_animation: '逐字旋入',
                in_animation_duration: 500000
            })
        } else if (i === 1) {
            start_text_infos_2.push({
                text,
                start,
                end,
                in_animation: '放大',
                in_animation_duration: 500000
            })
        } else if (i === 2) {
            start_text_infos_3.push({
                text,
                start,
                end,
                in_animation: '向上滑动',
                in_animation_duration: 500000
            })
        }

        start = end
    })

    // 主体内容数据组装
    let audio_list = [...audio_list1, ...audio_list2, ...audio_list3]
    let duration_list = [...duration_list1, ...duration_list2, ...duration_list3]
    let text_list = [...text_list1, ...text_list2, ...text_list3]

    let current_role_name = ''
    audio_list.forEach((ele, i) => {
        let audio_url = ele
        let duration = duration_list[i] * 1000000
        let text = text_list[i].line
        // 超过10个字换行
        text = text.replace(/(.{10})/g, '$1\n').replace(/\n$/g, '')
        let role_name = text_list[i].role_name
        end = start + duration

        // 音频
        audio_infos.push({
            audio_url,
            start,
            end,
            volume: 4
        })

        // 字幕
        let keywordArr = keywords.filter(key => text.includes(key))
        let text_info = {
            text,
            start,
            end,
            in_animation: '羽化向右擦开',
            in_animation_duration: 500000,
            keyword: keywordArr.join('|'),
            keyword_color: '#fe8a80',
            keyword_font_size: 10,
            font_size: 10
        }
        if (role_name === '主持人') {
            text_infos_1.push(text_info)
        } else {
            text_infos_2.push(text_info)
        }

        // 图片
        let host_image_info = {
            image_url: 'https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/7153ce955e1b4d51ab2e3972846fb13e.png~tplv-mdko3gqilj-image.image?rk3s=81d4c505&x-expires=1777338929&x-signature=LLDTeL38s5rfHt7%2BG1%2FvGFrwa%2FQ%3D&x-wf-file_name=CodeL.png',
            width: 300,
            height: 300,
            in_animation: '轻微放大',
            in_animation_duration: 500000
        }
        let book_image_info = {
            image_url: 'https://s.coze.cn/t/MRdXPFzGLOw/',
            width: 300,
            height: 300,
            in_animation: '轻微放大',
            in_animation_duration: 500000
        }
        if (current_role_name !== role_name) {
            if (role_name === '主持人') {
                host_image_info.start = start
                host_images.push(host_image_info)
                if (book_images.length > 0) {
                    book_images[book_images.length - 1].end = start
                }
            } else {
                book_image_info.start = start
                book_images.push(book_image_info)
                if (host_images.length > 0) {
                    host_images[host_images.length - 1].end = start
                }
            }
            current_role_name = role_name
        }

        if (i === audio_list.length - 1) {
            if (role_name === '主持人') {
                host_images[host_images.length - 1].end = end
            } else {
                book_images[book_images.length - 1].end = end
            }
        }

        start = end
    })

    // 背景
    bg_image_infos.push({
        image_url: bg_image,
        width: 1920,
        height: 1080,
        start: 0,
        end,
    })

    // 构建输出对象
    const ret = {
        start_text_infos_1: JSON.stringify(start_text_infos_1),
        start_text_infos_2: JSON.stringify(start_text_infos_2),
        start_text_infos_3: JSON.stringify(start_text_infos_3),
        start_audio_infos: JSON.stringify(start_audio_infos),
        start_audio_effect_1: JSON.stringify(start_audio_effect_1),
        start_audio_effect_2: JSON.stringify(start_audio_effect_2),
        text_infos_1: JSON.stringify(text_infos_1),
        text_infos_2: JSON.stringify(text_infos_2),
        audio_infos: JSON.stringify(audio_infos),
        host_images: JSON.stringify(host_images),
        book_images: JSON.stringify(book_images),
        bg_image_infos: JSON.stringify(bg_image_infos),
    };

    return ret;
}

2、视频剪辑

我们先创建草稿,设置宽高

在这里插入图片描述 在这里插入图片描述

然后添加背景

在这里插入图片描述

添加开场音频

在这里插入图片描述

添加开场字幕 1、添加开场字幕 2、添加开场字幕 3

在这里插入图片描述 在这里插入图片描述

添加开场音效 1、开场音效 2

在这里插入图片描述

添加对话音频

在这里插入图片描述

添加主持人字幕、添加书籍字幕

在这里插入图片描述

添加主持人图片

在这里插入图片描述

生成主持人图片关键帧-x 轴位移

在这里插入图片描述

offsets: 0|10|13|20|26|30|40|41|50|51|60|64|70|80|90
values: -1024|-824|-881|-1024|-910|-824|-995|-1024|-824|-853|-1024|-938|-824|-967|-1024

添加主持人图片关键帧-x 轴位移

在这里插入图片描述

生成主持人图片关键帧-y 轴位移

在这里插入图片描述

offsets: 0|10|13|20|26|30|40|41|50|51|60|64|70|80|90
values: -250|-172|-150|-206|-250|-217|-150|-161|-239|-250|-183|-150|-194|-250|-250

添加主持人图片关键帧-y 轴位移

在这里插入图片描述

添加书籍图片

在这里插入图片描述

生成书籍图片关键帧-x 轴位移、添加书籍图片关键帧-x 轴位移

在这里插入图片描述

offsets: 0|10|13|20|26|30|40|41|50|51|60|64|70|80|90|100
values: 1049|900|937|1049|975|900|1012|1049|900|1049|1012|900|975|1049

生成书籍图片关键帧-y 轴位移、添加书籍图片关键帧-y 轴位移

在这里插入图片描述

offsets: 0|10|13|20|26|30|40|41|50|51|60|64|70|80|90|100
values: 217|137|117|177|217|177|117|137|217|137|117|177|217|117

保存草稿 在这里插入图片描述

3、结束节点

最后编辑一下结束节点 在这里插入图片描述

剪映草稿下载

然后我们点击试运行

在这里插入图片描述

复制草稿地址

在这里插入图片描述

打开剪映小助手,粘贴到地址栏,点击创建草稿

在这里插入图片描述

下载完成后点开剪映,会看到界面多了一个草稿,这就是生成的视频

在这里插入图片描述

剪映小助手下载地址:www.51aigc.cc/#/home

好了,到这里搭建「假如书籍会说话」工作流的教程就讲完了,大家快动手试试吧 ~

如果还是不懂的话可以找我要详细的视频教程和工作流源码! 如果想学习其他工作流的话,我也整理了一份文档,需要的话也可以找我要!

在这里插入图片描述

我将持续每天更新市面上最新最火的工作流教程。如果您有任何关于Coze工作流的想法或需求,有智能体定制需求或者其他需求,欢迎随时留言向我分享。我会认真筛选每一条需求,从中挑选出优质且具有潜力的项目进行制作和教学!