You've already forked FrameTour-RenderWorker
feat(video): 添加视频缩放特效功能支持
- 在 EffectConfig 中新增 zoom 特效类型及参数解析 - 实现 get_zoom_params 方法用于获取缩放效果参数 - 更新文档注释说明 zoom 特效使用格式示例 - 修改渲染逻辑支持 zoom 特效的 filter_complex 处理 - 添加缩放特效的视频滤镜构建实现 - 统一处理 cameraShot 和 zoom 特效的效果叠加逻辑
This commit is contained in:
@@ -491,7 +491,10 @@ class RenderSegmentVideoHandler(BaseHandler):
|
||||
|
||||
# 解析 effects
|
||||
effects = render_spec.get_effects()
|
||||
has_camera_shot = any(e.effect_type == 'cameraShot' for e in effects)
|
||||
has_complex_effect = any(
|
||||
effect.effect_type in {'cameraShot', 'zoom'}
|
||||
for effect in effects
|
||||
)
|
||||
|
||||
# 硬件加速时需要先 hwdownload(将 GPU 表面下载到系统内存)
|
||||
hwaccel_prefix = self.get_hwaccel_filter_prefix()
|
||||
@@ -541,9 +544,8 @@ class RenderSegmentVideoHandler(BaseHandler):
|
||||
)
|
||||
filters.append(scale_filter)
|
||||
|
||||
# 5. 特效处理(cameraShot 需要特殊处理)
|
||||
if has_camera_shot:
|
||||
# cameraShot 需要使用 filter_complex 格式
|
||||
# 5. 特效处理(cameraShot / zoom 需要使用 filter_complex)
|
||||
if has_complex_effect:
|
||||
return self._build_filter_complex_with_effects(
|
||||
base_filters=filters,
|
||||
effects=effects,
|
||||
@@ -624,7 +626,7 @@ class RenderSegmentVideoHandler(BaseHandler):
|
||||
"""
|
||||
构建包含特效的 filter_complex 滤镜图
|
||||
|
||||
cameraShot 效果需要使用 split/freezeframes/concat 滤镜组合。
|
||||
cameraShot / zoom 效果都在此处统一处理并按 effects 顺序叠加。
|
||||
|
||||
Args:
|
||||
base_filters: 基础滤镜列表
|
||||
@@ -695,6 +697,31 @@ class RenderSegmentVideoHandler(BaseHandler):
|
||||
f"{frozen_out}{rest_out}concat=n=2:v=1:a=0{effect_output}"
|
||||
)
|
||||
|
||||
current_output = effect_output
|
||||
effect_idx += 1
|
||||
elif effect.effect_type == 'zoom':
|
||||
start_sec, scale_factor, duration_sec = effect.get_zoom_params()
|
||||
if start_sec < 0 or scale_factor <= 1.0 or duration_sec <= 0:
|
||||
continue
|
||||
|
||||
zoom_end_sec = start_sec + duration_sec
|
||||
base_out = f'[eff{effect_idx}_base]'
|
||||
zoom_source_out = f'[eff{effect_idx}_zoom_src]'
|
||||
zoom_scaled_out = f'[eff{effect_idx}_zoom_scaled]'
|
||||
effect_output = f'[v_eff{effect_idx}]'
|
||||
zoom_enable = f"'between(t,{start_sec},{zoom_end_sec})'"
|
||||
|
||||
filter_parts.append(
|
||||
f"{current_output}split=2{base_out}{zoom_source_out}"
|
||||
)
|
||||
filter_parts.append(
|
||||
f"{zoom_source_out}scale=iw*{scale_factor}:ih*{scale_factor},"
|
||||
f"crop={width}:{height}:(in_w-{width})/2:(in_h-{height})/2{zoom_scaled_out}"
|
||||
)
|
||||
filter_parts.append(
|
||||
f"{base_out}{zoom_scaled_out}overlay=0:0:enable={zoom_enable}{effect_output}"
|
||||
)
|
||||
|
||||
current_output = effect_output
|
||||
effect_idx += 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user