mirror of
https://github.com/linyqh/NarratoAI.git
synced 2025-12-12 19:52:48 +00:00
feat(webui): 新增短剧解说脚本生成功能
- 添加短剧解说模式,支持上传字幕文件 - 实现短剧解说脚本生成逻辑 -优化脚本设置界面布局,支持多种脚本类型 - 修复部分功能模块的引用错误
This commit is contained in:
parent
e66a5969f0
commit
048b2ff39a
@ -11,6 +11,7 @@ from app.models.schema import VideoClipParams
|
|||||||
from app.utils import utils, check_script
|
from app.utils import utils, check_script
|
||||||
from webui.tools.generate_script_docu import generate_script_docu
|
from webui.tools.generate_script_docu import generate_script_docu
|
||||||
from webui.tools.generate_script_short import generate_script_short
|
from webui.tools.generate_script_short import generate_script_short
|
||||||
|
from webui.tools.generate_short_summary import generate_script_short_sunmmary
|
||||||
|
|
||||||
|
|
||||||
def render_script_panel(tr):
|
def render_script_panel(tr):
|
||||||
@ -27,15 +28,20 @@ def render_script_panel(tr):
|
|||||||
|
|
||||||
# 获取当前选择的脚本类型
|
# 获取当前选择的脚本类型
|
||||||
script_path = st.session_state.get('video_clip_json_path', '')
|
script_path = st.session_state.get('video_clip_json_path', '')
|
||||||
|
|
||||||
# 根据脚本类型显示不同的布局
|
# 根据脚本类型显示不同的布局
|
||||||
if script_path == "short":
|
if script_path == "short":
|
||||||
# Short Generate模式下显示的内容
|
# 短剧混剪 模式下显示的内容
|
||||||
render_short_generate_options(tr)
|
render_short_generate_options(tr)
|
||||||
else:
|
elif script_path == "auto":
|
||||||
# 其他模式下保持原有布局
|
# 画面解说
|
||||||
# 渲染视频主题和提示词
|
|
||||||
render_video_details(tr)
|
render_video_details(tr)
|
||||||
|
elif script_path == "summary":
|
||||||
|
# 短剧解说
|
||||||
|
short_drama_summary(tr)
|
||||||
|
else:
|
||||||
|
# 默认为空
|
||||||
|
pass
|
||||||
|
|
||||||
# 渲染脚本操作按钮
|
# 渲染脚本操作按钮
|
||||||
render_script_buttons(tr, params)
|
render_script_buttons(tr, params)
|
||||||
@ -44,9 +50,10 @@ def render_script_panel(tr):
|
|||||||
def render_script_file(tr, params):
|
def render_script_file(tr, params):
|
||||||
"""渲染脚本文件选择"""
|
"""渲染脚本文件选择"""
|
||||||
script_list = [
|
script_list = [
|
||||||
(tr("None"), ""),
|
(tr("None"), ""),
|
||||||
(tr("Auto Generate"), "auto"),
|
(tr("Auto Generate"), "auto"),
|
||||||
(tr("Short Generate"), "short"),
|
(tr("Short Generate"), "short"),
|
||||||
|
(tr("Short Drama Summary"), "summary"),
|
||||||
(tr("Upload Script"), "upload_script")
|
(tr("Upload Script"), "upload_script")
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -100,11 +107,11 @@ def render_script_file(tr, params):
|
|||||||
# 读取上传的JSON内容并验证格式
|
# 读取上传的JSON内容并验证格式
|
||||||
script_content = uploaded_file.read().decode('utf-8')
|
script_content = uploaded_file.read().decode('utf-8')
|
||||||
json_data = json.loads(script_content)
|
json_data = json.loads(script_content)
|
||||||
|
|
||||||
# 保存到脚本目录
|
# 保存到脚本目录
|
||||||
script_file_path = os.path.join(script_dir, uploaded_file.name)
|
script_file_path = os.path.join(script_dir, uploaded_file.name)
|
||||||
file_name, file_extension = os.path.splitext(uploaded_file.name)
|
file_name, file_extension = os.path.splitext(uploaded_file.name)
|
||||||
|
|
||||||
# 如果文件已存在,添加时间戳
|
# 如果文件已存在,添加时间戳
|
||||||
if os.path.exists(script_file_path):
|
if os.path.exists(script_file_path):
|
||||||
timestamp = time.strftime("%Y%m%d%H%M%S")
|
timestamp = time.strftime("%Y%m%d%H%M%S")
|
||||||
@ -114,14 +121,14 @@ def render_script_file(tr, params):
|
|||||||
# 写入文件
|
# 写入文件
|
||||||
with open(script_file_path, "w", encoding='utf-8') as f:
|
with open(script_file_path, "w", encoding='utf-8') as f:
|
||||||
json.dump(json_data, f, ensure_ascii=False, indent=2)
|
json.dump(json_data, f, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
# 更新状态
|
# 更新状态
|
||||||
st.success(tr("Script Uploaded Successfully"))
|
st.success(tr("Script Uploaded Successfully"))
|
||||||
st.session_state['video_clip_json_path'] = script_file_path
|
st.session_state['video_clip_json_path'] = script_file_path
|
||||||
params.video_clip_json_path = script_file_path
|
params.video_clip_json_path = script_file_path
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
st.rerun()
|
st.rerun()
|
||||||
|
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
st.error(tr("Invalid JSON format"))
|
st.error(tr("Invalid JSON format"))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -193,7 +200,7 @@ def render_short_generate_options(tr):
|
|||||||
|
|
||||||
|
|
||||||
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"))
|
||||||
custom_prompt = st.text_area(
|
custom_prompt = st.text_area(
|
||||||
tr("Generation Prompt"),
|
tr("Generation Prompt"),
|
||||||
@ -201,44 +208,84 @@ def render_video_details(tr):
|
|||||||
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
|
||||||
)
|
)
|
||||||
|
# 非短视频模式下显示原有的三个输入框
|
||||||
|
input_cols = st.columns(2)
|
||||||
|
|
||||||
|
with input_cols[0]:
|
||||||
|
st.number_input(
|
||||||
|
tr("Frame Interval (seconds)"),
|
||||||
|
min_value=0,
|
||||||
|
value=st.session_state.get('frame_interval_input', config.frames.get('frame_interval_input', 3)),
|
||||||
|
help=tr("Frame Interval (seconds) (More keyframes consume more tokens)"),
|
||||||
|
key="frame_interval_input"
|
||||||
|
)
|
||||||
|
|
||||||
|
with input_cols[1]:
|
||||||
|
st.number_input(
|
||||||
|
tr("Batch Size"),
|
||||||
|
min_value=0,
|
||||||
|
value=st.session_state.get('vision_batch_size', config.frames.get('vision_batch_size', 10)),
|
||||||
|
help=tr("Batch Size (More keyframes consume more tokens)"),
|
||||||
|
key="vision_batch_size"
|
||||||
|
)
|
||||||
st.session_state['video_theme'] = video_theme
|
st.session_state['video_theme'] = video_theme
|
||||||
st.session_state['custom_prompt'] = custom_prompt
|
st.session_state['custom_prompt'] = custom_prompt
|
||||||
return video_theme, custom_prompt
|
return video_theme, custom_prompt
|
||||||
|
|
||||||
|
|
||||||
|
def short_drama_summary(tr):
|
||||||
|
"""短剧解说 渲染视频主题和提示词"""
|
||||||
|
subtitle_file = st.file_uploader(
|
||||||
|
tr("上传字幕文件"),
|
||||||
|
type=["srt"],
|
||||||
|
accept_multiple_files=False,
|
||||||
|
)
|
||||||
|
if subtitle_file is not None:
|
||||||
|
try:
|
||||||
|
# 读取上传的JSON内容并验证格式
|
||||||
|
script_content = subtitle_file.read().decode('utf-8')
|
||||||
|
|
||||||
|
# 保存到脚本目录
|
||||||
|
script_file_path = os.path.join(utils.subtitle_dir(), subtitle_file.name)
|
||||||
|
file_name, file_extension = os.path.splitext(subtitle_file.name)
|
||||||
|
|
||||||
|
# 如果文件已存在,添加时间戳
|
||||||
|
if os.path.exists(script_file_path):
|
||||||
|
timestamp = time.strftime("%Y%m%d%H%M%S")
|
||||||
|
file_name_with_timestamp = f"{file_name}_{timestamp}"
|
||||||
|
script_file_path = os.path.join(utils.subtitle_dir(), file_name_with_timestamp + file_extension)
|
||||||
|
|
||||||
|
# 写入文件
|
||||||
|
with open(script_file_path, "w", encoding='utf-8') as f:
|
||||||
|
json.dump(script_content, f, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
|
# 更新状态
|
||||||
|
st.success(tr("字幕上传成功"))
|
||||||
|
st.session_state['subtitle_path'] = script_file_path
|
||||||
|
time.sleep(0.1)
|
||||||
|
st.rerun()
|
||||||
|
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
st.error(tr("Invalid JSON format"))
|
||||||
|
except Exception as e:
|
||||||
|
st.error(f"{tr('Upload failed')}: {str(e)}")
|
||||||
|
video_theme = st.text_input(tr("短剧名称"))
|
||||||
|
st.session_state['video_theme'] = video_theme
|
||||||
|
return video_theme
|
||||||
|
|
||||||
|
|
||||||
def render_script_buttons(tr, params):
|
def render_script_buttons(tr, params):
|
||||||
"""渲染脚本操作按钮"""
|
"""渲染脚本操作按钮"""
|
||||||
# 获取当前选择的脚本类型
|
# 获取当前选择的脚本类型
|
||||||
script_path = st.session_state.get('video_clip_json_path', '')
|
script_path = st.session_state.get('video_clip_json_path', '')
|
||||||
|
|
||||||
# 根据脚本类型显示不同的设置
|
|
||||||
if script_path != "short":
|
|
||||||
# 非短视频模式下显示原有的三个输入框
|
|
||||||
input_cols = st.columns(2)
|
|
||||||
|
|
||||||
with input_cols[0]:
|
|
||||||
st.number_input(
|
|
||||||
tr("Frame Interval (seconds)"),
|
|
||||||
min_value=0,
|
|
||||||
value=st.session_state.get('frame_interval_input', config.frames.get('frame_interval_input', 3)),
|
|
||||||
help=tr("Frame Interval (seconds) (More keyframes consume more tokens)"),
|
|
||||||
key="frame_interval_input"
|
|
||||||
)
|
|
||||||
|
|
||||||
with input_cols[1]:
|
|
||||||
st.number_input(
|
|
||||||
tr("Batch Size"),
|
|
||||||
min_value=0,
|
|
||||||
value=st.session_state.get('vision_batch_size', config.frames.get('vision_batch_size', 10)),
|
|
||||||
help=tr("Batch Size (More keyframes consume more tokens)"),
|
|
||||||
key="vision_batch_size"
|
|
||||||
)
|
|
||||||
|
|
||||||
# 生成/加载按钮
|
# 生成/加载按钮
|
||||||
if script_path == "auto":
|
if script_path == "auto":
|
||||||
button_name = tr("Generate Video Script")
|
button_name = tr("Generate Video Script")
|
||||||
elif script_path == "short":
|
elif script_path == "short":
|
||||||
button_name = tr("Generate Short Video Script")
|
button_name = tr("Generate Short Video Script")
|
||||||
|
elif script_path == "summary":
|
||||||
|
button_name = tr("生成短剧解说脚本")
|
||||||
elif script_path.endswith("json"):
|
elif script_path.endswith("json"):
|
||||||
button_name = tr("Load Video Script")
|
button_name = tr("Load Video Script")
|
||||||
else:
|
else:
|
||||||
@ -250,9 +297,13 @@ def render_script_buttons(tr, params):
|
|||||||
generate_script_docu(params)
|
generate_script_docu(params)
|
||||||
elif script_path == "short":
|
elif script_path == "short":
|
||||||
# 获取自定义片段数量参数
|
# 获取自定义片段数量参数
|
||||||
custom_clips = st.session_state.get('custom_clips', 5)
|
custom_clips = st.session_state.get('custom_clips')
|
||||||
# 直接将custom_clips作为参数传递,而不是通过params对象
|
# 直接将custom_clips作为参数传递,而不是通过params对象
|
||||||
generate_script_short(tr, params, custom_clips)
|
generate_script_short(tr, params, custom_clips)
|
||||||
|
elif script_path == "summary":
|
||||||
|
# 执行短剧解说脚本生成
|
||||||
|
subtitle_path = st.session_state.get('subtitle_path')
|
||||||
|
generate_script_short_sunmmary(params, subtitle_path)
|
||||||
else:
|
else:
|
||||||
load_script(tr, script_path)
|
load_script(tr, script_path)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user