feat(video): 添加视频编码最大码率限制功能

- 在 get_video_encode_args 函数中新增 maxrate 参数用于限制峰值码率
- 实现 CRF/CQ 模式下同时控制质量和峰值码率的功能
- 自动计算 bufsize 为 maxrate 的 2 倍值
- 更新 VideoHandler 类中的编码参数方法以传递码率限制
- 修改视频合成和渲染模块以应用输出规格中的码率设置
- 移除静态 VIDEO_ENCODE_ARGS 常量以支持动态参数生成
This commit is contained in:
2026-03-04 10:03:33 +08:00
parent 34e7d84d52
commit ca90336905
3 changed files with 23 additions and 10 deletions

View File

@@ -42,19 +42,21 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def get_video_encode_args(hw_accel: str = HW_ACCEL_NONE) -> List[str]: def get_video_encode_args(hw_accel: str = HW_ACCEL_NONE, maxrate: Optional[int] = None) -> List[str]:
""" """
根据硬件加速配置获取视频编码参数 根据硬件加速配置获取视频编码参数
Args: Args:
hw_accel: 硬件加速类型 (none, qsv, cuda) hw_accel: 硬件加速类型 (none, qsv, cuda)
maxrate: 最大码率(bps),用于限制 CRF/CQ 模式的峰值码率。
例如 4000000 表示 4Mbps。bufsize 自动设为 maxrate 的 2 倍。
Returns: Returns:
FFmpeg 视频编码参数列表 FFmpeg 视频编码参数列表
""" """
if hw_accel == HW_ACCEL_QSV: if hw_accel == HW_ACCEL_QSV:
params = VIDEO_ENCODE_PARAMS_QSV params = VIDEO_ENCODE_PARAMS_QSV
return [ args = [
'-c:v', params['codec'], '-c:v', params['codec'],
'-preset', params['preset'], '-preset', params['preset'],
'-profile:v', params['profile'], '-profile:v', params['profile'],
@@ -64,7 +66,7 @@ def get_video_encode_args(hw_accel: str = HW_ACCEL_NONE) -> List[str]:
] ]
elif hw_accel == HW_ACCEL_CUDA: elif hw_accel == HW_ACCEL_CUDA:
params = VIDEO_ENCODE_PARAMS_CUDA params = VIDEO_ENCODE_PARAMS_CUDA
return [ args = [
'-c:v', params['codec'], '-c:v', params['codec'],
'-preset', params['preset'], '-preset', params['preset'],
'-profile:v', params['profile'], '-profile:v', params['profile'],
@@ -76,7 +78,7 @@ def get_video_encode_args(hw_accel: str = HW_ACCEL_NONE) -> List[str]:
else: else:
# 软件编码(默认) # 软件编码(默认)
params = VIDEO_ENCODE_PARAMS params = VIDEO_ENCODE_PARAMS
return [ args = [
'-c:v', params['codec'], '-c:v', params['codec'],
'-preset', params['preset'], '-preset', params['preset'],
'-profile:v', params['profile'], '-profile:v', params['profile'],
@@ -85,6 +87,14 @@ def get_video_encode_args(hw_accel: str = HW_ACCEL_NONE) -> List[str]:
'-pix_fmt', params['pix_fmt'], '-pix_fmt', params['pix_fmt'],
] ]
# CRF/CQ + maxrate 上限:保留质量控制的同时限制峰值码率
if maxrate and maxrate > 0:
maxrate_k = f'{maxrate // 1000}k'
bufsize_k = f'{maxrate * 2 // 1000}k'
args.extend(['-maxrate', maxrate_k, '-bufsize', bufsize_k])
return args
def get_hwaccel_decode_args(hw_accel: str = HW_ACCEL_NONE, device_index: Optional[int] = None) -> List[str]: def get_hwaccel_decode_args(hw_accel: str = HW_ACCEL_NONE, device_index: Optional[int] = None) -> List[str]:
""" """
@@ -579,14 +589,17 @@ class BaseHandler(TaskHandler, ABC):
# ========== FFmpeg 参数生成 ========== # ========== FFmpeg 参数生成 ==========
def get_video_encode_args(self) -> List[str]: def get_video_encode_args(self, maxrate: Optional[int] = None) -> List[str]:
""" """
获取当前配置的视频编码参数 获取当前配置的视频编码参数
Args:
maxrate: 最大码率(bps),用于限制峰值码率
Returns: Returns:
FFmpeg 视频编码参数列表 FFmpeg 视频编码参数列表
""" """
return get_video_encode_args(self.config.hw_accel) return get_video_encode_args(self.config.hw_accel, maxrate=maxrate)
def get_hwaccel_decode_args(self) -> List[str]: def get_hwaccel_decode_args(self) -> List[str]:
""" """

View File

@@ -250,7 +250,7 @@ class ComposeTransitionHandler(BaseHandler):
] ]
# 编码参数(根据硬件加速配置动态获取) # 编码参数(根据硬件加速配置动态获取)
cmd.extend(self.get_video_encode_args()) cmd.extend(self.get_video_encode_args(maxrate=output_spec.bitrate))
# 帧率 # 帧率
fps = output_spec.fps fps = output_spec.fps

View File

@@ -11,7 +11,7 @@ import logging
from typing import List, Optional, Tuple from typing import List, Optional, Tuple
from urllib.parse import urlparse, unquote from urllib.parse import urlparse, unquote
from handlers.base import BaseHandler, VIDEO_ENCODE_ARGS from handlers.base import BaseHandler
from domain.task import Task, TaskType, RenderSpec, OutputSpec, Effect, IMAGE_EXTENSIONS from domain.task import Task, TaskType, RenderSpec, OutputSpec, Effect, IMAGE_EXTENSIONS
from domain.result import TaskResult, ErrorCode from domain.result import TaskResult, ErrorCode
@@ -492,7 +492,7 @@ class RenderSegmentTsHandler(BaseHandler):
'-vf', vf_filter, '-vf', vf_filter,
] ]
cmd.extend(VIDEO_ENCODE_ARGS) cmd.extend(self.get_video_encode_args(maxrate=output_spec.bitrate))
fps = output_spec.fps fps = output_spec.fps
cmd.extend(['-r', str(fps)]) cmd.extend(['-r', str(fps)])
@@ -628,7 +628,7 @@ class RenderSegmentTsHandler(BaseHandler):
cmd.extend(['-vf', filters]) cmd.extend(['-vf', filters])
# 编码参数(根据硬件加速配置动态获取) # 编码参数(根据硬件加速配置动态获取)
cmd.extend(self.get_video_encode_args()) cmd.extend(self.get_video_encode_args(maxrate=output_spec.bitrate))
# 帧率 # 帧率
fps = output_spec.fps fps = output_spec.fps