build: 更新依赖并重构部分代码

- 更新 moviepy 依赖版本
- 添加 edge-tts、streamlit 等新依赖
- 移除 g4f、dashscope 等未使用的依赖- 重构 merge_video.py 中的导入语句
- 注释掉 task.py 中的多个函数定义
This commit is contained in:
linyq 2025-05-07 13:52:18 +08:00
parent 3d9b4b6d93
commit c3ea0bcc69
3 changed files with 139 additions and 139 deletions

View File

@ -15,147 +15,147 @@ from app.services import state as sm
from app.utils import utils from app.utils import utils
def generate_script(task_id, params): # def generate_script(task_id, params):
logger.info("\n\n## generating video script") # logger.info("\n\n## generating video script")
video_script = params.video_script.strip() # video_script = params.video_script.strip()
if not video_script: # if not video_script:
video_script = llm.generate_script( # video_script = llm.generate_script(
video_subject=params.video_subject, # video_subject=params.video_subject,
language=params.video_language, # language=params.video_language,
paragraph_number=params.paragraph_number, # paragraph_number=params.paragraph_number,
) # )
else: # else:
logger.debug(f"video script: \n{video_script}") # logger.debug(f"video script: \n{video_script}")
if not video_script: # if not video_script:
sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) # sm.state.update_task(task_id, state=const.TASK_STATE_FAILED)
logger.error("failed to generate video script.") # logger.error("failed to generate video script.")
return None # return None
return video_script # return video_script
def generate_terms(task_id, params, video_script): # def generate_terms(task_id, params, video_script):
logger.info("\n\n## generating video terms") # logger.info("\n\n## generating video terms")
video_terms = params.video_terms # video_terms = params.video_terms
if not video_terms: # if not video_terms:
video_terms = llm.generate_terms( # video_terms = llm.generate_terms(
video_subject=params.video_subject, video_script=video_script, amount=5 # video_subject=params.video_subject, video_script=video_script, amount=5
) # )
else: # else:
if isinstance(video_terms, str): # if isinstance(video_terms, str):
video_terms = [term.strip() for term in re.split(r"[,]", video_terms)] # video_terms = [term.strip() for term in re.split(r"[,]", video_terms)]
elif isinstance(video_terms, list): # elif isinstance(video_terms, list):
video_terms = [term.strip() for term in video_terms] # video_terms = [term.strip() for term in video_terms]
else: # else:
raise ValueError("video_terms must be a string or a list of strings.") # raise ValueError("video_terms must be a string or a list of strings.")
logger.debug(f"video terms: {utils.to_json(video_terms)}") # logger.debug(f"video terms: {utils.to_json(video_terms)}")
if not video_terms: # if not video_terms:
sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) # sm.state.update_task(task_id, state=const.TASK_STATE_FAILED)
logger.error("failed to generate video terms.") # logger.error("failed to generate video terms.")
return None # return None
return video_terms # return video_terms
def save_script_data(task_id, video_script, video_terms, params): # def save_script_data(task_id, video_script, video_terms, params):
script_file = path.join(utils.task_dir(task_id), "script.json") # script_file = path.join(utils.task_dir(task_id), "script.json")
script_data = { # script_data = {
"script": video_script, # "script": video_script,
"search_terms": video_terms, # "search_terms": video_terms,
"params": params, # "params": params,
} # }
with open(script_file, "w", encoding="utf-8") as f: # with open(script_file, "w", encoding="utf-8") as f:
f.write(utils.to_json(script_data)) # f.write(utils.to_json(script_data))
def generate_audio(task_id, params, video_script): # def generate_audio(task_id, params, video_script):
logger.info("\n\n## generating audio") # logger.info("\n\n## generating audio")
audio_file = path.join(utils.task_dir(task_id), "audio.mp3") # audio_file = path.join(utils.task_dir(task_id), "audio.mp3")
sub_maker = voice.tts( # sub_maker = voice.tts(
text=video_script, # text=video_script,
voice_name=voice.parse_voice_name(params.voice_name), # voice_name=voice.parse_voice_name(params.voice_name),
voice_rate=params.voice_rate, # voice_rate=params.voice_rate,
voice_file=audio_file, # voice_file=audio_file,
) # )
if sub_maker is None: # if sub_maker is None:
sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) # sm.state.update_task(task_id, state=const.TASK_STATE_FAILED)
logger.error( # logger.error(
"""failed to generate audio: # """failed to generate audio:
1. check if the language of the voice matches the language of the video script. # 1. check if the language of the voice matches the language of the video script.
2. check if the network is available. If you are in China, it is recommended to use a VPN and enable the global traffic mode. # 2. check if the network is available. If you are in China, it is recommended to use a VPN and enable the global traffic mode.
""".strip() # """.strip()
) # )
return None, None, None # return None, None, None
audio_duration = math.ceil(voice.get_audio_duration(sub_maker)) # audio_duration = math.ceil(voice.get_audio_duration(sub_maker))
return audio_file, audio_duration, sub_maker # return audio_file, audio_duration, sub_maker
def generate_subtitle(task_id, params, video_script, sub_maker, audio_file): # def generate_subtitle(task_id, params, video_script, sub_maker, audio_file):
if not params.subtitle_enabled: # if not params.subtitle_enabled:
return "" # return ""
subtitle_path = path.join(utils.task_dir(task_id), "subtitle111.srt") # subtitle_path = path.join(utils.task_dir(task_id), "subtitle111.srt")
subtitle_provider = config.app.get("subtitle_provider", "").strip().lower() # subtitle_provider = config.app.get("subtitle_provider", "").strip().lower()
logger.info(f"\n\n## generating subtitle, provider: {subtitle_provider}") # logger.info(f"\n\n## generating subtitle, provider: {subtitle_provider}")
subtitle_fallback = False # subtitle_fallback = False
if subtitle_provider == "edge": # if subtitle_provider == "edge":
voice.create_subtitle( # voice.create_subtitle(
text=video_script, sub_maker=sub_maker, subtitle_file=subtitle_path # text=video_script, sub_maker=sub_maker, subtitle_file=subtitle_path
) # )
if not os.path.exists(subtitle_path): # if not os.path.exists(subtitle_path):
subtitle_fallback = True # subtitle_fallback = True
logger.warning("subtitle file not found, fallback to whisper") # logger.warning("subtitle file not found, fallback to whisper")
if subtitle_provider == "whisper" or subtitle_fallback: # if subtitle_provider == "whisper" or subtitle_fallback:
subtitle.create(audio_file=audio_file, subtitle_file=subtitle_path) # subtitle.create(audio_file=audio_file, subtitle_file=subtitle_path)
logger.info("\n\n## correcting subtitle") # logger.info("\n\n## correcting subtitle")
subtitle.correct(subtitle_file=subtitle_path, video_script=video_script) # subtitle.correct(subtitle_file=subtitle_path, video_script=video_script)
subtitle_lines = subtitle.file_to_subtitles(subtitle_path) # subtitle_lines = subtitle.file_to_subtitles(subtitle_path)
if not subtitle_lines: # if not subtitle_lines:
logger.warning(f"subtitle file is invalid: {subtitle_path}") # logger.warning(f"subtitle file is invalid: {subtitle_path}")
return "" # return ""
return subtitle_path # return subtitle_path
def get_video_materials(task_id, params, video_terms, audio_duration): # def get_video_materials(task_id, params, video_terms, audio_duration):
if params.video_source == "local": # if params.video_source == "local":
logger.info("\n\n## preprocess local materials") # logger.info("\n\n## preprocess local materials")
materials = video.preprocess_video( # materials = video.preprocess_video(
materials=params.video_materials, clip_duration=params.video_clip_duration # materials=params.video_materials, clip_duration=params.video_clip_duration
) # )
if not materials: # if not materials:
sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) # sm.state.update_task(task_id, state=const.TASK_STATE_FAILED)
logger.error( # logger.error(
"no valid materials found, please check the materials and try again." # "no valid materials found, please check the materials and try again."
) # )
return None # return None
return [material_info.url for material_info in materials] # return [material_info.url for material_info in materials]
else: # else:
logger.info(f"\n\n## downloading videos from {params.video_source}") # logger.info(f"\n\n## downloading videos from {params.video_source}")
downloaded_videos = material.download_videos( # downloaded_videos = material.download_videos(
task_id=task_id, # task_id=task_id,
search_terms=video_terms, # search_terms=video_terms,
source=params.video_source, # source=params.video_source,
video_aspect=params.video_aspect, # video_aspect=params.video_aspect,
video_contact_mode=params.video_concat_mode, # video_contact_mode=params.video_concat_mode,
audio_duration=audio_duration * params.video_count, # audio_duration=audio_duration * params.video_count,
max_clip_duration=params.video_clip_duration, # max_clip_duration=params.video_clip_duration,
) # )
if not downloaded_videos: # if not downloaded_videos:
sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) # sm.state.update_task(task_id, state=const.TASK_STATE_FAILED)
logger.error( # logger.error(
"failed to download videos, maybe the network is not available. if you are in China, please use a VPN." # "failed to download videos, maybe the network is not available. if you are in China, please use a VPN."
) # )
return None # return None
return downloaded_videos # return downloaded_videos
def start_subclip(task_id: str, params: VideoClipParams, subclip_path_videos: dict): def start_subclip(task_id: str, params: VideoClipParams, subclip_path_videos: dict):

View File

@ -1,38 +1,38 @@
requests~=2.31.0 requests~=2.32.0
moviepy==2.1.1 moviepy==2.1.1
faster-whisper~=1.0.1 edge-tts==6.1.19
uvicorn~=0.27.1 streamlit~=1.45.0
fastapi~=0.115.4
tomli~=2.0.1 openai~=1.77.0
streamlit~=1.40.0 google-generativeai>=0.8.5
loguru~=0.7.2 loguru~=0.7.2
fastapi~=0.115.4
uvicorn~=0.27.1
pydantic~=2.11.4
faster-whisper~=1.0.1
tomli~=2.0.1
aiohttp~=3.10.10 aiohttp~=3.10.10
httpx==0.27.2
urllib3~=2.2.1 urllib3~=2.2.1
pydantic~=2.6.3
g4f~=0.3.0.4
dashscope~=1.15.0
google.generativeai>=0.8.3
python-multipart~=0.0.9 python-multipart~=0.0.9
redis==5.0.3 redis==5.0.3
opencv-python~=4.10.0.84 opencv-python~=4.10.0.84
# for azure speech
# https://techcommunity.microsoft.com/t5/ai-azure-ai-services-blog/9-more-realistic-ai-voices-for-conversations-now-generally/ba-p/4099471
azure-cognitiveservices-speech~=1.37.0 azure-cognitiveservices-speech~=1.37.0
git-changelog~=2.5.2 git-changelog~=2.5.2
watchdog==5.0.2 watchdog==5.0.2
pydub==0.25.1 pydub==0.25.1
psutil>=5.9.0 psutil>=5.9.0
opencv-python~=4.10.0.84
scikit-learn~=1.5.2 scikit-learn~=1.5.2
google-generativeai~=0.8.3
pillow==10.3.0 pillow==10.3.0
python-dotenv~=1.0.1 python-dotenv~=1.0.1
openai~=1.53.0
tqdm>=4.66.6 tqdm>=4.66.6
tenacity>=9.0.0 tenacity>=9.0.0
tiktoken==0.8.0 tiktoken==0.8.0
yt-dlp==2024.11.18
pysrt==1.1.2 pysrt==1.1.2
httpx==0.27.2 transformers==4.50.0
transformers==4.47.0
edge-tts==6.1.19 # yt-dlp==2025.4.30

View File

@ -1,7 +1,7 @@
""" """
合并视频和字幕文件 合并视频和字幕文件
""" """
from moviepy.editor import VideoFileClip, concatenate_videoclips from moviepy import VideoFileClip, concatenate_videoclips
import pysrt import pysrt
import os import os