114 lines
4.1 KiB
Python
114 lines
4.1 KiB
Python
from os import path
|
|
|
|
from loguru import logger
|
|
|
|
from app.config import config
|
|
from app.models.schema import VideoParams, VoiceNames
|
|
from app.services import gpt, material, voice, video, subtitle
|
|
from app.utils import utils
|
|
|
|
|
|
def _parse_voice(name: str):
|
|
# "female-zh-CN-XiaoxiaoNeural",
|
|
# remove first part split by "-"
|
|
if name not in VoiceNames:
|
|
name = VoiceNames[0]
|
|
|
|
parts = name.split("-")
|
|
_lang = f"{parts[1]}-{parts[2]}"
|
|
_voice = f"{_lang}-{parts[3]}"
|
|
|
|
return _voice, _lang
|
|
|
|
|
|
def start(task_id, params: VideoParams):
|
|
"""
|
|
{
|
|
"video_subject": "",
|
|
"video_aspect": "横屏 16:9(西瓜视频)",
|
|
"voice_name": "女生-晓晓",
|
|
"enable_bgm": false,
|
|
"font_name": "STHeitiMedium 黑体-中",
|
|
"text_color": "#FFFFFF",
|
|
"font_size": 60,
|
|
"stroke_color": "#000000",
|
|
"stroke_width": 1.5
|
|
}
|
|
"""
|
|
logger.info(f"start task: {task_id}")
|
|
video_subject = params.video_subject
|
|
voice_name, language = _parse_voice(params.voice_name)
|
|
paragraph_number = params.paragraph_number
|
|
n_threads = params.n_threads
|
|
|
|
logger.info("\n\n## generating video script")
|
|
script = gpt.generate_script(video_subject=video_subject, language=language, paragraph_number=paragraph_number)
|
|
|
|
logger.info("\n\n## generating video terms")
|
|
search_terms = gpt.generate_terms(video_subject=video_subject, video_script=script, amount=5)
|
|
|
|
script_file = path.join(utils.task_dir(task_id), f"script.json")
|
|
script_data = {
|
|
"script": script,
|
|
"search_terms": search_terms
|
|
}
|
|
|
|
with open(script_file, "w") as f:
|
|
f.write(utils.to_json(script_data))
|
|
|
|
audio_file = path.join(utils.task_dir(task_id), f"audio.mp3")
|
|
subtitle_path = path.join(utils.task_dir(task_id), f"subtitle.srt")
|
|
|
|
logger.info("\n\n## generating audio")
|
|
sub_maker = voice.tts(text=script, voice_name=voice_name, voice_file=audio_file)
|
|
|
|
subtitle_provider = config.app.get("subtitle_provider", "").strip().lower()
|
|
logger.info(f"\n\n## generating subtitle, provider: {subtitle_provider}")
|
|
if subtitle_provider == "edge":
|
|
voice.create_subtitle(text=script, sub_maker=sub_maker, subtitle_file=subtitle_path)
|
|
if subtitle_provider == "whisper":
|
|
subtitle.create(audio_file=audio_file, subtitle_file=subtitle_path)
|
|
logger.info("\n\n## correcting subtitle")
|
|
subtitle.correct(subtitle_file=subtitle_path, video_script=script)
|
|
|
|
logger.info("\n\n## downloading videos")
|
|
video_paths = material.download_videos(task_id=task_id, search_terms=search_terms, video_aspect=params.video_aspect,
|
|
wanted_count=20,
|
|
minimum_duration=5)
|
|
|
|
logger.info("\n\n## combining videos")
|
|
combined_video_path = path.join(utils.task_dir(task_id), f"combined.mp4")
|
|
video.combine_videos(combined_video_path=combined_video_path,
|
|
video_paths=video_paths,
|
|
audio_file=audio_file,
|
|
video_aspect=params.video_aspect,
|
|
max_clip_duration=5,
|
|
threads=n_threads)
|
|
|
|
final_video_path = path.join(utils.task_dir(task_id), f"final.mp4")
|
|
|
|
bgm_file = video.get_bgm_file(bgm_name=params.bgm_name)
|
|
logger.info("\n\n## generating video")
|
|
# Put everything together
|
|
video.generate_video(video_path=combined_video_path,
|
|
audio_path=audio_file,
|
|
subtitle_path=subtitle_path,
|
|
output_file=final_video_path,
|
|
|
|
video_aspect=params.video_aspect,
|
|
|
|
threads=n_threads,
|
|
|
|
font_name=params.font_name,
|
|
fontsize=params.font_size,
|
|
text_fore_color=params.text_fore_color,
|
|
stroke_color=params.stroke_color,
|
|
stroke_width=params.stroke_width,
|
|
|
|
bgm_file=bgm_file
|
|
)
|
|
logger.start(f"task {task_id} finished")
|
|
return {
|
|
"video_file": final_video_path,
|
|
}
|