fix(format): black格式化 unified_render_service.py
This commit is contained in:
@@ -238,10 +238,15 @@ class UnifiedRenderService:
|
||||
else:
|
||||
# 回退到带滤镜的直通渲染
|
||||
pass_through_has_audio = self._render_pass_through(
|
||||
layers, output_path, ass_path=ass_path, video_duration=video_duration
|
||||
layers,
|
||||
output_path,
|
||||
ass_path=ass_path,
|
||||
video_duration=video_duration,
|
||||
)
|
||||
else:
|
||||
filter_complex, input_args = self._build_filter_complex(layers, ass_path=ass_path)
|
||||
filter_complex, input_args = self._build_filter_complex(
|
||||
layers, ass_path=ass_path
|
||||
)
|
||||
self._execute_ffmpeg(filter_complex, input_args, video_only_path)
|
||||
|
||||
t_video_end = time.time()
|
||||
@@ -326,7 +331,9 @@ class UnifiedRenderService:
|
||||
if not main_layer or not main_layer.clips:
|
||||
return 0.0
|
||||
|
||||
total = sum(UnifiedRenderService._clip_effective_duration(c) for c in main_layer.clips)
|
||||
total = sum(
|
||||
UnifiedRenderService._clip_effective_duration(c) for c in main_layer.clips
|
||||
)
|
||||
|
||||
# 减去转场重叠时间(粗略估算)
|
||||
n_clips = len(main_layer.clips)
|
||||
@@ -434,7 +441,10 @@ class UnifiedRenderService:
|
||||
return False, f"像素格式不是yuv420p: {info.get('pix_fmt', 'unknown')}"
|
||||
|
||||
# 分辨率必须一致
|
||||
if info.get("width", 0) != self.output_width or info.get("height", 0) != self.output_height:
|
||||
if (
|
||||
info.get("width", 0) != self.output_width
|
||||
or info.get("height", 0) != self.output_height
|
||||
):
|
||||
return False, (
|
||||
f"分辨率不匹配: "
|
||||
f"{info.get('width', 0)}x{info.get('height', 0)} "
|
||||
@@ -484,7 +494,9 @@ class UnifiedRenderService:
|
||||
role = layers[0].role
|
||||
|
||||
# 判断是否满足 copy 条件
|
||||
can_copy, reason = self._can_use_stream_copy(clip, ass_path=ass_path, video_duration=video_duration)
|
||||
can_copy, reason = self._can_use_stream_copy(
|
||||
clip, ass_path=ass_path, video_duration=video_duration
|
||||
)
|
||||
if not can_copy:
|
||||
logger.info(
|
||||
"[unified-render] stream_copy 跳过: plan_id=%s reason=%s",
|
||||
@@ -512,7 +524,9 @@ class UnifiedRenderService:
|
||||
|
||||
# 计算最终时长
|
||||
final_duration = effective_duration
|
||||
if video_duration > 0 and (final_duration <= 0 or final_duration > video_duration):
|
||||
if video_duration > 0 and (
|
||||
final_duration <= 0 or final_duration > video_duration
|
||||
):
|
||||
final_duration = video_duration
|
||||
if final_duration > 0:
|
||||
command.extend(["-t", f"{final_duration:.3f}"])
|
||||
@@ -549,7 +563,9 @@ class UnifiedRenderService:
|
||||
)
|
||||
return True
|
||||
else:
|
||||
logger.warning("[unified-render] stream_copy 输出为空: plan_id=%s", self.plan.id)
|
||||
logger.warning(
|
||||
"[unified-render] stream_copy 输出为空: plan_id=%s", self.plan.id
|
||||
)
|
||||
return False
|
||||
except (subprocess.CalledProcessError, subprocess.TimeoutExpired) as e:
|
||||
logger.warning(
|
||||
@@ -612,7 +628,10 @@ class UnifiedRenderService:
|
||||
filters.append(f"scale={pip_w}:{pip_h}")
|
||||
else:
|
||||
# main / broll / background: 铺满裁剪
|
||||
filters.append(f"scale={self.output_width}:{self.output_height}" ":force_original_aspect_ratio=increase")
|
||||
filters.append(
|
||||
f"scale={self.output_width}:{self.output_height}"
|
||||
":force_original_aspect_ratio=increase"
|
||||
)
|
||||
filters.append(f"crop={self.output_width}:{self.output_height}")
|
||||
|
||||
filters.append("setpts=PTS-STARTPTS")
|
||||
@@ -628,7 +647,9 @@ class UnifiedRenderService:
|
||||
|
||||
# 最终输出时长:取 clip 有效时长和 video_duration 的较小值
|
||||
final_duration = effective_duration
|
||||
if video_duration > 0 and (final_duration <= 0 or final_duration > video_duration):
|
||||
if video_duration > 0 and (
|
||||
final_duration <= 0 or final_duration > video_duration
|
||||
):
|
||||
final_duration = video_duration
|
||||
|
||||
command = [
|
||||
@@ -727,7 +748,9 @@ class UnifiedRenderService:
|
||||
resolved.sort(key=lambda c: c.order)
|
||||
return resolved
|
||||
|
||||
def _group_clips_into_layers(self, resolved_clips: list[ResolvedClip]) -> list[RenderLayer]:
|
||||
def _group_clips_into_layers(
|
||||
self, resolved_clips: list[ResolvedClip]
|
||||
) -> list[RenderLayer]:
|
||||
"""将 ResolvedClips 分组为 RenderLayers。
|
||||
|
||||
分组规则见 _resolve_layer_role 函数文档。
|
||||
@@ -817,14 +840,16 @@ class UnifiedRenderService:
|
||||
filters.append(f"scale={pip_w}:{pip_h}")
|
||||
elif role == "background":
|
||||
filters.append(
|
||||
f"scale={self.output_width}:{self.output_height}" ":force_original_aspect_ratio=increase"
|
||||
f"scale={self.output_width}:{self.output_height}"
|
||||
":force_original_aspect_ratio=increase"
|
||||
)
|
||||
filters.append(f"crop={self.output_width}:{self.output_height}")
|
||||
else:
|
||||
# main / broll: 铺满裁剪(scale to cover + center crop)
|
||||
# 对齐链路A编辑器合成行为,与主流短视频平台一致
|
||||
filters.append(
|
||||
f"scale={self.output_width}:{self.output_height}" ":force_original_aspect_ratio=increase"
|
||||
f"scale={self.output_width}:{self.output_height}"
|
||||
":force_original_aspect_ratio=increase"
|
||||
)
|
||||
filters.append(f"crop={self.output_width}:{self.output_height}")
|
||||
|
||||
@@ -841,8 +866,13 @@ class UnifiedRenderService:
|
||||
layer_clip_indices = [all_clips.index(c) for c in layer.clips]
|
||||
layer_labels = [preprocessed_labels[i] for i in layer_clip_indices]
|
||||
# 使用 trim 后的有效时长,与 Step 1 的 trim=duration 保持一致
|
||||
layer_durations = [UnifiedRenderService._clip_effective_duration(all_clips[i]) for i in layer_clip_indices]
|
||||
layer_transitions = [all_clips[i].transition_effect for i in layer_clip_indices]
|
||||
layer_durations = [
|
||||
UnifiedRenderService._clip_effective_duration(all_clips[i])
|
||||
for i in layer_clip_indices
|
||||
]
|
||||
layer_transitions = [
|
||||
all_clips[i].transition_effect for i in layer_clip_indices
|
||||
]
|
||||
|
||||
if len(layer_labels) == 1:
|
||||
# 单 clip 层,直接使用预处理标签
|
||||
@@ -873,7 +903,8 @@ class UnifiedRenderService:
|
||||
base_label = layer_output_labels[role]
|
||||
combined_label = f"combined_{role}"
|
||||
filter_parts.append(
|
||||
f"[{final_video_label}][{base_label}]" f"overlay=(W-w)/2:(H-h)/2[{combined_label}]"
|
||||
f"[{final_video_label}][{base_label}]"
|
||||
f"overlay=(W-w)/2:(H-h)/2[{combined_label}]"
|
||||
)
|
||||
final_video_label = combined_label
|
||||
else:
|
||||
@@ -898,13 +929,18 @@ class UnifiedRenderService:
|
||||
20,
|
||||
)
|
||||
combined_label = f"combined_{layer.role}"
|
||||
filter_parts.append(f"[{final_video_label}][{overlay_label}]" f"overlay={x}:{y}[{combined_label}]")
|
||||
filter_parts.append(
|
||||
f"[{final_video_label}][{overlay_label}]"
|
||||
f"overlay={x}:{y}[{combined_label}]"
|
||||
)
|
||||
final_video_label = combined_label
|
||||
|
||||
# 叠加字幕(如有)+ 最终像素格式
|
||||
if ass_path is not None:
|
||||
ass_filter_path = str(ass_path).replace("\\", "/").replace(":", "\\:")
|
||||
filter_parts.append(f"[{final_video_label}]subtitles='{ass_filter_path}',format=yuv420p[final_video]")
|
||||
filter_parts.append(
|
||||
f"[{final_video_label}]subtitles='{ass_filter_path}',format=yuv420p[final_video]"
|
||||
)
|
||||
else:
|
||||
filter_parts.append(f"[{final_video_label}]format=yuv420p[final_video]")
|
||||
|
||||
@@ -979,5 +1015,9 @@ class UnifiedRenderService:
|
||||
def _clip_effective_duration(clip: ResolvedClip) -> float:
|
||||
"""计算 clip 的有效时长."""
|
||||
if clip.duration > 0:
|
||||
return min(clip.duration, clip.actual_duration) if clip.actual_duration > 0 else clip.duration
|
||||
return (
|
||||
min(clip.duration, clip.actual_duration)
|
||||
if clip.actual_duration > 0
|
||||
else clip.duration
|
||||
)
|
||||
return clip.actual_duration if clip.actual_duration > 0 else 0.0
|
||||
|
||||
Reference in New Issue
Block a user