diff --git a/app/services/task.py b/app/services/task.py index 5ac0c13..018d149 100644 --- a/app/services/task.py +++ b/app/services/task.py @@ -15,147 +15,147 @@ from app.services import state as sm from app.utils import utils -def generate_script(task_id, params): - logger.info("\n\n## generating video script") - video_script = params.video_script.strip() - if not video_script: - video_script = llm.generate_script( - video_subject=params.video_subject, - language=params.video_language, - paragraph_number=params.paragraph_number, - ) - else: - logger.debug(f"video script: \n{video_script}") +# def generate_script(task_id, params): +# logger.info("\n\n## generating video script") +# video_script = params.video_script.strip() +# if not video_script: +# video_script = llm.generate_script( +# video_subject=params.video_subject, +# language=params.video_language, +# paragraph_number=params.paragraph_number, +# ) +# else: +# logger.debug(f"video script: \n{video_script}") - if not video_script: - sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) - logger.error("failed to generate video script.") - return None +# if not video_script: +# sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) +# logger.error("failed to generate video script.") +# return None - return video_script +# return video_script -def generate_terms(task_id, params, video_script): - logger.info("\n\n## generating video terms") - video_terms = params.video_terms - if not video_terms: - video_terms = llm.generate_terms( - video_subject=params.video_subject, video_script=video_script, amount=5 - ) - else: - if isinstance(video_terms, str): - video_terms = [term.strip() for term in re.split(r"[,,]", video_terms)] - elif isinstance(video_terms, list): - video_terms = [term.strip() for term in video_terms] - else: - raise ValueError("video_terms must be a string or a list of strings.") +# def generate_terms(task_id, params, video_script): +# logger.info("\n\n## generating video terms") +# video_terms = params.video_terms +# if not video_terms: +# video_terms = llm.generate_terms( +# video_subject=params.video_subject, video_script=video_script, amount=5 +# ) +# else: +# if isinstance(video_terms, str): +# video_terms = [term.strip() for term in re.split(r"[,,]", video_terms)] +# elif isinstance(video_terms, list): +# video_terms = [term.strip() for term in video_terms] +# else: +# 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: - sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) - logger.error("failed to generate video terms.") - return None +# if not video_terms: +# sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) +# logger.error("failed to generate video terms.") +# return None - return video_terms +# return video_terms -def save_script_data(task_id, video_script, video_terms, params): - script_file = path.join(utils.task_dir(task_id), "script.json") - script_data = { - "script": video_script, - "search_terms": video_terms, - "params": params, - } +# def save_script_data(task_id, video_script, video_terms, params): +# script_file = path.join(utils.task_dir(task_id), "script.json") +# script_data = { +# "script": video_script, +# "search_terms": video_terms, +# "params": params, +# } - with open(script_file, "w", encoding="utf-8") as f: - f.write(utils.to_json(script_data)) +# with open(script_file, "w", encoding="utf-8") as f: +# f.write(utils.to_json(script_data)) -def generate_audio(task_id, params, video_script): - logger.info("\n\n## generating audio") - audio_file = path.join(utils.task_dir(task_id), "audio.mp3") - sub_maker = voice.tts( - text=video_script, - voice_name=voice.parse_voice_name(params.voice_name), - voice_rate=params.voice_rate, - voice_file=audio_file, - ) - if sub_maker is None: - sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) - logger.error( - """failed to generate audio: -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. - """.strip() - ) - return None, None, None +# def generate_audio(task_id, params, video_script): +# logger.info("\n\n## generating audio") +# audio_file = path.join(utils.task_dir(task_id), "audio.mp3") +# sub_maker = voice.tts( +# text=video_script, +# voice_name=voice.parse_voice_name(params.voice_name), +# voice_rate=params.voice_rate, +# voice_file=audio_file, +# ) +# if sub_maker is None: +# sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) +# logger.error( +# """failed to generate audio: +# 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. +# """.strip() +# ) +# return None, None, None - audio_duration = math.ceil(voice.get_audio_duration(sub_maker)) - return audio_file, audio_duration, sub_maker +# audio_duration = math.ceil(voice.get_audio_duration(sub_maker)) +# return audio_file, audio_duration, sub_maker -def generate_subtitle(task_id, params, video_script, sub_maker, audio_file): - if not params.subtitle_enabled: - return "" +# def generate_subtitle(task_id, params, video_script, sub_maker, audio_file): +# if not params.subtitle_enabled: +# return "" - subtitle_path = path.join(utils.task_dir(task_id), "subtitle111.srt") - subtitle_provider = config.app.get("subtitle_provider", "").strip().lower() - logger.info(f"\n\n## generating subtitle, provider: {subtitle_provider}") +# subtitle_path = path.join(utils.task_dir(task_id), "subtitle111.srt") +# subtitle_provider = config.app.get("subtitle_provider", "").strip().lower() +# logger.info(f"\n\n## generating subtitle, provider: {subtitle_provider}") - subtitle_fallback = False - if subtitle_provider == "edge": - voice.create_subtitle( - text=video_script, sub_maker=sub_maker, subtitle_file=subtitle_path - ) - if not os.path.exists(subtitle_path): - subtitle_fallback = True - logger.warning("subtitle file not found, fallback to whisper") +# subtitle_fallback = False +# if subtitle_provider == "edge": +# voice.create_subtitle( +# text=video_script, sub_maker=sub_maker, subtitle_file=subtitle_path +# ) +# if not os.path.exists(subtitle_path): +# subtitle_fallback = True +# logger.warning("subtitle file not found, fallback to whisper") - if subtitle_provider == "whisper" or subtitle_fallback: - subtitle.create(audio_file=audio_file, subtitle_file=subtitle_path) - logger.info("\n\n## correcting subtitle") - subtitle.correct(subtitle_file=subtitle_path, video_script=video_script) +# if subtitle_provider == "whisper" or subtitle_fallback: +# subtitle.create(audio_file=audio_file, subtitle_file=subtitle_path) +# logger.info("\n\n## correcting subtitle") +# subtitle.correct(subtitle_file=subtitle_path, video_script=video_script) - subtitle_lines = subtitle.file_to_subtitles(subtitle_path) - if not subtitle_lines: - logger.warning(f"subtitle file is invalid: {subtitle_path}") - return "" +# subtitle_lines = subtitle.file_to_subtitles(subtitle_path) +# if not subtitle_lines: +# logger.warning(f"subtitle file is invalid: {subtitle_path}") +# return "" - return subtitle_path +# return subtitle_path -def get_video_materials(task_id, params, video_terms, audio_duration): - if params.video_source == "local": - logger.info("\n\n## preprocess local materials") - materials = video.preprocess_video( - materials=params.video_materials, clip_duration=params.video_clip_duration - ) - if not materials: - sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) - logger.error( - "no valid materials found, please check the materials and try again." - ) - return None - return [material_info.url for material_info in materials] - else: - logger.info(f"\n\n## downloading videos from {params.video_source}") - downloaded_videos = material.download_videos( - task_id=task_id, - search_terms=video_terms, - source=params.video_source, - video_aspect=params.video_aspect, - video_contact_mode=params.video_concat_mode, - audio_duration=audio_duration * params.video_count, - max_clip_duration=params.video_clip_duration, - ) - if not downloaded_videos: - sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) - logger.error( - "failed to download videos, maybe the network is not available. if you are in China, please use a VPN." - ) - return None - return downloaded_videos +# def get_video_materials(task_id, params, video_terms, audio_duration): +# if params.video_source == "local": +# logger.info("\n\n## preprocess local materials") +# materials = video.preprocess_video( +# materials=params.video_materials, clip_duration=params.video_clip_duration +# ) +# if not materials: +# sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) +# logger.error( +# "no valid materials found, please check the materials and try again." +# ) +# return None +# return [material_info.url for material_info in materials] +# else: +# logger.info(f"\n\n## downloading videos from {params.video_source}") +# downloaded_videos = material.download_videos( +# task_id=task_id, +# search_terms=video_terms, +# source=params.video_source, +# video_aspect=params.video_aspect, +# video_contact_mode=params.video_concat_mode, +# audio_duration=audio_duration * params.video_count, +# max_clip_duration=params.video_clip_duration, +# ) +# if not downloaded_videos: +# sm.state.update_task(task_id, state=const.TASK_STATE_FAILED) +# logger.error( +# "failed to download videos, maybe the network is not available. if you are in China, please use a VPN." +# ) +# return None +# return downloaded_videos def start_subclip(task_id: str, params: VideoClipParams, subclip_path_videos: dict): diff --git a/requirements.txt b/requirements.txt index 9d26499..723fa43 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,38 +1,38 @@ -requests~=2.31.0 +requests~=2.32.0 moviepy==2.1.1 -faster-whisper~=1.0.1 -uvicorn~=0.27.1 -fastapi~=0.115.4 -tomli~=2.0.1 -streamlit~=1.40.0 +edge-tts==6.1.19 +streamlit~=1.45.0 + +openai~=1.77.0 +google-generativeai>=0.8.5 + 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 +httpx==0.27.2 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 redis==5.0.3 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 git-changelog~=2.5.2 watchdog==5.0.2 pydub==0.25.1 psutil>=5.9.0 -opencv-python~=4.10.0.84 scikit-learn~=1.5.2 -google-generativeai~=0.8.3 pillow==10.3.0 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 pysrt==1.1.2 -httpx==0.27.2 -transformers==4.47.0 -edge-tts==6.1.19 +transformers==4.50.0 + +# yt-dlp==2025.4.30 \ No newline at end of file diff --git a/webui/utils/merge_video.py b/webui/utils/merge_video.py index 65e13aa..6c8503c 100644 --- a/webui/utils/merge_video.py +++ b/webui/utils/merge_video.py @@ -1,7 +1,7 @@ """ 合并视频和字幕文件 """ -from moviepy.editor import VideoFileClip, concatenate_videoclips +from moviepy import VideoFileClip, concatenate_videoclips import pysrt import os