diff --git a/README.md b/README.md
index 7a829bf..17e6cbc 100644
--- a/README.md
+++ b/README.md
@@ -66,6 +66,9 @@
- [ ] 支持更多的语音合成服务商,比如 OpenAI TTS, Azure TTS
- [ ] 自动上传到YouTube平台
+## 交流讨论 💬
+
+
## 视频演示 📺
### 竖屏 9:16
@@ -102,8 +105,17 @@
+## 配置要求 📦
+- 建议最低 CPU 4核或以上,内存 8G 或以上,显卡非必须
+- Windows 10 或 MacOS 11.0 以上系统
+
## 安装部署 📥
+> 不想部署的可以直接下载安装包,解压直接使用
+- **Windows** 版本下载地址
+ - 百度网盘: https://pan.baidu.com/s/1BB3SGtAFTytzFLS5t2d8Gg?pwd=5bry
+
+### 前提条件
- 尽量不要使用 **中文路径**,避免出现一些无法预料的问题
- 请确保你的 **网络** 是正常的,VPN需要打开`全局流量`模式
@@ -375,14 +387,6 @@ pip install Pillow==8.4.0
- 可以提交 [issue](https://github.com/harry0703/MoneyPrinterTurbo/issues)
或者 [pull request](https://github.com/harry0703/MoneyPrinterTurbo/pulls)。
-- 也可以关注我的 **抖音** 或 **视频号**:`网旭哈瑞.AI`
- - 我会在上面发布一些 **使用教程** 和 **纯技术** 分享。
- - 如果有更新和优化,我也会在上面 **及时通知**。
- - 有问题也可以在上面 **留言**,我会 **尽快回复**。
-
-| 抖音 | | 视频号 |
-|:---------------------------------------:|:------------:|:-------------------------------------------:|
-|
| |
|
## 参考项目 📚
diff --git a/app/config/config.py b/app/config/config.py
index 2afcdd0..19d4a77 100644
--- a/app/config/config.py
+++ b/app/config/config.py
@@ -53,7 +53,7 @@ listen_port = _cfg.get("listen_port", 8080)
project_name = _cfg.get("project_name", "MoneyPrinterTurbo")
project_description = _cfg.get("project_description",
"https://github.com/harry0703/MoneyPrinterTurbo")
-project_version = _cfg.get("project_version", "1.0.1")
+project_version = _cfg.get("project_version", "1.1.0")
reload_debug = False
imagemagick_path = app.get("imagemagick_path", "")
diff --git a/app/services/llm.py b/app/services/llm.py
index fda371f..e622818 100644
--- a/app/services/llm.py
+++ b/app/services/llm.py
@@ -5,6 +5,8 @@ from typing import List
from loguru import logger
from openai import OpenAI
from openai import AzureOpenAI
+from openai.types.chat import ChatCompletion
+
from app.config import config
@@ -154,7 +156,15 @@ def _generate_response(prompt: str) -> str:
messages=[{"role": "user", "content": prompt}]
)
if response:
- content = response.choices[0].message.content
+ if isinstance(response, ChatCompletion):
+ content = response.choices[0].message.content
+ else:
+ raise Exception(
+ f"[{llm_provider}] returned an invalid response: \"{response}\", please check your network "
+ f"connection and try again.")
+ else:
+ raise Exception(
+ f"[{llm_provider}] returned an empty response, please check your network connection and try again.")
return content.replace("\n", "")
diff --git a/app/services/subtitle.py b/app/services/subtitle.py
index 5ea8028..d19ac59 100644
--- a/app/services/subtitle.py
+++ b/app/services/subtitle.py
@@ -1,4 +1,5 @@
import json
+import os.path
import re
from faster_whisper import WhisperModel
@@ -17,8 +18,13 @@ model = None
def create(audio_file, subtitle_file: str = ""):
global model
if not model:
- logger.info(f"loading model: {model_size}, device: {device}, compute_type: {compute_type}")
- model = WhisperModel(model_size_or_path=model_size,
+ model_path = f"{utils.root_dir()}/models/whisper-{model_size}"
+ model_bin_file = f"{model_path}/model.bin"
+ if not os.path.isdir(model_path) or not os.path.isfile(model_bin_file):
+ model_path = model_size
+
+ logger.info(f"loading model: {model_path}, device: {device}, compute_type: {compute_type}")
+ model = WhisperModel(model_size_or_path=model_path,
device=device,
compute_type=compute_type)
diff --git a/app/services/video.py b/app/services/video.py
index 6ada901..e05dc12 100644
--- a/app/services/video.py
+++ b/app/services/video.py
@@ -124,7 +124,7 @@ def wrap_text(text, max_width, font='Arial', fontsize=60):
width, height = get_text_size(text)
if width <= max_width:
- return text
+ return text, height
logger.warning(f"wrapping text, max_width: {max_width}, text_width: {width}, text: {text}")
@@ -149,8 +149,9 @@ def wrap_text(text, max_width, font='Arial', fontsize=60):
if processed:
_wrapped_lines_ = [line.strip() for line in _wrapped_lines_]
result = '\n'.join(_wrapped_lines_).strip()
+ height = len(_wrapped_lines_) * height
logger.warning(f"wrapped text: {result}")
- return result
+ return result, height
_wrapped_lines_ = []
chars = list(text)
@@ -165,8 +166,9 @@ def wrap_text(text, max_width, font='Arial', fontsize=60):
_txt_ = ''
_wrapped_lines_.append(_txt_)
result = '\n'.join(_wrapped_lines_).strip()
+ height = len(_wrapped_lines_) * height
logger.warning(f"wrapped text: {result}")
- return result
+ return result, height
def generate_video(video_path: str,
@@ -199,23 +201,15 @@ def generate_video(video_path: str,
logger.info(f"using font: {font_path}")
- if params.subtitle_position == "top":
- position_height = video_height * 0.1
- elif params.subtitle_position == "bottom":
- position_height = video_height * 0.9
- else:
- position_height = "center"
-
- def generator(txt, **kwargs):
+ def create_text_clip(subtitle_item):
+ phrase = subtitle_item[1]
max_width = video_width * 0.9
- # logger.debug(f"rendering text: {txt}")
- wrapped_txt = wrap_text(txt,
- max_width=max_width,
- font=font_path,
- fontsize=params.font_size
- ) # 调整max_width以适应你的视频
-
- clip = TextClip(
+ wrapped_txt, txt_height = wrap_text(phrase,
+ max_width=max_width,
+ font=font_path,
+ fontsize=params.font_size
+ )
+ _clip = TextClip(
wrapped_txt,
font=font_path,
fontsize=params.font_size,
@@ -225,15 +219,28 @@ def generate_video(video_path: str,
stroke_width=params.stroke_width,
print_cmd=False,
)
- return clip
+ duration = subtitle_item[0][1] - subtitle_item[0][0]
+ _clip = _clip.set_start(subtitle_item[0][0])
+ _clip = _clip.set_end(subtitle_item[0][1])
+ _clip = _clip.set_duration(duration)
+ if params.subtitle_position == "bottom":
+ _clip = _clip.set_position(('center', video_height * 0.95 - _clip.h))
+ elif params.subtitle_position == "top":
+ _clip = _clip.set_position(('center', video_height * 0.1))
+ else:
+ _clip = _clip.set_position(('center', 'center'))
+ return _clip
video_clip = VideoFileClip(video_path)
audio_clip = AudioFileClip(audio_path).volumex(params.voice_volume)
if subtitle_path and os.path.exists(subtitle_path):
- sub = SubtitlesClip(subtitles=subtitle_path, make_textclip=generator, encoding='utf-8')
- sub_clip = sub.set_position(lambda _t: ('center', position_height))
- video_clip = CompositeVideoClip([video_clip, sub_clip])
+ sub = SubtitlesClip(subtitles=subtitle_path, encoding='utf-8')
+ text_clips = []
+ for item in sub.subtitles:
+ clip = create_text_clip(subtitle_item=item)
+ text_clips.append(clip)
+ video_clip = CompositeVideoClip([video_clip, *text_clips])
bgm_file = get_bgm_file(bgm_type=params.bgm_type, bgm_file=params.bgm_file)
if bgm_file:
@@ -258,7 +265,7 @@ if __name__ == "__main__":
txt_zh = "测试长字段这是您的旅行技巧指南帮助您进行预算友好的冒险"
font = utils.resource_dir() + "/fonts/STHeitiMedium.ttc"
for txt in [txt_en, txt_zh]:
- t = wrap_text(text=txt, max_width=1000, font=font, fontsize=60)
+ t, h = wrap_text(text=txt, max_width=1000, font=font, fontsize=60)
print(t)
task_id = "aa563149-a7ea-49c2-b39f-8c32cc225baf"
diff --git a/docs/wechat-01.jpg b/docs/wechat-01.jpg
new file mode 100644
index 0000000..96add13
Binary files /dev/null and b/docs/wechat-01.jpg differ
diff --git a/webui/Main.py b/webui/Main.py
index 9631d39..6ff61cf 100644
--- a/webui/Main.py
+++ b/webui/Main.py
@@ -38,7 +38,7 @@ hide_streamlit_style = """
"""
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
-st.title("MoneyPrinterTurbo")
+st.title(f"MoneyPrinterTurbo v{config.project_version}")
font_dir = os.path.join(root_dir, "resource", "fonts")
song_dir = os.path.join(root_dir, "resource", "songs")
diff --git a/webui/i18n/de.json b/webui/i18n/de.json
index 63bd397..d68899b 100644
--- a/webui/i18n/de.json
+++ b/webui/i18n/de.json
@@ -58,6 +58,6 @@
"Model Name": "Model Name",
"Please Enter the LLM API Key": "Please Enter the **LLM API Key**",
"Please Enter the Pexels API Key": "Please Enter the **Pexels API Key**",
- "Get Help": "If you need help, or have any questions, you can join discord for help: https://harryai.cc/moneyprinterturbo"
+ "Get Help": "If you need help, or have any questions, you can join discord for help: https://harryai.cc"
}
}
\ No newline at end of file
diff --git a/webui/i18n/en.json b/webui/i18n/en.json
index f9458a9..5fca842 100644
--- a/webui/i18n/en.json
+++ b/webui/i18n/en.json
@@ -59,6 +59,6 @@
"Model Name": "Model Name",
"Please Enter the LLM API Key": "Please Enter the **LLM API Key**",
"Please Enter the Pexels API Key": "Please Enter the **Pexels API Key**",
- "Get Help": "If you need help, or have any questions, you can join discord for help: https://harryai.cc/moneyprinterturbo"
+ "Get Help": "If you need help, or have any questions, you can join discord for help: https://harryai.cc"
}
}
\ No newline at end of file
diff --git a/webui/i18n/zh.json b/webui/i18n/zh.json
index 7019c27..28f719d 100644
--- a/webui/i18n/zh.json
+++ b/webui/i18n/zh.json
@@ -59,6 +59,6 @@
"Model Name": "模型名称 (:blue[需要到大模型提供商的后台确认被授权的模型名称])",
"Please Enter the LLM API Key": "请先填写大模型 **API Key**",
"Please Enter the Pexels API Key": "请先填写 **Pexels API Key**",
- "Get Help": "有任何问题或建议,可以加入 **微信群** 求助或讨论:https://harryai.cc/moneyprinterturbo"
+ "Get Help": "有任何问题或建议,可以加入 **微信群** 求助或讨论:https://harryai.cc"
}
}
\ No newline at end of file