diff --git a/entity/ffmpeg.py b/entity/ffmpeg.py index 51a9c53..3e864a0 100644 --- a/entity/ffmpeg.py +++ b/entity/ffmpeg.py @@ -299,11 +299,42 @@ class FfmpegTask(object): if zoom_factor == 1: continue effect_index += 1 + + # 获取缩放中心点(从pos_json或使用默认中心) + center_x = "iw/2" + center_y = "ih/2" + pos_json_str = self.ext_data.get('posJson', '{}') + try: + pos_json = json.loads(pos_json_str) if pos_json_str != '{}' else {} + if pos_json: + _f_x = pos_json.get('ltX', 0) + _f_x2 = pos_json.get('rbX', 0) + _f_y = pos_json.get('ltY', 0) + _f_y2 = pos_json.get('rbY', 0) + _v_w = pos_json.get('imgWidth', 1) + _v_h = pos_json.get('imgHeight', 1) + if _v_w > 0 and _v_h > 0: + # 计算坐标系统中的中心点 + 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}" + except Exception as e: + # 解析失败使用默认中心 + pass + if duration == 0: - filter_args.append(f"{video_output_str}trim=start={start_time},scale=iw*{zoom_factor}:ih*{zoom_factor},crop=iw/{zoom_factor}:ih/{zoom_factor}:(iw-iw/{zoom_factor})/2:(ih-ih/{zoom_factor})/2,setpts=PTS-STARTPTS[v_eff{effect_index}]") + # 静态缩放(整个视频时长) + 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)" - filter_args.append(f"{video_output_str}scale=iw*({zoom_expr}):ih*({zoom_expr}),crop=iw:ih:(iw-iw)/2:(ih-ih)/2[v_eff{effect_index}]") + # 动态缩放(指定时间段内) + 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}]") video_output_str = f"[v_eff{effect_index}]" elif effect.startswith("skip:"): param = effect.split(":", 2)[1] @@ -312,7 +343,7 @@ class FfmpegTask(object): skip_seconds = float(param) if skip_seconds > 0: effect_index += 1 - filter_args.append(f"{video_output_str}trim=start={skip_seconds},setpts=PTS-STARTPTS[v_eff{effect_index}]") + filter_args.append(f"{video_output_str}trim=start={skip_seconds}[v_eff{effect_index}]") video_output_str = f"[v_eff{effect_index}]" elif effect.startswith("tail:"): param = effect.split(":", 2)[1] @@ -324,7 +355,7 @@ class FfmpegTask(object): # 首先获取视频总时长,然后计算开始时间 # 使用reverse+trim+reverse的方法来精确获取最后N秒 filter_args.append(f"{video_output_str}reverse[v_rev{effect_index}]") - filter_args.append(f"[v_rev{effect_index}]trim=duration={tail_seconds},setpts=PTS-STARTPTS[v_trim{effect_index}]") + filter_args.append(f"[v_rev{effect_index}]trim=duration={tail_seconds}[v_trim{effect_index}]") filter_args.append(f"[v_trim{effect_index}]reverse[v_eff{effect_index}]") video_output_str = f"[v_eff{effect_index}]" ...