day06-Coze工作流之口播数字人

今日内容

1 目标

# 1 制作一个工作流实现:
	-1.1 用户上传一段口播视频  + 一段音频---》合成到一起---》对口型口播视频
    -1.2 用户上传一段口播视频  + 写一段文字--》克隆本人的音色--》生成口播视频
    -1.3 用户上传一段口播视频,没有声音,没有文字--》 实现很多的段子--》克隆本人的音色--》生成口播视频
    
# 2 做成视频
	-发布小红书
    -抖音
    
# 3 解决:
	不需要我们每次都在镜头前录一段视频,提前录制好一个底视频,填入文字--》自动生成视频

1.1 展示

2 注册 飞影数字人--克隆音色

# 1 官网:免费额度,需要收费【积分】--》https://hifly.cc/i/nRIvKHfGXX6
	-https://hifly.cc/
        
        
# 2 注册后--》声音克隆
	-https://hifly.cc/clone
    -可以使用公共的音色
    
# 3 添加声音--》上传一段 mp3---》你的声音
	-如何录制自己的声音:ev录屏
    -只录声音即可
    
    
# 4 克隆完后,复制声音id
	- 04575cff-8f34-4905-a4d2-b6b06afdd3ec
    - 你们自己克隆自己的--》生成口播视频后,才是自己的音色
    
    
# 5 接下来使用Coze,创建工作流--》生成口播数字人--》使用的音色就是上面克隆的

# 6 Coze中使用飞影数字人插件:插件上有介绍,一会看
	-收费:速度快,无水印
    -免费费:速度慢,有水印

image-20260522201319271

image-20260522201551343

image-20260522202404171

3 Coze一键生成口播数字人工作流

3.1 拆分

# 1 目标:制作一个数字人口播工作流
	-1.1 用户上传一段口播视频  + 一段音频---》合成到一起---》对口型口播视频
    -1.2 用户上传一段口播视频  + 写一段文字--》克隆本人的音色--》生成口播视频
    -1.3 用户上传一段口播视频,没有声音,没有文字--》 现实生活中很多的段子,最新的新闻--》克隆本人的音色--》生成口播视频

# 2 拆分【比之前的复杂--不以节点数衡量工作流的好坏】
	1- 开始:【3个变量:视频必传,音频和文字选传】
    	-一段露脸视频【正脸】---》【20s-30s】--》作为底片
		-一段音频--【视频+此音频合成口播】
        -一段文字--》通过本人音色--》生成文字口播
        -只传了视频,没有音频和文字--》大模型生成时下热点---》生成口播
    2 选择器:	
    	-判断用户是否上传了音频
        	-如果上传了音频--》走下面:视频音频合成分支
        	-如果没上传音频--》走上面:文字+底片  、 大模型生成文字+底片
    3 分支:文字+底片  、 大模型生成文字+底片
    	
    3.1 选择器:
    	-判断用户是否上传了文字
        	-如果传了文字,直接用
            -如果没传文字,大模型获取时下热点--》生成文字
     3.2 大模型:获取时下热点
     3.3 代码节点:从大模型生成的文字 或  用户上传的文字中,选一个非空---》继续往后走
        	-目的:【变量聚合作用一样】
            	如果用户上传了文字---》口播的文字就是用户上传的
            	如果用户没有上传了文字---》口播的文字就是大模型生成的的
                
     3.4 飞影数字人生成插件---》生成口播
    	-音色id
        -文字【可能是用户传的,可能是大模型生成的】
      	-露脸视频:底片
        
    4 飞影数字人生成插件---》音频视频合成:生成口播
    	-音频
        -视频
    5 代码:两个飞影生成口播视频的分支,必定只有一个走了,选择一个非空,继续往后走
    	-选择一个非空的,继续往后走【变量聚合作用一样】
        
    6 循环查询飞影数字人是否生成成功
    6.1 代码:先休息15s
    6.2 飞影查询数字人是否成功的插件
    6.3 选择器
    	-生成成功---》结束循环
        -没生成成功--》继续循环
    7 代码节点
    	-循环查询了很多次--》只有最后一次的查询结果中有口播视频
        -取出最后有口播视频的链接
    8 结束:
    	输出口播视频地址

image-20260522202600069

image-20260522204422360

3.2 开始

# 1 三个参数
	-视频底片:必填
    -音频
    -文字

image-20260522205230228

3.3 选择器:判断用户是否上传音频

# 1 判断用户是否上传了音频
	-没上传--》走上面
    -上传了--》走下面

image-20260522205500739

3.4 文字 生成口播分支

3.4.1 选择器:判断用户是否上传了文字

# 1 判断用户是否上传文字
	-如果没传文字--》走上面--》大模型生成文字
    -如果传了文字--》走下面--》直接用

image-20260522205821705

3.4.2 大模型:生成时下热点文字

######### 提示词############
# 角色
你是一位极具幽默感的口播创作者,擅长创作出令人捧腹大笑且时长在 1 分钟内的口播文字内容。

## 技能
### 技能 1: 生成搞笑口播
无需用户输入,直接随机创作一段搞笑且时长在 1 分钟内的口播文字内容。内容可以涵盖生活趣事、幽默段子、诙谐故事等各种搞笑元素,要确保语言生动活泼、风格独特,能让听众在短时间内开怀大笑。

## 限制:
- 输出内容必须是搞笑风格的口播文字,且时长要在 1 分钟内。
- 语言表达要清晰易懂、生动有趣,避免使用过于晦涩或专业的词汇。 

######## 该大模型不需要输入################

image-20260522210242487

3.4.3 代码节点:选择大模型文案或用户上传文案

# 1 工作流中,可以插入代码,完成我们的需求
	-可以使用两种语言任选其一
    	-js:不会
        -python:我们选择
        
        
# 2 代码不要求大家自己能写出来,只要能懂意思即可:可以用ai生成【后续会讲ai生成代码】


# 3 代码节点:本质也是节点
	-有输入
    	-代码完成中间的操作
    -有输出
    
# 4 我们这个代码节点:作用
	-输入:
    	-大模型生成的文字
        -用户上传的文字
    -输出:
    	-选择一种文字输出【要么是大模型的,要么是用户上传的】
        
        
# 5 代码节点模板【coze代码节点,相对固定】
async def main(args: Args) -> Output:
    # 1 params 当成一个包裹:包裹中有传入的变量:llm_text,text
    params = args.params
    # 加一堆逻辑,输出即可
    # 2 返回的变量【规范是必须包裹在字典中】:out---》值是 lqz
    ret: Output = {
        "out": "lqz",
    }
    return ret


# 6 真正的代码
async def main(args: Args) -> Output:
    params = args.params
    #1  取出llm_text和text
    llm_text=params['llm_text']   # 取出传入的 llm_text,大模型生成的文字
    text=params['text']   # 取出传入的 text:用户传的文字
    
    # 2 返回llm_text 或 text 的非空
    ret: Output = {
        "out": llm_text or text,  # 谁不为空输出谁
    }
    return ret
async def main(args: Args) -> Output:
    params = args.params
    #1  取出llm_text和text
    llm_text=params['llm_text']   # 取出传入的 llm_text,大模型生成的文字
    text=params['text']   # 取出传入的 text:用户传的文字
    
    # 2 返回llm_text 或 text 的非空
    ret: Output = {
        "out": llm_text or text,  # 谁不为空输出谁
    }
    return ret

image-20260522213943206

image-20260522214145246

3.4.4 飞影数字人插件

#1 地址:https://www.coze.cn/store/plugin/7472321639192084506

# 2 介绍
输入人物视频,以及一段音频或文本,生成对口型数字人视频。飞影会员(https://hifly.cc 免费注册)可生成无时长限制、无水印的视频。 用文本驱动时需指定声音ID,可选择以下声音: 芳芳(适合童声、故事、宣传片):0bdcbf49-5704-4a18-b4c5-1fcee7b6b1e2 小李(适合口播、培训):570f41c9-0fdd-415e-939b-1e9335851494 老中医(适合健康科普):96728d36-dfbe-4285-ad4d-879c46a013d2 李阿姨(适合电商带货):2654756a-c7d9-4b81-97d3-e9e76d56d7ff 红女郎(适合口播、培训):1169ef2d-7911-4b0c-855e-188e8a76ca53 更多声音可前往 https://hifly.cc/market/voice 选择(收藏声音后,可在"我的收藏”中复制声音ID),也可一键复刻( https://hifly.cc/clone )声音,支持7种语言5种方言
        
# 3 总结
	-如果免费,有水印
    -如果在飞影注册,充钱--》使用hifly_id【官网获取】--》没有水印

image-20260522214500618

image-20260522214908462

3.5 音频视频生成口播分支

image-20260522215151953

3.6 代码节点

两个飞影数字人节点--》共同进入到代码中--》选择一个非空

async def main(args: Args) -> Output:
    params = args.params
    # 1 取出:job_id01和job_id02
    job_id01=params['job_id01']
    job_id02=params['job_id02']
    # 2 返回一个非空
    ret: Output = {
        "out": job_id01 or job_id02,
    }
    return ret

3.7 循环等待口播视频制作完成

# 1 三种情况,三个分支,只会走一条
	-无论走哪条--》都让飞影在制作视频呢--》比较耗时
    -我们通过job_id--》查询视频是否制作完成
    
# 2 使用循环:每隔15s,查询一次
	-如果视频制作好了--》直接结束
    -如果视频没制作好--》继续循环
    	-15s再查。。。

image-20260522220252019

image-20260522221354569

3.7.1 代码:睡15s

image-20260522220838454

import time
async def main(args: Args) -> Output:
    params = args.params
    # 睡15s
    time.sleep(15)
    ret: Output = {
        "out": "",
    }
    return ret

3.7.2 查询数字人状态

image-20260522220821757

3.7.3 选择器

# 1 判断上一个查询 视频节点是否返回了视频
	-如果video_url 有值,说明创造好了--》终止循环
    -如果video_url 没有值,说明没有创造好了--》继续循环

image-20260522221133967

3.8 代码节点

#  1 作用
	取出创造好的,口播视频地址
# 2 为什么要使用代码取出视频地址
	-我们循环了很多次--》生成一个列表-->取出视频的地址
    	["","","","https://www.sadfasd.com/xxx.mp4"]
        
        
# 3 代码:我已经写好了
def filter_first_non_empty(data):
    # 确保输入是列表
    if not isinstance(data, list):
        raise ValueError("Input data.output must be a list.")
    
    # 找到第一个非空的元素
    for item in data:
        # 确保元素是字符串类型并去除空白后检查
        if isinstance(item, str) and item.strip() != "":
            return item
    
    # 如果没有找到非空元素,返回空字符串
    return ""


async def main(args: Args) -> Output:
    params = args.params

    # 构建输出对象
    ret: Output = {
        "out": filter_first_non_empty(params["input"])
   
    }
    return ret

3.9 结束

image-20260522222031670

posted @ 2026-05-28 17:54  凫弥  阅读(31)  评论(0)    收藏  举报