Files
dsProject/dsLightRag/Manim/Demos/T_0.py
2025-08-14 15:45:08 +08:00

195 lines
7.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
import logging
import os
import subprocess
from Manim.Demos.ManimKit import SYS_PROMPT, generate_code_with_llm
# 更详细地控制日志输出
logger = logging.getLogger('T0')
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
logger.addHandler(handler)
if __name__ == '__main__':
try:
# 首次生成唯一时间戳
# timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S_%f')[:-3] # 保留到毫秒
# 后续写死时间戳
timestamp = "20250804_084910_884"
skeleton_basename = f"Skeleton/Skeleton_{timestamp}.py"
scene_class_name = f"Skeleton_{timestamp}"
# 教师输入的提示词数组(简化版)
teacher_prompts = [
{
"id": 1,
"task": "生成片头标题动画",
"requirements": [
"黑色背景",
"使用大标题文本'东师理想数学动画AI制作平台作品',字号=60白色",
"添加副标题'正弦与余弦的关系',字号=36蓝色",
"主标题+副标题淡入2秒停留3秒淡出2秒",
"最后清屏1秒"
]
},
{
"id": 2,
"task": "生成可运行的 Manim 场景骨架",
"requirements": [
"黑色背景",
"建立完整四象限坐标系x∈[-3.5π,3.5π]y∈[-1.5,1.5]",
"不画任何曲线,只显示坐标轴,坐标轴要记得带箭头"
]
},
{
"id": 3,
"task": "在上一步基础上追加",
"requirements": [
"用绿色画 y = sin(x)",
"用 MathTex 在 (-3π,1) 位置标 'sin(x)'",
"动画:坐标轴淡入 1s → 曲线从左到右扫出 3s"
]
},
{
"id": 4,
"task": "在上一步基础上追加",
"requirements": [
"用红色画 y = cos(x)",
"用 MathTex 在 (3π,-1) 位置标 'cos(x)'",
"动画TransformFromCopy 把正弦变成余弦 3s",
"最后在屏幕上方用黄色 MathTex 写出 cos(x) = sin(x + π/2)"
]
},
{
"id": 5,
"task": "在上一步基础上追加",
"requirements": [
"黄色虚线竖线随 x 移动",
"绿色圆点跟踪 sin(x)",
"红色圆点跟踪 cos(x)",
"ValueTracker 从 -3π 匀速扫到 3π耗时 6s",
"其余元素保持不变"
]
}
]
# 系统补充信息(教师无需关心)
system_supplements = {
"base_info": f"文件名:{skeleton_basename},场景类:{scene_class_name}",
"output_requirement": "输出:完整代码 + `if __name__ == \"__main__\":`",
"continue_requirement": f"输出:完整替换 {skeleton_basename} 的新代码",
"video_config": "帧率30fps输出目录output/",
}
# 设置保存路径
skeleton_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), skeleton_basename)
# 显示所有可用任务
print("可用任务列表:")
for prompt_info in teacher_prompts:
print(f"任务 {prompt_info['id']}: {prompt_info['task']}")
for req in prompt_info['requirements']:
print(f" - {req}")
print()
# 让用户选择要执行的任务ID
while True:
try:
selected_id = int(input("请输入要执行的任务ID (1-5): "))
if 1 <= selected_id <= 5:
break
else:
print("无效的ID请输入1-5之间的数字。")
except ValueError:
print("请输入有效的数字。")
# 查找用户选择的任务
selected_prompt = None
for prompt_info in teacher_prompts:
if prompt_info['id'] == selected_id:
selected_prompt = prompt_info
break
# 处理用户选择的任务
prompt_id = selected_prompt["id"]
task = selected_prompt["task"]
requirements = selected_prompt["requirements"]
logger.info(f"处理任务 {prompt_id}: {task}...")
# 构建教师输入部分
teacher_part = f"任务:{task}\n要求:\n"
for req in requirements:
teacher_part += f"- {req}\n"
# 构建完整提示词
if prompt_id == 1:
# 第一个任务,包含基础信息和输出要求
full_prompt = f"""
{teacher_part}
{system_supplements['base_info']}
{system_supplements['output_requirement']}
重要配置要求:
- 请设置输出目录为output/
- 设置帧率为30fps
- 确保生成MP4格式视频
- 添加标题淡入淡出动画以确保生成视频而非静态图像
"""
else:
# 后续任务,检查前置文件是否存在
if os.path.exists(skeleton_path):
# 构建继续要求
full_prompt = f"""
{teacher_part}
{system_supplements['continue_requirement']}
{skeleton_basename} 内容:
{open(skeleton_path, 'r', encoding='utf-8').read()}
重要配置要求:
- 请保持输出目录为output/
- 保持帧率为30fps
- 确保生成MP4格式视频
"""
else:
logger.error(f"错误: 任务 {prompt_id} 依赖于前置任务生成的 {skeleton_basename} 文件,但该文件不存在。")
logger.info("请先执行任务 1 生成基础文件,然后再执行后续任务。")
exit(1)
# 格式化系统提示
formatted_prompt = SYS_PROMPT.format(XuQiu=full_prompt,Preview=True)
# 调用函数生成代码
generate_code_with_llm(prompt=formatted_prompt, save_path=skeleton_path)
logger.info(f"任务 {prompt_id} 处理完成!生成的文件为:{skeleton_basename}")
# 执行生成的Skeleton文件
logger.info(f"正在执行 {skeleton_basename} ...")
try:
# 定义清晰的输出目录
current_dir = os.path.dirname(os.path.abspath(__file__))
output_dir = os.path.join(current_dir, "output")
os.makedirs(output_dir, exist_ok=True)
# 构建执行命令根据preview参数决定是否添加-p选项
command = ['python', skeleton_path, '-o', output_dir]
# 执行文件并通过命令行参数指定输出目录
subprocess.run(
command,
check=True
)
logger.info(f"视频已生成到: {output_dir}\\videos\\1080p30\\Skeleton_{timestamp}.mp4")
# TODO
# 这个生成的视频路径对于研发来讲很重要,需要返回给前端,前端展示给用户查看效果
except subprocess.CalledProcessError as e:
logger.error(f"执行文件时出错: {str(e)}")
except Exception as e:
logger.error(f"执行过程中发生未知错误: {str(e)}")
except Exception as e:
logger.error(f"程序执行出错: {str(e)}")