You've already forked FrameTour-RenderWorker
feat(重构): 实现新的渲染服务架构
- 新增 RenderTask
This commit is contained in:
79
entity/effects/camera_shot.py
Normal file
79
entity/effects/camera_shot.py
Normal file
@@ -0,0 +1,79 @@
|
||||
from typing import List, Dict, Any
|
||||
from .base import EffectProcessor
|
||||
|
||||
class CameraShotEffect(EffectProcessor):
|
||||
"""相机镜头效果处理器"""
|
||||
|
||||
def validate_params(self) -> bool:
|
||||
"""验证参数:start_time,duration,rotate_deg"""
|
||||
params = self.parse_params()
|
||||
if not params:
|
||||
return True # 使用默认参数
|
||||
|
||||
# 参数格式: "start_time,duration,rotate_deg"
|
||||
if len(params) > 3:
|
||||
return False
|
||||
|
||||
try:
|
||||
for i, param in enumerate(params):
|
||||
if param == '':
|
||||
continue
|
||||
if i == 2: # rotate_deg
|
||||
int(param)
|
||||
else: # start_time, duration
|
||||
float(param)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def generate_filter_args(self, video_input: str, effect_index: int) -> tuple[List[str], str]:
|
||||
"""生成相机镜头效果的滤镜参数"""
|
||||
if not self.validate_params():
|
||||
return [], video_input
|
||||
|
||||
params = self.parse_params()
|
||||
|
||||
# 设置默认值
|
||||
start = 3.0
|
||||
duration = 1.0
|
||||
rotate_deg = 0
|
||||
|
||||
if len(params) >= 1 and params[0] != '':
|
||||
start = float(params[0])
|
||||
if len(params) >= 2 and params[1] != '':
|
||||
duration = float(params[1])
|
||||
if len(params) >= 3 and params[2] != '':
|
||||
rotate_deg = int(params[2])
|
||||
|
||||
filter_args = []
|
||||
|
||||
# 生成输出流标识符
|
||||
start_out_str = "[eff_s]"
|
||||
mid_out_str = "[eff_m]"
|
||||
end_out_str = "[eff_e]"
|
||||
final_output = f"[v_eff{effect_index}]"
|
||||
|
||||
# 分割视频流为三部分
|
||||
filter_args.append(f"{video_input}split=3{start_out_str}{mid_out_str}{end_out_str}")
|
||||
|
||||
# 选择开始部分帧
|
||||
filter_args.append(f"{start_out_str}select=lt(n\\,{int(start * self.frame_rate)}){start_out_str}")
|
||||
|
||||
# 选择结束部分帧
|
||||
filter_args.append(f"{end_out_str}select=gt(n\\,{int(start * self.frame_rate)}){end_out_str}")
|
||||
|
||||
# 选择中间特定帧并扩展
|
||||
filter_args.append(f"{mid_out_str}select=eq(n\\,{int(start * self.frame_rate)}){mid_out_str}")
|
||||
filter_args.append(f"{mid_out_str}tpad=start_mode=clone:start_duration={duration:.4f}{mid_out_str}")
|
||||
|
||||
# 如果需要旋转
|
||||
if rotate_deg != 0:
|
||||
filter_args.append(f"{mid_out_str}rotate=PI*{rotate_deg}/180{mid_out_str}")
|
||||
|
||||
# 连接三部分
|
||||
filter_args.append(f"{start_out_str}{mid_out_str}{end_out_str}concat=n=3:v=1:a=0,setpts=N/{self.frame_rate}/TB{final_output}")
|
||||
|
||||
return filter_args, final_output
|
||||
|
||||
def get_effect_name(self) -> str:
|
||||
return "cameraShot"
|
Reference in New Issue
Block a user