mirror of
https://github.com/linyqh/NarratoAI.git
synced 2025-12-14 13:02:50 +00:00
完成汉化和自定义提示词
This commit is contained in:
parent
49b52041ce
commit
072cfb9856
@ -247,17 +247,10 @@ class MoonshotGenerator(BaseGenerator):
|
|||||||
|
|
||||||
|
|
||||||
class ScriptProcessor:
|
class ScriptProcessor:
|
||||||
def __init__(self, model_name, api_key=None, prompt=None):
|
def __init__(self, model_name: str, api_key: str = None, prompt: str = None, video_theme: str = ""):
|
||||||
self.model_name = model_name
|
self.model_name = model_name
|
||||||
# 根据不同模型选择对应的环境变量
|
self.api_key = api_key
|
||||||
default_api_key = {
|
self.video_theme = video_theme
|
||||||
'gemini': 'GOOGLE_API_KEY',
|
|
||||||
'gpt': 'OPENAI_API_KEY',
|
|
||||||
'qwen': 'DASHSCOPE_API_KEY',
|
|
||||||
'moonshot': 'MOONSHOT_API_KEY'
|
|
||||||
}
|
|
||||||
api_key_env = next((v for k, v in default_api_key.items() if k in model_name.lower()), 'OPENAI_API_KEY')
|
|
||||||
self.api_key = api_key or os.getenv(api_key_env)
|
|
||||||
self.prompt = prompt or self._get_default_prompt()
|
self.prompt = prompt or self._get_default_prompt()
|
||||||
|
|
||||||
# 根据模型名称选择对应的生成器
|
# 根据模型名称选择对应的生成器
|
||||||
@ -271,11 +264,11 @@ class ScriptProcessor:
|
|||||||
self.generator = OpenAIGenerator(model_name, self.api_key, self.prompt)
|
self.generator = OpenAIGenerator(model_name, self.api_key, self.prompt)
|
||||||
|
|
||||||
def _get_default_prompt(self) -> str:
|
def _get_default_prompt(self) -> str:
|
||||||
return """你是一位极具幽默感的短视频脚本创作大师,擅长用"温和的违反"制造笑点,让野外建造视频既有趣又富有传播力。你的任务是将视频画面描述转化为能在社交平台疯狂传播的爆款口播文案。
|
return f"""你是一位极具幽默感的短视频脚本创作大师,擅长用"温和的违反"制造笑点,让{self.video_theme}视频既有趣又富有传播力。你的任务是将视频画面描述转化为能在社交平台疯狂传播的爆款口播文案。
|
||||||
|
|
||||||
目标受众:热爱野外生活、追求独特体验的18-35岁年轻人
|
目标受众:热爱生活、追求独特体验的18-35岁年轻人
|
||||||
文案风格:基于HKRR理论 + 段子手精神
|
文案风格:基于HKRR理论 + 段子手精神
|
||||||
主题:野外建造
|
主题:{self.video_theme}
|
||||||
|
|
||||||
【创作核心理念】
|
【创作核心理念】
|
||||||
1. 敢于用"温和的违反"制造笑点,但不能过于冒犯
|
1. 敢于用"温和的违反"制造笑点,但不能过于冒犯
|
||||||
@ -300,7 +293,7 @@ class ScriptProcessor:
|
|||||||
3. 用接地气的表达方式拉近与观众距离
|
3. 用接地气的表达方式拉近与观众距离
|
||||||
|
|
||||||
【节奏控制 Rhythm】
|
【节奏控制 Rhythm】
|
||||||
1. 严格控制文案字数在{word_count}字左右,允许误差不超过5字
|
1. 严格控制文案字数在{self.word_count}字左右,允许误差不超过5字
|
||||||
2. 像讲段子一样,注意铺垫和包袱的节奏
|
2. 像讲段子一样,注意铺垫和包袱的节奏
|
||||||
3. 确保每段都有笑点,但不强求
|
3. 确保每段都有笑点,但不强求
|
||||||
4. 段落结尾干净利落,不拖泥带水
|
4. 段落结尾干净利落,不拖泥带水
|
||||||
@ -313,7 +306,7 @@ class ScriptProcessor:
|
|||||||
5. 确保情节和建造过程的逻辑连续性
|
5. 确保情节和建造过程的逻辑连续性
|
||||||
|
|
||||||
【字数控制要求】
|
【字数控制要求】
|
||||||
1. 严格控制文案字数在{word_count}字左右,允许误差不超过5字
|
1. 严格控制文案字数在{self.word_count}字左右,允许误差不超过5字
|
||||||
2. 如果内容过长,优先精简修饰性词语
|
2. 如果内容过长,优先精简修饰性词语
|
||||||
3. 如果内容过短,可以适当增加细节描写
|
3. 如果内容过短,可以适当增加细节描写
|
||||||
4. 保持文案结构完整,不因字数限制而牺牲内容质量
|
4. 保持文案结构完整,不因字数限制而牺牲内容质量
|
||||||
|
|||||||
@ -24,6 +24,8 @@ def render_basic_settings(tr):
|
|||||||
|
|
||||||
|
|
||||||
def render_language_settings(tr):
|
def render_language_settings(tr):
|
||||||
|
st.subheader(tr("Proxy Settings"))
|
||||||
|
|
||||||
"""渲染语言设置"""
|
"""渲染语言设置"""
|
||||||
system_locale = utils.get_system_locale()
|
system_locale = utils.get_system_locale()
|
||||||
i18n_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "i18n")
|
i18n_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "i18n")
|
||||||
|
|||||||
@ -127,15 +127,15 @@ def render_video_file(tr, params):
|
|||||||
def render_video_details(tr):
|
def render_video_details(tr):
|
||||||
"""渲染视频主题和提示词"""
|
"""渲染视频主题和提示词"""
|
||||||
video_theme = st.text_input(tr("Video Theme"))
|
video_theme = st.text_input(tr("Video Theme"))
|
||||||
prompt = st.text_area(
|
custom_prompt = st.text_area(
|
||||||
tr("Generation Prompt"),
|
tr("Generation Prompt"),
|
||||||
value=st.session_state.get('video_plot', ''),
|
value=st.session_state.get('video_plot', ''),
|
||||||
help=tr("Custom prompt for LLM, leave empty to use default prompt"),
|
help=tr("Custom prompt for LLM, leave empty to use default prompt"),
|
||||||
height=180
|
height=180
|
||||||
)
|
)
|
||||||
st.session_state['video_name'] = video_theme
|
st.session_state['video_theme'] = video_theme
|
||||||
st.session_state['video_plot'] = prompt
|
st.session_state['custom_prompt'] = custom_prompt
|
||||||
return video_theme, prompt
|
return video_theme, custom_prompt
|
||||||
|
|
||||||
|
|
||||||
def render_script_buttons(tr, params):
|
def render_script_buttons(tr, params):
|
||||||
@ -368,17 +368,10 @@ def generate_script(tr, params):
|
|||||||
|
|
||||||
update_progress(70, "正在生成脚本...")
|
update_progress(70, "正在生成脚本...")
|
||||||
|
|
||||||
# 构建完整的上下文
|
|
||||||
context = {
|
|
||||||
'video_name': st.session_state.get('video_name', ''),
|
|
||||||
'video_plot': st.session_state.get('video_plot', ''),
|
|
||||||
'frame_analysis': frame_analysis,
|
|
||||||
'total_frames': len(keyframe_files)
|
|
||||||
}
|
|
||||||
# 从配置中获取文本生成相关配置
|
# 从配置中获取文本生成相关配置
|
||||||
text_provider = config.app.get('text_llm_provider', 'gemini').lower()
|
text_provider = config.app.get('text_llm_provider', 'gemini').lower()
|
||||||
text_api_key = config.app.get(f'text_{text_provider}_api_key')
|
text_api_key = config.app.get(f'text_{text_provider}_api_key')
|
||||||
text_model = config.app.get(f'text_{text_provider}_model_name', 'gemini-1.5-pro')
|
text_model = config.app.get(f'text_{text_provider}_model_name')
|
||||||
text_base_url = config.app.get(f'text_{text_provider}_base_url')
|
text_base_url = config.app.get(f'text_{text_provider}_base_url')
|
||||||
|
|
||||||
# 构建帧内容列表
|
# 构建帧内容列表
|
||||||
@ -426,12 +419,16 @@ def generate_script(tr, params):
|
|||||||
if not frame_content_list:
|
if not frame_content_list:
|
||||||
raise Exception("没有有效的帧内容可以处理")
|
raise Exception("没有有效的帧内容可以处理")
|
||||||
|
|
||||||
|
# ===================开始生成文案===================
|
||||||
|
update_progress(90, "正在生成文案...")
|
||||||
# 使用 ScriptProcessor 生成脚本
|
# 使用 ScriptProcessor 生成脚本
|
||||||
from app.utils.script_generator import ScriptProcessor
|
from app.utils.script_generator import ScriptProcessor
|
||||||
|
custom_prompt = st.session_state.get('custom_prompt', '')
|
||||||
processor = ScriptProcessor(
|
processor = ScriptProcessor(
|
||||||
model_name=text_model,
|
model_name=text_model,
|
||||||
api_key=text_api_key,
|
api_key=text_api_key,
|
||||||
prompt="" # 使用默认提示词
|
prompt=custom_prompt,
|
||||||
|
video_theme=st.session_state.get('video_theme', '')
|
||||||
)
|
)
|
||||||
|
|
||||||
# 处理帧内容生成脚本
|
# 处理帧内容生成脚本
|
||||||
@ -476,11 +473,11 @@ def generate_script(tr, params):
|
|||||||
'vision_api_key': st.session_state.get('narrato_vision_key'),
|
'vision_api_key': st.session_state.get('narrato_vision_key'),
|
||||||
'llm_model': st.session_state.get('narrato_llm_model', 'qwen-plus'),
|
'llm_model': st.session_state.get('narrato_llm_model', 'qwen-plus'),
|
||||||
'llm_api_key': st.session_state.get('narrato_llm_key'),
|
'llm_api_key': st.session_state.get('narrato_llm_key'),
|
||||||
'custom_prompt': st.session_state.get('video_plot', '')
|
'custom_prompt': st.session_state.get('custom_prompt', '')
|
||||||
}
|
}
|
||||||
|
|
||||||
# 发送API请求
|
# 发送API请求
|
||||||
logger.info(f"请求 NarratoAPI:{api_url}")
|
logger.info(f"请求NarratoAPI: {api_url}")
|
||||||
update_progress(40, "正在上传文件...")
|
update_progress(40, "正在上传文件...")
|
||||||
with open(zip_path, 'rb') as f:
|
with open(zip_path, 'rb') as f:
|
||||||
files = {'file': (os.path.basename(zip_path), f, 'application/x-zip-compressed')}
|
files = {'file': (os.path.basename(zip_path), f, 'application/x-zip-compressed')}
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
"Crop Video": "裁剪视频",
|
"Crop Video": "裁剪视频",
|
||||||
"Video File": "视频文件(:blue[1️⃣支持上传视频文件(限制2G) 2️⃣大文件建议直接导入 ./resource/videos 目录])",
|
"Video File": "视频文件(:blue[1️⃣支持上传视频文件(限制2G) 2️⃣大文件建议直接导入 ./resource/videos 目录])",
|
||||||
"Plot Description": "剧情描述 (:blue[可从 https://www.tvmao.com/ 获取])",
|
"Plot Description": "剧情描述 (:blue[可从 https://www.tvmao.com/ 获取])",
|
||||||
"Generate Video Keywords": "点击使用AI根据**文案**生成【视频关键词】",
|
"Generate Video Keywords": "点击使用AI根据**文案**生成【视频关键<EFBFBD><EFBFBD>】",
|
||||||
"Please Enter the Video Subject": "请先填写视频文案",
|
"Please Enter the Video Subject": "请先填写视频文案",
|
||||||
"Generating Video Script and Keywords": "AI正在生成视频文案和关键词...",
|
"Generating Video Script and Keywords": "AI正在生成视频文案和关键词...",
|
||||||
"Generating Video Keywords": "AI正在生成视频关键词...",
|
"Generating Video Keywords": "AI正在生成视频关键词...",
|
||||||
@ -97,12 +97,34 @@
|
|||||||
"Check Format": "脚本格式检查",
|
"Check Format": "脚本格式检查",
|
||||||
"Script Loaded Successfully": "脚本加载成功",
|
"Script Loaded Successfully": "脚本加载成功",
|
||||||
"Script format check passed": "脚本格式检查通过",
|
"Script format check passed": "脚本格式检查通过",
|
||||||
"Script format check failed": "脚本格式检查失败",
|
"Script format check failed": "脚本格式检查失<EFBFBD><EFBFBD>",
|
||||||
"Failed to Load Script": "加载脚本失败",
|
"Failed to Load Script": "加载脚本失败",
|
||||||
"Failed to Save Script": "保存脚本失败",
|
"Failed to Save Script": "保存脚本失败",
|
||||||
"Script saved successfully": "脚本保存成功",
|
"Script saved successfully": "脚本保存成功",
|
||||||
"Video Script": "视频脚本",
|
"Video Script": "视频脚本",
|
||||||
"Video Quality": "视频质量",
|
"Video Quality": "视频质量",
|
||||||
"Custom prompt for LLM, leave empty to use default prompt": "自定义提示词,留空则使用默认提示词"
|
"Custom prompt for LLM, leave empty to use default prompt": "自定义提示词,留空则使用默认提示词",
|
||||||
|
"Basic Settings": "基础设置",
|
||||||
|
"Proxy Settings": "代理设置",
|
||||||
|
"Language": "界面语言",
|
||||||
|
"HTTP_PROXY": "HTTP 代理",
|
||||||
|
"HTTPs_PROXY": "HTTPS 代理",
|
||||||
|
"Vision Model Settings": "视频分析模型设置",
|
||||||
|
"Vision Model Provider": "视频分析模型提供商",
|
||||||
|
"Vision API Key": "视频分析 API 密钥",
|
||||||
|
"Vision Base URL": "视频分析接口地址",
|
||||||
|
"Vision Model Name": "视频分析模型名称",
|
||||||
|
"Narrato Additional Settings": "Narrato 附加设置",
|
||||||
|
"Narrato API Key": "Narrato API 密钥",
|
||||||
|
"Narrato API URL": "Narrato API 地址",
|
||||||
|
"Text Generation Model Settings": "文案生成模型设置",
|
||||||
|
"LLM Model Name": "大语言模型名称",
|
||||||
|
"LLM Model API Key": "大语言模型 API 密钥",
|
||||||
|
"Batch Size": "批处理大小",
|
||||||
|
"Text Model Provider": "文案生成模型提供商",
|
||||||
|
"Text API Key": "文案生成 API 密钥",
|
||||||
|
"Text Base URL": "文案生成接口地址",
|
||||||
|
"Text Model Name": "文案生成模型名称",
|
||||||
|
"Account ID": "账户 ID"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user