You've already forked FrameTour-RenderWorker
refactor
This commit is contained in:
@@ -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"
|
||||
Reference in New Issue
Block a user