-
Notifications
You must be signed in to change notification settings - Fork 262
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
Dev v2 #67
Conversation
- 新增 V2脚本生成接口和相关服务 - 重构脚本生成逻辑,提高可维护性和可扩展性 - 优化关键帧提取和处理流程 - 改进错误处理和日志记录
- 在 schema_v2.py 中添加了新的请求和响应模型 - 在 script.py 中实现了 /scripts/crop 和 /youtube/download 接口- 新增 video_service.py 和 youtube_service.py 服务模块 - 更新 utils.py 中的工具函数以支持新功能
…sponse 模型- 实现 /scripts/start-subclip 接口,用于启动视频剪辑任务 - 支持异步处理,返回任务 ID 和初始状态
- 修改支持的语音列表,仅保留中文语音 - 在主程序中添加代理配置环境变量 -优化剪辑视频函数,改为返回字典类型 - 更新任务服务中的剪辑视频函数,适应新的参数类型 - 修改测试用例中的视频剪辑函数,增加输出路径参数 - 更新脚本控制器中的剪辑视频函数,集成任务 ID 和子视频字典
- 新增参数以支持更灵活的配置 -优化脚本保存逻辑,支持自定义脚本名称 -增加视频下载和脚本生成的条件判断,提高效率 - 异步生成最终视频,返回任务路径 - 更新示例使用新的管道配置
- 新增 extract_audio_and_create_subtitle函数,用于从视频文件中提取音频并生成字幕文件 - 更新 video_pipeline.py,修改视频下载和处理的相关参数
- 新增 chat_with_qwen 函数,用于与通义千问AI模型进行对话 - 添加错误处理和资源管理,提高代码健壮性 - 优化视频剪辑功能,增加输出路径参数 -读取字幕文件并将其作为输入发送给AI模型 -处理API调用异常,并提供错误文档链接
-重构了 merge_audio_files 函数,增加了对 OST 设置的支持 - 新增 time_to_seconds 函数,支持多种时间格式的转换 - 修改了 audio_merger 模块的逻辑,根据 OST 设置处理音频 - 更新了 task 模块中的 start_subclip 函数,传入 OST 信息 - 优化了 subtitle 和 video 模块的逻辑,适应新的音频处理方式
- 重构了时间戳转换函数,支持 HH:MM:SS,mmm 格式 - 优化了时间戳计算逻辑,提高了精度- 更新了相关服务和工具类中的时间戳处理方法
|
GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
---|---|---|---|---|---|
14652941 | Triggered | Generic High Entropy Secret | 86d398d | app/test/test_qwen.py | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
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 by ChatGPT
# headers=headers, | ||
# filename=f"{filename}{extension}", | ||
# media_type=f"video/{extension[1:]}", | ||
# ) |
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.
该代码看起来是一个 FastAPI 应用,提供了几个 API 端点用于管理视频和音乐文件。以下是一些代码审查的结果:
注释和文档
代码中缺乏注释和文档,这对于代码的维护和理解是很有帮助的。建议添加注释和文档来解释代码的目的和功能。
错误处理
代码中有一些错误处理,但是它并不是很完善。例如,在 upload_bgm_file
函数中,如果文件上传失败,会抛出一个 HttpException
,但是这个错误信息并不详细。建议增加详细的错误信息和错误处理机制。
文件路径处理
代码中使用了 os.path.join
来处理文件路径,这是正确的。但是,建议使用 pathlib
库来处理文件路径,因为它更方便和安全。
文件类型检查
在 upload_bgm_file
函数中,只检查了文件扩展名是否为 .mp3
,但是并没有检查文件的类型是否是真正的音频文件。建议增加文件类型检查来确保文件是真正的音频文件。
视频流和下载
视频流和下载功能实现了,但是建议优化这些功能来提高性能和安全性。例如,可以使用 StreamingResponse
来实现视频流,而不需要将整个视频文件加载到内存中。
文件上传
文件上传功能实现了,但是建议增加文件上传的大小限制和文件类型限制来防止恶意用户上传很大的文件或非允许的文件类型。
路由
路由设计得比较混乱,建议重新设计路由来提高代码的可读性和维护性。例如,可以使用子路由来分组相关的 API 端点。
测试
代码中缺乏测试,这对于代码的可靠性和维护性是很重要的。建议增加测试来确保代码的正确性和稳定性。
其他
代码中有一些重复的代码,建议提取出重复的代码来提高代码的可读性和维护性。
# 将认证依赖项应用于所有路由 | ||
if dependencies: | ||
router.dependencies = dependencies | ||
return router |
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.
这段代码定义了一个函数 v2_router
,用于创建一个 FastAPI 路由器(router)。以下是一些代码审查意见和建议:
bug 风险:
dependencies
参数类型没有被限制,理论上可以传入任何类型的数据。如果传入的数据不符合 FastAPI 的期望类型,可能会导致异常。建议增加类型提示,例如dependencies: List[Depends] = None
。- 如果传入的
dependencies
参数中包含相同的认证依赖项,可能会导致重复注册的错误。 router.tags
和router.prefix
的赋值没有做任何错误处理,如果赋值失败(例如,tags
不是列表类型),可能会导致未捕获的异常。
改进建议:
- 考虑增加文档注释,描述
v2_router
函数的作用和参数含义。 - 考虑增加类型提示,明确
dependencies
参数的类型和范围。 - 考虑增加错误处理,捕获可能的异常并返回合理的错误信息。
- 考虑增加测试用例,确保
v2_router
函数的正确性和robust性。
改进后的代码示例:
from fastapi import APIRouter, Depends
from typing import List, Optional
def v2_router(dependencies: Optional[List[Depends]] = None) -> APIRouter:
"""
创建一个 FastAPI 路由器,应用于 V2 API。
Args:
dependencies (List[Depends], optional): 认证依赖项列表。 Defaults to None.
Returns:
APIRouter: FastAPI 路由器实例。
"""
try:
router = APIRouter()
router.tags = ["V2"]
router.prefix = "/api/v2"
if dependencies:
router.dependencies = dependencies
return router
except Exception as e:
# 添加错误处理和日志记录
print(f"Error creating V2 router: {e}")
raise
|
||
except Exception as e: | ||
logger.exception(f"Start subclip task failed: {str(e)}") | ||
raise |
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.
这是一个使用FastAPI框架的API代码。以下是一些代码评审的建议和发现的潜在问题:
- 异常处理: 代码中使用了try-except块来捕获异常,并使用logger记录异常信息。但是,并没有对异常进行分类处理,只是简单地记录并重新抛出异常。建议根据异常类型进行不同的处理和返回结果。
- 参数验证: 代码中没有对输入参数进行验证和处理。建议使用Pydantic的参数验证和默认值功能来确保输入参数的正确性和完整性。
- 异步任务: 代码中使用了BackgroundTasks来创建异步任务。建议使用更高级的异步任务库,例如 Celery或Zato,来简化异步任务的管理和调度。
- 服务类: 代码中使用了服务类(ScriptGenerator、VideoService、YoutubeService等)来执行业务逻辑。建议考虑使用工厂模式或依赖注入模式来创建和管理服务实例。
- 类型定义: 代码中使用了类型定义(GenerateScriptRequest、CropVideoRequest等)来定义API请求体。建议考虑使用 typing模块来定义更复杂的类型和结构。
- 实例变量: 代码中使用了实例变量(如task_id)来存储临时数据。建议考虑使用更安全和高效的方式,例如使用 fastapi.Request.state来存储请求状态数据。
- 重复代码: 代码中有重复的try-except块和异常处理代码。建议考虑抽取出公共的异常处理方法来减少重复代码。
- 测试: 代码中没有测试用例。建议考虑写入测试用例来确保API的正确性和可靠性。
以下是一些具体的代码优化建议:
generate_script
和crop_video
函数的try-except块可以合并为一个公共的异常处理函数。start_subclip
函数中可以使用fastapi.Request.state来存储任务ID和状态数据,而不是直接传递参数。task_service.start_subclip
函数可以考虑使用asyncio.create_task来异步执行任务,而不是直接使用BackgroundTasks。VideoClipParams
类型定义可以使用typing模块来定义更复杂的类型和结构。
@@ -366,6 +366,8 @@ class VideoClipParams(BaseModel): | |||
custom_position: float = Field(default=70.0, description="自定义位置") | |||
|
|||
n_threads: Optional[int] = 8 # 线程数,有助于提升视频处理速度 | |||
tts_volume: float = 1.0 # TTS音频音量 | |||
video_volume: float = 0.1 # 视频原声音量 | |||
|
|||
class VideoTranscriptionRequest(BaseModel): | |||
video_name: str |
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.
这段代码看起来是Python,使用了Pydantic的BaseModel和Field来定义模型。这是一个非常简洁的补丁,但是仍然有一些细节可以注意:
-
注释和文档:虽然已有的注释是在描述各个字段的用途,但是建议在增加新字段时也加上相应的注释,例如
tts_volume
和video_volume
的默认值是为什么这么设定的。 -
类型和缺省值:对于
tts_volume
和video_volume
的缺省值,如果是没有具体设定,建议可以使用一个_ENUM_来自定义这些值的取值范围,以提示他人这两个值应该取哪些具体值。 -
类型潜在问题:虽然代码里用的是浮点数类型的值(float),但如果使用者可能会传入无效的、或者超出正常范围的值(例如负数),建议加以检查的机制。
示例:
from enum import Enum
from pydantic import BaseModel, Field
class VolumeLevel(Enum):
min = 0.0
max = 1.0
class VideoClipParams(BaseModel):
...
tts_volume: float = Field(default=1.0, ge=0.0, le=1.0, description="TTS音频音量,取值范围[0.0, 1.0]")
video_volume: float = Field(default=0.1, ge=0.0, le=1.0, description="视频原声音量,取值范围[0.0, 1.0]")
...
- 测试覆盖率:为了确保这两行新代码不会破坏已有的代码逻辑,建议编写测试用例来覆盖这些新的场景,以避免后续的潜在问题。
task_id: str | ||
state: str | ||
videos: Optional[List[str]] = None | ||
combined_videos: Optional[List[str]] = None |
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.
这是一个使用 Pydantic 定义的模型(Model)代码。总体来说,代码结构清晰,类型注释清楚,易于理解。但是,我有一些建议和注意事项:
- 类型注释:尽管有些字段已经注释了类型,但是建议将所有的 字段都加上类型注释,例如
video_path
、url
等。 - ** Optional类型 **:有些字段使用
Optional
类型,但是没有指定默认值,例如voice_name
、rename
等。如果没有默认值,最好使用None
来指定。 - 列表类型:有些字段使用
List[dict]
,但是并没有指定字典结构。如果可能,最好指定字典结构,例如List[Dict[str, str]]
。 - 枚举类型:有一些字段的值可能是枚举类型,例如
resolution
、video_aspect
等。如果可能,最好定义枚举类型来限制值的范围。 - 文档注释:建议添加模型和字段的文档注释,来描述每个字段的含义和用途。
- 任务ID:多个模型中都有
task_id
字段,建议定义一个常量或枚举来表示任务 ID 的类型。 - 验证:通过 Pydantic 的验证功能,可以添加一些校验规则,例如检查值是否在一定范围内等。
总的来说,这个代码基本上是良好的,但是可以通过一些注释和类型定义来提高代码的可读性和安全性。
@@ -7,6 +8,8 @@ | |||
logger.info( | |||
"start server, docs: http://127.0.0.1:" + str(config.listen_port) + "/docs" | |||
) | |||
os.environ["HTTP_PROXY"] = config.proxy.get("http") | |||
os.environ["HTTPS_PROXY"] = config.proxy.get("https") | |||
uvicorn.run( | |||
app="app.asgi:app", | |||
host=config.listen_host, |
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.
以下是代码审查后的结果:
- 未导入模块 config:在patch中,使用了 config 模块,但没有导入它。请确保 config 模块已在文件中导入。
- 潜在的环境变量覆盖:在设置 os.environ["HTTP_PROXY"] 和 os.environ["HTTPS_PROXY"] 时,可能会覆盖其他模块或应用的环境变量设置。为了避免这种情况,可以考虑使用更特定的环境变量名称,例如 "MY_APP_HTTP_PROXY" 和 "MY_APP_HTTPS_PROXY"。
- 异常处理:在执行 uvicorn.run() 时,如果发生异常,可能会导致服务器崩溃。建议添加 try-except 块来捕获异常并记录错误信息。
- HTTP_PROXY 和 HTTPS_PROXY 的验证:在设置环境变量时,没有验证 HTTP_PROXY 和 HTTPS_PROXY 的值是否有效。如果值为空或不正确,可能会导致异常。建议添加基本的验证来确保值的有效性。
- uvicorn.run() 的 host 参数:在 uvicorn.run() 中使用 host 参数指定监听主机,但没有指定端口号。建议添加 port 参数来指定端口号,以确保服务器监听正确的端口。
改进后的代码示例:
import os
import uvicorn
from loguru import logger
from myapp.config import config # 假设 config 模块在 myapp.config 文件中
if __name__ == "__main__":
logger.info(
"start server, docs: http://127.0.0.1:" + str(config.listen_port) + "/docs"
)
if config.proxy and "http" in config.proxy and "https" in config.proxy:
os.environ["MY_APP_HTTP_PROXY"] = config.proxy["http"]
os.environ["MY_APP_HTTPS_PROXY"] = config.proxy["https"]
try:
uvicorn.run(
app="app.asgi:app",
host=config.listen_host,
port=config.listen_port,
)
except Exception as e:
logger.error(f"Server failed to start: {e}")
tiktoken==0.8.0 | ||
yt-dlp==2024.11.18 |
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.
这是一个 Python 项目的 requirements.txt
文件补丁。以下是对其进行的简略代码审查:
补丁修复了最后一行结尾缺少换行符的问题(\ No newline at end of file
),但同时引入了一个重复的 tiktoken==0.8.0
行。
改进建议:
- 删除重复的
tiktoken==0.8.0
行,避免不必要的重复依赖项。 - 确保
yt-dlp
的版本号为最新,避免因版本号过旧导致的问题。
修复后的补丁:
@@ -31,4 +31,5 @@ python-dotenv~=1.0.1
openai~=1.53.0
tqdm>=4.66.6
tenacity>=9.0.0
tiktoken==0.8.0
+yt-dlp==2024.11.18
注意:由于 yt-dlp
的版本号是动态的(包含日期),您可能需要考虑使用固定版本号或将其加入到一个版本控制系统中,避免因版本号变化导致的问题。
vision_llm_provider="gemini", | ||
voice_name="zh-CN-YunjianNeural", | ||
) | ||
print(result) |
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.
这个代码是 Python 脚本,用于管道处理视频相关的工作流程。下面是一些代码审查的建议和风险:
-
异常处理:在
run_pipeline
方法中,异常处理是非常简单的,如果异常发生,会直接返回错误信息。但是,可能需要更详细的异常处理机制,每个方法应该单独处理异常,并提供更详细的错误信息。 -
路径判断:在
run_pipeline
方法中,判断视频和脚本路径的逻辑可能需要优化。如果视频和脚本都不存在,应该提供更合理的处理方式。 -
脚本生成:在
generate_script
方法中,脚本生成的逻辑可能需要优化。如果脚本生成失败,应该提供更详细的错误信息。 -
视频剪辑:在
crop_video
方法中,视频剪辑的逻辑可能需要优化。如果视频剪辑失败,应该提供更详细的错误信息。 -
视频生成:在
generate_final_video
方法中,视频生成的逻辑可能需要优化。如果视频生成失败,应该提供更详细的错误信息。 -
线程安全:在
generate_final_video
方法中,使用线程数目(n_threads
)可能需要优化,确保线程安全。 -
请求超时:在使用
requests
库时,可能需要设置超时时间,以避免长时间等待。 -
错误信息:在异常处理中,错误信息可能需要优化,提供更详细的信息,以便于调试。
-
函数签名:函数签名可能需要优化,以便于理解函数的输入和输出信息。
-
注释:注释可能需要优化,以便于理解代码的逻辑和意图。
以下是代码修改建议:
- 使用
try/except
块来捕获异常,并提供详细的错误信息。 - 使用
logging
库来记录日志信息。 - 使用
time
库来记录函数执行时间。 - 使用
threading
库来优化线程安全。 - 使用
requests
库来设置超时时间。
import logging
import time
import threading
import requests
# 设置日志级别
logging.basicConfig(level=logging.INFO)
class VideoPipeline:
# ...
def run_pipeline(self, task_id: str, script_name: str, youtube_url: str, video_name: str="null", skip_seconds: int = 0, threshold: int = 30, vision_batch_size: int = 10, vision_llm_provider: str = "gemini", voice_name: str = "zh-CN-YunjianNeural") -> Dict[str, Any]:
try:
# 开始记录时间
start_time = time.time()
# ...
# 结束记录时间
end_time = time.time()
logging.info(f"总共花费了 {end_time - start_time} 秒")
return {
"status": "等待异步生成视频",
"path": os.path.join(current_path, "storage", "tasks", task_id)
}
except Exception as e:
# 使用 logging 记录错误信息
logging.error(f"出现了异常:{str(e)}")
return {
"status": "error",
"error": str(e)
}
def generate_script(self, video_path: str, skip_seconds: int = 0,
threshold: int = 30, vision_batch_size: int = 10,
vision_llm_provider: str = "gemini") -> Dict[str, Any]:
try:
# ...
response = requests.post(endpoint, json=payload, timeout=10) # 设置超时时间
response.raise_for_status()
return response.json()
except requests.exceptions.Timeout:
# 使用 logging 记录超时错误信息
logging.error("出现了超时异常")
raise
except Exception as e:
# 使用 logging 记录错误信息
logging.error(f"出现了异常:{str(e)}")
raise
@@ -20,7 +20,7 @@ def render_audio_panel(tr): | |||
def render_tts_settings(tr): | |||
"""渲染TTS(文本转语音)设置""" | |||
# 获取支持的语音列表 | |||
support_locales = ["zh-CN", "zh-HK", "zh-TW", "en-US"] | |||
support_locales = ["zh-CN"] | |||
voices = voice.get_all_azure_voices(filter_locals=support_locales) | |||
|
|||
# 创建友好的显示名称 |
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.
这段代码看起来是用于渲染文本转语音(TTS)设置的界面,它从指定的语言列表中获取所有的 Azure 声音。
**潜在的 bug 风险:
- 当前的实现仅支持“zh-CN”语言,如果其它语言的支持被意外删除,这可能会引起问题。
**改进建议:
- 将支持的语言列表放入一个常量文件或者配置文件中,这样可以方便地修改和维护支持的语言。
- 添加注释解释为什么只支持“zh-CN”语言,这样可以帮助未来的开发者理解代码的决策。
- 考虑添加错误处理机制,防止在获取 Azure 声音时出现异常。
- 使用更具描述性的变量名,例如
supported_languages
代替support_locales
。 - 使用更安全的方式获取 Azure 声音,例如使用 try-except 块来处理异常。
例如:
SUPPORTED_LANGUAGES = ["zh-CN"] # 可以放入常量文件或配置文件中
def render_tts_settings(tr):
"""渲染TTS(文本转语音)设置"""
# 获取支持的语音列表
voices = []
try:
voices = voice.get_all_azure_voices(filter_locals=SUPPORTED_LANGUAGES)
except Exception as e:
# 处理异常
print(f"获取 Azure 声音异常:{e}")
# 创建友好的显示名称
@@ -103,7 +103,6 @@ | |||
"Video Quality": "视频质量", | |||
"Custom prompt for LLM, leave empty to use default prompt": "自定义提示词,留空则使用默认提示词", | |||
"Proxy Settings": "代理设置", | |||
"Language": "界面语言", | |||
"HTTP_PROXY": "HTTP 代理", | |||
"HTTPs_PROXY": "HTTPS 代理", | |||
"Vision Model Settings": "视频分析模型设置", |
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.
以下是该代码更改的简要审查:
变更描述:删除了一个名为“Language”的键值对,键为“Language”,值为“界面语言”。
风险:
- 字典键值对删除后可能引起错误:如果其他地方使用了这个键值对,删除这个键值对可能会引起错误,特别是如果程序依赖于这个键值对来进行某些操作。
- 不必要的耦合:如果程序中的其他地方都使用了这个键值对,那么删除它可能会导致不必要的耦合,因为其他地方可能会使用不同的方式来进行语言设置。
改进建议:
- 确认是否依赖于该键值对:在删除这个键值对之前,确认程序的其他地方是否依赖于它。如果有依赖,最好保留这个键值对或重构程序以避免耦合。
- 考虑重构语言设置:如果程序的语言设置较复杂,考虑重构语言设置的实现,以避免不必要的耦合和错误。
- 添加注释或文档:在代码中添加注释或文档,以说明为什么删除了这个键值对,并且记录程序的语言设置实现,以便于未来的维护和更改。
PR 类型
请选择一个适当的标签(必选其一):
描述
相关 Issue
更改内容
测试
截图(如果适用)
检查清单
补充说明