refactor(entity): 优化视频变速和缩放效果处理

-将视频变速实现从 minterpolate 改为使用 setpts,避免 PTS 冲突问题
-简化缩放效果处理逻辑
This commit is contained in:
2025-09-12 18:01:41 +08:00
parent cf43f6379e
commit 0c7181911e

View File

@@ -271,39 +271,33 @@ class FfmpegTask(object):
if param == '':
param = "1"
if param != "1":
# 视频变速:使用minterpolate实现,避免PTS冲突
# 视频变速:使用fps实现,避免PTS冲突
effect_index += 1
speed_factor = 1.0 / float(param) # 慢放倍数转换为速度因子
filter_args.append(f"{video_output_str}minterpolate=fps=25*{speed_factor}:mi_mode=mci[v_eff{effect_index}]")
filter_args.append(f"{video_output_str}setpts={param}*PTS[v_eff{effect_index}]")
video_output_str = f"[v_eff{effect_index}]"
elif effect.startswith("zoom:"):
param = effect.split(":", 2)[1]
if param == '':
continue
_split = param.split(",")
if len(_split) < 3:
if len(_split) < 2:
continue
try:
start_time = float(_split[0])
zoom_factor = float(_split[1])
duration = float(_split[2])
if start_time < 0:
start_time = 0
if duration < 0:
duration = 0
if zoom_factor <= 0:
zoom_factor = 1
except (ValueError, IndexError):
start_time = 0
duration = 0
zoom_factor = 1
if zoom_factor == 1:
continue
effect_index += 1
# 获取缩放中心点(从pos_json或使用默认中心)
center_x = "iw/2"
center_y = "ih/2"
left_x = f"iw/(2*{zoom_factor})"
top_y = f"ih/(2*{zoom_factor})"
pos_json_str = self.ext_data.get('posJson', '{}')
try:
pos_json = json.loads(pos_json_str) if pos_json_str != '{}' else {}
@@ -319,23 +313,14 @@ class FfmpegTask(object):
center_x_ratio = (_f_x + _f_x2) / (2 * _v_w)
center_y_ratio = (_f_y + _f_y2) / (2 * _v_h)
# 转换为视频坐标系统
center_x = f"iw*{center_x_ratio:.6f}"
center_y = f"ih*{center_y_ratio:.6f}"
left_x = f"iw*({center_x_ratio:.6f}-1/(2*{zoom_factor}))"
top_y = f"ih*({center_y_ratio:.6f}-1/(2*{zoom_factor}))"
except Exception as e:
# 解析失败使用默认中心
pass
if duration == 0:
# 静态缩放(整个视频时长)
x_expr = f"({center_x})-(ow*zoom)/2"
y_expr = f"({center_y})-(oh*zoom)/2"
filter_args.append(f"{video_output_str}trim=start={start_time},zoompan=z={zoom_factor}:x={x_expr}:y={y_expr}:d=1[v_eff{effect_index}]")
else:
# 动态缩放(指定时间段内)
zoom_expr = f"if(between(t\\,{start_time}\\,{start_time + duration})\\,{zoom_factor}\\,1)"
x_expr = f"({center_x})-(ow*zoom)/2"
y_expr = f"({center_y})-(oh*zoom)/2"
filter_args.append(f"{video_output_str}zoompan=z={zoom_expr}:x={x_expr}:y={y_expr}:d=1[v_eff{effect_index}]")
# 静态缩放(整个视频时长)
filter_args.append(f"{video_output_str}scale={zoom_factor}*iw:{zoom_factor}*ih,crop=iw/{zoom_factor}:ih/{zoom_factor}:{left_x}:{top_y}[v_eff{effect_index}]")
video_output_str = f"[v_eff{effect_index}]"
elif effect.startswith("skip:"):
param = effect.split(":", 2)[1]