diff --git a/entity/ffmpeg.py b/entity/ffmpeg.py index 796d20c..399e964 100644 --- a/entity/ffmpeg.py +++ b/entity/ffmpeg.py @@ -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]