This commit is contained in:
2025-09-24 04:51:12 +08:00
parent a54c157f9a
commit 6d37e7c23c
12 changed files with 548 additions and 101 deletions

View File

@@ -1,4 +1,3 @@
import json
import os
import time
from typing import List, Optional
@@ -8,6 +7,11 @@ from entity.render_task import RenderTask, TaskType
from entity.effects import registry as effect_registry
from util.exceptions import FFmpegError
from util.ffmpeg import probe_video_info, probe_video_audio
from util.ffmpeg_utils import (
build_base_ffmpeg_args, build_null_audio_input, build_amix_filter,
build_overlay_scale_filter, get_annexb_filter, build_standard_output_args
)
from util.json_utils import safe_json_loads
import logging
logger = logging.getLogger(__name__)
@@ -90,19 +94,15 @@ class FFmpegCommandBuilder:
def _build_encode_command(self) -> List[str]:
"""构建编码命令"""
args = ["ffmpeg", "-y", "-hide_banner"]
args = build_base_ffmpeg_args()
input_args = []
filter_args = []
output_args = [
*self.config.video_args,
*self.config.audio_args,
*self.config.encoder_args,
*self.config.default_args
]
output_args = build_standard_output_args()
# annexb处理
if self.task.annexb:
output_args.extend(["-bsf:v", self._get_mp4toannexb_filter()])
output_args.extend(["-bsf:v", get_annexb_filter()])
output_args.extend(["-reset_timestamps", "1"])
# 处理输入文件
@@ -158,10 +158,7 @@ class FFmpegCommandBuilder:
def _add_center_cut(self, filter_args: List[str], video_input: str, effect_index: int) -> tuple[str, int]:
"""添加中心裁剪"""
pos_json = self.task.ext_data.get('posJson', '{}')
try:
pos_data = json.loads(pos_json) if pos_json != '{}' else {}
except:
pos_data = {}
pos_data = safe_json_loads(pos_json, {})
_v_w = pos_data.get('imgWidth', 1)
_f_x = pos_data.get('ltX', 0)
@@ -179,10 +176,7 @@ class FFmpegCommandBuilder:
_w, _h = self.task.resolution.split('x', 1)
pos_json = self.task.ext_data.get('posJson', '{}')
try:
pos_data = json.loads(pos_json) if pos_json != '{}' else {}
except:
pos_data = {}
pos_data = safe_json_loads(pos_json, {})
_v_w = pos_data.get('imgWidth', 1)
_v_h = pos_data.get('imgHeight', 1)
@@ -224,10 +218,10 @@ class FFmpegCommandBuilder:
input_index = input_args.count("-i") // 2 # 每个输入占两个参数 -i filename
input_args.extend(["-i", overlay])
if self.config.old_ffmpeg:
filter_args.append(f"{current_input}[{input_index}:v]scale2ref=iw:ih[v]")
if self.config.overlay_scale_mode == "scale":
filter_args.append(f"{current_input}[{input_index}:v]scale=iw:ih[v]")
else:
filter_args.append(f"{current_input}[{input_index}:v]scale=rw:rh[v]")
filter_args.append(f"{current_input}[{input_index}:v]{self.config.overlay_scale_mode}=iw:ih[v]")
filter_args.append(f"[v][{input_index}:v]overlay=1:eof_action=endall[v]")
current_input = "[v]"
@@ -240,7 +234,7 @@ class FFmpegCommandBuilder:
if self.task.mute:
input_index = input_args.count("-i") // 2
input_args.extend(["-f", "lavfi", "-i", "anullsrc=cl=stereo:r=48000"])
input_args.extend(build_null_audio_input())
audio_output_str = f"[{input_index}:a]"
else:
audio_output_str = "[0:a]"
@@ -248,7 +242,7 @@ class FFmpegCommandBuilder:
for audio in self.task.audios:
input_index = input_args.count("-i") // 2
input_args.extend(["-i", audio.replace("\\", "/")])
filter_args.append(f"{audio_output_str}[{input_index}:a]amix=duration=shortest:dropout_transition=0:normalize=0[a]")
filter_args.append(f"{audio_output_str}[{input_index}:a]{self.config.amix_args[0]}[a]")
audio_output_str = "[a]"
return audio_output_str.strip("[]") if audio_output_str else None
@@ -268,14 +262,8 @@ class FFmpegCommandBuilder:
for audio in self.task.audios:
input_index = input_args.count("-i") // 2
input_args.extend(["-i", audio.replace("\\", "/")])
filter_args.append(f"{audio_output_str}[{input_index}:a]amix=duration=shortest:dropout_transition=0:normalize=0[a]")
filter_args.append(f"{audio_output_str}[{input_index}:a]{self.config.amix_args[0]}[a]")
audio_output_str = "[a]"
return audio_output_str if audio_output_str else None
def _get_mp4toannexb_filter(self) -> str:
"""获取mp4toannexb滤镜"""
encoder_args_str = " ".join(self.config.encoder_args).lower()
if "hevc" in encoder_args_str:
return "hevc_mp4toannexb"
return "h264_mp4toannexb"