diff --git a/短视频AI生成/brand_words.txt b/短视频AI生成/brand_words.txt new file mode 100644 index 0000000..baa1bd7 --- /dev/null +++ b/短视频AI生成/brand_words.txt @@ -0,0 +1 @@ +淘宝闪购 \ No newline at end of file diff --git a/短视频AI生成/main.py b/短视频AI生成/main.py index bdb3ab9..556e047 100644 --- a/短视频AI生成/main.py +++ b/短视频AI生成/main.py @@ -2,4 +2,163 @@ """ 主模块 """ +import warnings +warnings.filterwarnings( + action="ignore", category=UserWarning, module="volcenginesdkarkruntime.*" +) + +import json +from pathlib import Path +from typing import Any, Dict, List +from uuid import uuid4 + +from volcenginesdkarkruntime import Ark +from volcenginesdkarkruntime.types.responses import ( + ResponseOutputMessage, + ResponseOutputText, +) + + +# 初始化火山引擎 AsyncArk 客户端 +ark_client = Ark( + base_url="https://ark.cn-beijing.volces.com/api/v3", + api_key="2c28ab07-888c-45be-84a2-fc4b2cb5f3f2", +) # 本人火山引擎账密 + + +def generate_task_id() -> str: + """ + 生成任务标识 + :return: 任务ID + """ + return uuid4().hex.upper().replace("-", "") + + +def get_brand_words() -> List[str]: + """ + 获取品牌词 + :return: 品牌词 + """ + try: + with open( + file=Path(__file__).parent / "brand_words.txt", mode="r", encoding="utf-8" + ) as file: # Trae IDE 需要指定文件路径(和 PyCharm 不同) + brand_words = [line.strip() for line in file.readlines() if line.strip()] + assert brand_words, "品牌词为空" + return brand_words + except FileNotFoundError: + raise FileNotFoundError("未找到品牌词文件") + except Exception as exception: + raise exception + + +def refactor_storyboard_prompt(brand_word: str) -> str: + """ + 重构分镜脚本的提示词 + :param brand_word: 品牌词 + :return: 重构后分镜脚本的提示词 + """ + try: + with open( + file=Path(__file__).parent / "storyboard_prompt_template.txt", + mode="r", + encoding="utf-8", + ) as file: + storyboard_prompt = file.read() + return storyboard_prompt.replace("{{品牌词}}", brand_word) + except FileNotFoundError: + raise FileNotFoundError("未找到分镜脚本的提示词模板文件") + except Exception as exception: + raise exception + + +def get_storyboard(brand_word: str) -> Dict[str, Any]: + """ + 获取分镜脚本 + :param brand_word: 品牌词 + :return: 分镜脚本 + """ + # 重构分镜脚本的提示词 + storyboard_prompt = refactor_storyboard_prompt(brand_word) + + retries = 0 # 重试次数 + while True: + try: + # 调用豆包Seed语言大模型,基于分镜脚本的提示词生成分镜脚本 + response = ark_client.responses.create( + model="doubao-seed-2-0-pro-260215", + input=[ + { + "role": "user", + "content": [{"type": "input_text", "text": storyboard_prompt}], + } + ], + ) + # 解析响应并反序列化以此作为分镜脚本 + storyboard = json.loads( + [item for item in [item for item in response.output if isinstance(item, ResponseOutputMessage)][0].content if isinstance(item, ResponseOutputText)][0].text # type: ignore + ) + return storyboard + except Exception as exception: + retries += 1 + if retries > 2: + raise Exception(f"获取分镜脚本发生异常,{str(exception)}") + continue + + +storyboard = { + "核心营销要点": "淘宝闪购每日上新全品类正品好物,限时超低价开抢,购物省心又划算", + "分镜脚本": [ + { + "阶段": "前段", + "口播": "买好物想省钱看这里!", + "TTS情绪": "energetic", + "首帧提示词": "橙色淘宝闪购logo 画面中央偏上 半透明小尺寸、特效未展开 浅橙色渐变背景 亮橙+米白 柔和光影 9:16竖屏 1080P 高清干净 无水印", + "尾帧提示词": "橙色立体淘宝闪购logo 画面正中央 清晰显示、周围带细碎金光闪效 浅橙色渐变背景 亮橙+暖白 明亮光影 9:16竖屏 1080P 高清干净 无水印", + "运镜提示词": "slight zoom in", + }, + { + "阶段": "中段", + "口播": "淘宝闪购全是官方正品,服饰美妆数码家居全品类,每天限时开抢价格超划算", + "TTS情绪": "happy", + "首帧提示词": "服饰、美妆、数码、家居四类商品缩略图围绕淘宝闪购logo 画面中央 半透明小尺寸、特效未展开 暖白色背景 多彩明快 柔和光影 9:16竖屏 1080P 高清干净 无水印", + "尾帧提示词": "服饰、美妆、数码 、家居爆款商品清晰展示,旁附「直降50%」「限时抢」标签,淘宝闪购logo居上方中央 高亮饱满、爆闪优惠光效完全展开 暖白色背景 多彩明亮 充足光影 9:16竖屏 1080P 高清干净 无水印", + "运镜提示词": "slow push in", + }, + { + "阶段": "后段", + "口播": "快点击下方链接抢!", + "TTS情绪": "cheer", + "首帧提示词": "黄色「点击下方链接」按钮+淘宝闪购logo 画面中央 半透明小尺寸、特效未展开 亮橙色背景 亮黄+橙红 柔和光影 9:16竖屏 1080P 高清干净 无水印", + "尾帧提示词": "高亮立体「点击下方链接」按钮+闪烁箭头指向屏幕下方,淘宝闪购logo居按钮上方 完全展示、高亮饱满、脉冲光效完整 亮橙色背景 亮黄+橙红 明亮耀眼光影 9:16竖屏 1080P 高清干净 无水印", + "运镜提示词": "slight zoom in", + }, + ], +} + + +def generate_frame(frame_prompt: str) -> str: + """ + 生成视频帧 + :param frame_prompt: 视频帧提示词 + :return: 视频帧 + """ + # 调用豆包Seed图像大模型,基于视频帧提示词生成视频帧 + response = ark_client.responses.create( + model="doubao-seed-2-0-pro-260215", + input=[ + { + "role": "user", + "content": [{"type": "input_text", "text": frame_prompt}], + } + ], + ) + # 解析响应并反序列化,以此作为视频帧 + frame = json.loads( + [item for item in [item for item in response.output if isinstance(item, ResponseOutputMessage)][0].content if isinstance(item, ResponseOutputText)][0].text # type: ignore + ) + return frame + + +print(storyboard) diff --git a/短视频AI生成/storyboard_prompt_template.txt b/短视频AI生成/storyboard_prompt_template.txt new file mode 100644 index 0000000..029f554 --- /dev/null +++ b/短视频AI生成/storyboard_prompt_template.txt @@ -0,0 +1,72 @@ +你作为一名专业、优秀的广告编导,请为品牌“{{品牌词}}”生成一条15秒营销广告分镜脚本。该脚本用于AI生成短视频,投放于快手、今日头条、视频号等短视频平台。 + +必须严格遵守以下所有规则,不可遗漏任何字段: + +1. 内容要求 +- 符合品牌真实经营范围与营销风格 +- 符合短视频平台用户偏好 +- 不得虚构、不得违规 + +2. 时长结构(总15秒) +- 前段:3秒,吸引注意力 +- 中段:10秒,传递核心卖点 +- 后段:2秒,引导点击下方链接 + +3. 口播要求(用于 EdgeTTS 语音合成) +- 前段口播:8~12个汉字 +- 中段口播:25~35个汉字 +- 后段口播:5~10个汉字 +- 口语化、情绪饱满、适合短视频传播 + +4. TTS 情绪要求(必须返回英文单词) +- 从以下列表中选择:cheer, happy, energetic, warm, friendly, confident +- 字段名固定为:TTS情绪 + +5. 首帧 / 尾帧提示词(用于 Seedream 4.5 文生图) +- 格式:主体+位置+状态+环境+色彩+光影 +- 9:16 竖屏,1080P,高清干净,无水印 +- 首帧:元素刚出现,半透明,小尺寸,特效未展开 +- 尾帧:元素完全展示,高亮饱满,特效完整 +- 画面自然、有质感、适合电商营销 + +6. 运镜提示词(用于 Seedance 1.5 图生视频,必须英文) +- 运镜平稳、无抖动 +- 主体居中不变形 +- 可选:slow push in, slow pan, slight zoom in, slow circle +- 与本段时长匹配 + +7. 输出强制要求 +- 只输出标准 JSON,无任何多余文字 +- 不要解释、不要前言、不要后缀 +- 不要 ```json 标记 +- 严格按下面结构输出 + +{ + "核心营销要点": "一句话总结品牌核心价值", + "分镜脚本": [ + { + "阶段": "前段", + "口播": "...", + "TTS情绪": "...", + "首帧提示词": "...", + "尾帧提示词": "...", + "运镜提示词": "..." + }, + { + "阶段": "中段", + "口播": "...", + "TTS情绪": "...", + "首帧提示词": "...", + "尾帧提示词": "...", + "运镜提示词": "..." + }, + { + "阶段": "后段", + "口播": "...", + "TTS情绪": "...", + "首帧提示词": "...", + "尾帧提示词": "...", + "运镜提示词": "..." + } + ] +} \ No newline at end of file