-
Notifications
You must be signed in to change notification settings - Fork 7
feat: GLCC Project - Short Video Production Based on MCP #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @xiaoxianhjy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
此拉取请求为GLCC项目引入了基于MCP的短视频制作功能,作为中期考核的一部分。它主要关注于提示词工程和工作流设计,为自动化视频生成奠定了基础。
Highlights
- 新增背景图片生成工具: 引入了BackgroundImageGenerator类,用于创建带有自定义文本和样式的视频背景图片。
- 增强的Manim提示词系统: 实现了EnhancedManimPromptSystem,旨在通过提供不同类型的提示词模板(基础、数学、教育)、少样本示例和代码验证规则,优化Manim动画代码的生成。
- 全面的质量评估系统: 添加了VisualQualityAssessment、ContentCoherenceChecker、ExampleDrivenJSONParser和AnimationContentMatcher类,用于评估动画质量、检查内容连贯性以及验证动画与文案的匹配度,这表明了对生成内容质量的重视。
- 健壮的JSON解析工具: 引入了json_parser_utils.py,提供了一系列鲁棒的JSON提取、解析和验证函数,以确保与大型语言模型交互时的数据完整性。
- 项目依赖更新: requirements.txt文件已更新,包含了Manim、OpenAI、Pillow等关键库,支持视频生成、AI交互和图像/音频处理功能。
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
此PR为项目引入了一个基于LLM和Manim自动生成科普短视频的完整工作流,架构清晰,功能全面。代码中体现了许多良好实践,例如使用环境变量管理API密钥、实现了带重试和回退的鲁棒错误处理等。
不过,代码中也存在一些可以改进的地方:
- 关键问题:存在一个潜在的字体授权问题,这对于开源项目至关重要,需要立即解决。
- 代码重复:在多个类中存在重复的LLM API调用逻辑,建议进行重构以提升代码的可维护性。
- 小缺陷:部分示例代码和逻辑中存在一些小bug和未使用的代码,应当清理。
- 代码风格:个别魔法数字可以提取为配置项,以增强可读性。
总体而言,这是一次非常有价值的功能添加。解决以上反馈将使代码更加健壮、易于维护,并确保其在开源社区的合规性。
| script_dir = os.path.dirname(os.path.abspath(__file__)) | ||
| font_names = ['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC', 'Microsoft YaHei'] | ||
| # 首先尝试加载本地字体文件 | ||
| local_font = os.path.join(script_dir, 'asset', '字小魂扶摇手书(商用需授权).ttf') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "code": '''from manim import * | ||
|
|
||
| class MLConceptScene(Scene): | ||
| def construct(self): | ||
| # Title with background | ||
| title = Text("Machine Learning", font_size=48, color=BLUE) | ||
| title_bg = SurroundingRectangle(title, color=BLUE, fill_opacity=0.1) | ||
| self.play(DrawBorderThenFill(title_bg), Write(title)) | ||
| self.play(title.animate.scale(0.7).to_edge(UP)) | ||
|
|
||
| # Data points | ||
| dots = VGroup(*[Dot(2*np.random.random(3)-1, color=BLUE) for _ in range(10)]) | ||
| self.play(LaggedStart(*[Create(dot) for dot in dots], lag_ratio=0.1)) | ||
|
|
||
| # Learning process | ||
| line = Line(LEFT*2, RIGHT*2, color=RED) | ||
| learning_text = Text("Learning Pattern...", font_size=24).to_edge(DOWN) | ||
| self.play(Write(learning_text), Create(line)) | ||
|
|
||
| # Result | ||
| result_text = Text("Pattern Found!", font_size=32, color=GREEN).to_edge(DOWN) | ||
| self.play(Transform(learning_text, result_text)) | ||
|
|
||
| self.wait(2)''' | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在 MLConceptScene 的 few-shot 示例中,代码 VGroup(*[Dot(2*np.random.random(3)-1, color=BLUE) for _ in range(10)]) 使用了 np,但是在该代码片段的开头没有 import numpy as np。虽然 from manim import * 可能会导入 numpy,但在示例中明确导入可以提高代码的健壮性和可读性,并确保LLM生成的代码总是有效的。建议在 from manim import * 之后添加 import numpy as np。
"code": '''from manim import *
import numpy as np
class MLConceptScene(Scene):
def construct(self):
# Title with background
title = Text("Machine Learning", font_size=48, color=BLUE)
title_bg = SurroundingRectangle(title, color=BLUE, fill_opacity=0.1)
self.play(DrawBorderThenFill(title_bg), Write(title))
self.play(title.animate.scale(0.7).to_edge(UP))
# Data points
dots = VGroup(*[Dot(2*np.random.random(3)-1, color=BLUE) for _ in range(10)])
self.play(LaggedStart(*[Create(dot) for dot in dots], lag_ratio=0.1))
# Learning process
line = Line(LEFT*2, RIGHT*2, color=RED)
learning_text = Text("Learning Pattern...", font_size=24).to_edge(DOWN)
self.play(Write(learning_text), Create(line))
# Result
result_text = Text("Pattern Found!", font_size=32, color=GREEN).to_edge(DOWN)
self.play(Transform(learning_text, result_text))
self.wait(2)'''| y_position = config['padding'] | ||
| for i, line in enumerate(config['subtitle_lines']): | ||
| bbox = draw.textbbox((0, 0), line, font=subtitle_font) | ||
| x_offset = self.width - bbox[2] - (config['padding'] + 30) + (i * config['subtitle_offset']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if self.topic: | ||
| output_dir = os.path.join(config['output_dir'], self.topic) | ||
| os.makedirs(output_dir, exist_ok=True) | ||
| else: | ||
| output_dir = config['output_dir'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
此处的目录创建逻辑与 __init__ 方法中的部分逻辑重复,并且存在不一致性。当 self.topic 为 False 时,没有为 output_dir 调用 os.makedirs,这依赖于 __init__ 中的创建。建议将目录创建逻辑统一,以提高代码的清晰度和健壮性。
| if self.topic: | |
| output_dir = os.path.join(config['output_dir'], self.topic) | |
| os.makedirs(output_dir, exist_ok=True) | |
| else: | |
| output_dir = config['output_dir'] | |
| if self.topic: | |
| output_dir = os.path.join(config['output_dir'], self.topic) | |
| os.makedirs(output_dir, exist_ok=True) | |
| else: | |
| output_dir = config['output_dir'] | |
| os.makedirs(output_dir, exist_ok=True) |
| def _load_validation_rules(self): | ||
| """加载代码验证规则""" | ||
| return { | ||
| "required_imports": ["from manim import"], | ||
| "required_structure": ["class", "Scene", "def construct"], | ||
| "best_practices": ["self.play", "self.wait", "color="], | ||
| "mathematical": ["MathTex", "LaTeX"], | ||
| "educational": ["Text", "title", "explanation"] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| client = OpenAI( | ||
| base_url='https://api-inference.modelscope.cn/v1', | ||
| api_key=os.environ.get('MODELSCOPE_API_KEY'), | ||
| ) | ||
| max_retries = 3 | ||
| llm_response = None | ||
| for attempt in range(max_retries): | ||
| try: | ||
| llm_response = client.chat.completions.create( | ||
| model='Qwen/Qwen3-235B-A22B-Instruct-2507', | ||
| messages=[ | ||
| {'role': 'system', 'content': 'You are a professional science education animation quality assessor.'}, | ||
| {'role': 'user', 'content': quality_prompt} | ||
| ] | ||
| ) | ||
| break | ||
| except Exception as e: | ||
| print(f"API调用失败,第{attempt+1}次: {e}") | ||
| if attempt < max_retries - 1: | ||
| time.sleep((attempt + 1) * 2) | ||
| else: | ||
| print("API多次失败,返回默认内容") | ||
| return self._mock_quality_assessment() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| moviepy==1.0.3 | ||
| edge-tts==6.1.9 | ||
| pydub==0.25.1 | ||
| matplotlib==3.8.4 No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
基于MCP的短视频制作开源项目
在运行前,请先设置你的魔搭社区的token,例如:$env:MODELSCOPE_API_KEY = "你的token"