feat(subtitle): 添加字幕自定义位置功能

- 在 generate_video.py 中实现自定义字幕位置的逻辑
- 在 schema.py 中添加 custom_position 字段
- 更新 webui 组件以支持自定义位置设置
- 调整任务处理逻辑,支持新的自定义位置参数
This commit is contained in:
linyq 2025-05-08 20:45:14 +08:00
parent b762bf8d93
commit fef3b3c8fd
4 changed files with 22 additions and 10 deletions

View File

@ -362,9 +362,10 @@ class VideoClipParams(BaseModel):
text_back_color: Optional[str] = None # 文本背景色
stroke_color: str = "black" # 描边颜色
stroke_width: float = 1.5 # 描边宽度
subtitle_position: str = "bottom" # top, bottom, center, custom
subtitle_position: str = "bottom" # top, bottom, center, custom
custom_position: float = 70.0 # 自定义位置
n_threads: Optional[int] = Field(default=16, description="解说语音音量") # 线程<E7BABF><E7A88B><EFBFBD>,有助于提升视频处理速度
n_threads: Optional[int] = Field(default=16, description="线程数") # 线程数,有助于提升视频处理速度
tts_volume: Optional[float] = Field(default=1.0, description="解说语音音量(后处理)")
original_volume: Optional[float] = Field(default=1.0, description="视频原声音量")

View File

@ -10,7 +10,7 @@
import os
import traceback
from typing import Optional, Dict, Any, Union
from typing import Optional, Dict, Any
from loguru import logger
from moviepy import (
VideoFileClip,
@ -18,7 +18,6 @@ from moviepy import (
CompositeAudioClip,
CompositeVideoClip,
TextClip,
concatenate_videoclips,
afx
)
from moviepy.video.tools.subtitles import SubtitlesClip
@ -54,6 +53,7 @@ def merge_materials(
- subtitle_color: 字幕颜色默认白色
- subtitle_bg_color: 字幕背景颜色默认透明
- subtitle_position: 字幕位置可选值'bottom', 'top', 'center'默认'bottom'
- custom_position: 自定义位置
- stroke_color: 描边颜色默认黑色
- stroke_width: 描边宽度默认1
- threads: 处理线程数默认2
@ -71,11 +71,12 @@ def merge_materials(
bgm_volume = options.get('bgm_volume', 0.3)
original_audio_volume = options.get('original_audio_volume', 0.0) # 默认为0即不保留原声
keep_original_audio = options.get('keep_original_audio', False) # 是否保留原声
subtitle_font = options.get('subtitle_font', None)
subtitle_font = options.get('subtitle_font', '')
subtitle_font_size = options.get('subtitle_font_size', 40)
subtitle_color = options.get('subtitle_color', '#FFFFFF')
subtitle_bg_color = options.get('subtitle_bg_color', 'transparent')
subtitle_position = options.get('subtitle_position', 'bottom')
custom_position = options.get('custom_position', 70)
stroke_color = options.get('stroke_color', '#000000')
stroke_width = options.get('stroke_width', 1)
threads = options.get('threads', 2)
@ -222,6 +223,15 @@ def merge_materials(
_clip = _clip.with_position(("center", video_height * 0.95 - _clip.h))
elif subtitle_position == "top":
_clip = _clip.with_position(("center", video_height * 0.05))
elif subtitle_position == "custom":
margin = 10
max_y = video_height - _clip.h - margin
min_y = margin
custom_y = (video_height - _clip.h) * (custom_position / 100)
custom_y = max(
min_y, min(custom_y, max_y)
)
_clip = _clip.with_position(("center", custom_y))
else: # center
_clip = _clip.with_position(("center", "center"))

View File

@ -306,8 +306,8 @@ def start_subclip(task_id: str, params: VideoClipParams, subclip_path_videos: di
output_video_path = path.join(utils.task_dir(task_id), f"combined.mp4")
logger.info(f"\n\n## 6. 最后一步: 合并字幕/BGM/配音/视频 -> {output_video_path}")
bgm_path = '/Users/apple/Desktop/home/NarratoAI/resource/songs/bgm.mp3'
# bgm_path = params.bgm_file
# bgm_path = '/Users/apple/Desktop/home/NarratoAI/resource/songs/bgm.mp3'
bgm_path = utils.get_bgm_file()
# 调用示例
options = {
@ -315,11 +315,12 @@ def start_subclip(task_id: str, params: VideoClipParams, subclip_path_videos: di
'bgm_volume': params.bgm_volume, # 背景音乐音量
'original_audio_volume': params.original_volume, # 视频原声音量0表示不保留
'keep_original_audio': True, # 是否保留原声
'subtitle_font': 'MicrosoftYaHeiNormal.ttc', # 这里使用相对字体路径,会自动在 font_dir() 目录下查找
'subtitle_font': params.font_name, # 这里使用相对字体路径,会自动在 font_dir() 目录下查找
'subtitle_font_size': params.font_size,
'subtitle_color': '#FFFFFF',
'subtitle_color': params.text_fore_color,
'subtitle_bg_color': None, # 直接使用None表示透明背景
'subtitle_position': params.subtitle_position,
'custom_position': params.custom_position,
'threads': params.n_threads
}
generate_video.merge_materials(

View File

@ -127,7 +127,7 @@ def get_subtitle_params():
'font_name': st.session_state.get('font_name', ''),
'font_size': st.session_state.get('font_size', 60),
'text_fore_color': st.session_state.get('text_fore_color', '#FFFFFF'),
'position': st.session_state.get('subtitle_position', 'bottom'),
'subtitle_position': st.session_state.get('subtitle_position', 'bottom'),
'custom_position': st.session_state.get('custom_position', 70.0),
'stroke_color': st.session_state.get('stroke_color', '#000000'),
'stroke_width': st.session_state.get('stroke_width', 1.5),