This commit is contained in:
2025-09-24 10:50:34 +08:00
parent c055a68592
commit ec1705769c
18 changed files with 348 additions and 330 deletions

View File

@@ -1,27 +1,17 @@
"""测试FFmpeg命令构建器"""
import pytest
from unittest.mock import Mock, patch
from entity.ffmpeg_command_builder import FFmpegCommandBuilder
from entity.render_task import RenderTask
from config.settings import Config
from config.settings import FFmpegConfig, APIConfig, StorageConfig
from tests.utils.test_helpers import MockRenderTask, FFmpegValidator
class TestFFmpegCommandBuilder:
"""测试FFmpeg命令构建器"""
@pytest.fixture
def mock_config(self):
"""模拟配置"""
return Config(
encoder_args="-c:v h264",
video_args="-preset fast",
template_dir="tests/test_data/templates",
api_endpoint="http://test.local",
access_key="test_key"
)
@pytest.fixture
def simple_task(self):
"""简单的渲染任务"""
@@ -43,15 +33,15 @@ class TestFFmpegCommandBuilder:
}
return task
def test_init(self, simple_task, mock_config):
def test_init(self, simple_task):
"""测试初始化"""
builder = FFmpegCommandBuilder(simple_task, mock_config)
builder = FFmpegCommandBuilder(simple_task)
assert builder.task == simple_task
assert builder.config == mock_config
assert builder.config is not None
def test_build_copy_command(self, simple_task, mock_config):
def test_build_copy_command(self, simple_task):
"""测试构建复制命令"""
builder = FFmpegCommandBuilder(simple_task, mock_config)
builder = FFmpegCommandBuilder(simple_task)
command = builder._build_copy_command()
# 验证命令结构
@@ -67,13 +57,13 @@ class TestFFmpegCommandBuilder:
assert "output.mp4" in command
assert "-c" in command and "copy" in command
def test_build_concat_command_multiple_files(self, mock_config):
def test_build_concat_command_multiple_files(self):
"""测试构建多文件拼接命令"""
task = MockRenderTask()
task.input_files = ["file1.mp4", "file2.mp4", "file3.mp4"]
task.output_path = "concat_output.mp4"
builder = FFmpegCommandBuilder(task, mock_config)
builder = FFmpegCommandBuilder(task)
command = builder._build_concat_command()
validation = FFmpegValidator.validate_ffmpeg_command(command)
@@ -84,9 +74,9 @@ class TestFFmpegCommandBuilder:
assert "concat=n=3:v=1:a=1" in " ".join(command)
assert all(f"file{i}.mp4" in command for i in range(1, 4))
def test_build_encode_command_with_effects(self, task_with_effects, mock_config):
def test_build_encode_command_with_effects(self, task_with_effects):
"""测试构建带特效的编码命令"""
builder = FFmpegCommandBuilder(task_with_effects, mock_config)
builder = FFmpegCommandBuilder(task_with_effects)
command = builder._build_encode_command()
validation = FFmpegValidator.validate_ffmpeg_command(command)
@@ -99,13 +89,13 @@ class TestFFmpegCommandBuilder:
# 应该包含编码参数
assert "-c:v" in command and "h264" in command
def test_add_effects_single_effect(self, mock_config):
def test_add_effects_single_effect(self):
"""测试添加单个特效"""
task = MockRenderTask()
task.effects = ["zoom:0,2.0,3.0"]
task.ext_data = {"posJson": "{}"}
builder = FFmpegCommandBuilder(task, mock_config)
builder = FFmpegCommandBuilder(task)
filter_args = []
result_input, result_index = builder._add_effects(filter_args, "[0:v]", 1)
@@ -115,13 +105,13 @@ class TestFFmpegCommandBuilder:
assert result_input == "[v_eff1]" # 输出流应该更新
assert result_index == 2 # 索引应该递增
def test_add_effects_multiple_effects(self, mock_config):
def test_add_effects_multiple_effects(self):
"""测试添加多个特效"""
task = MockRenderTask()
task.effects = ["zoom:0,2.0,3.0", "ospeed:1.5"]
task.ext_data = {"posJson": "{}"}
builder = FFmpegCommandBuilder(task, mock_config)
builder = FFmpegCommandBuilder(task)
filter_args = []
result_input, result_index = builder._add_effects(filter_args, "[0:v]", 1)
@@ -131,12 +121,12 @@ class TestFFmpegCommandBuilder:
assert result_input == "[v_eff2]" # 最终输出流
assert result_index == 3 # 索引应该递增两次
def test_add_effects_invalid_effect(self, mock_config):
def test_add_effects_invalid_effect(self):
"""测试添加无效特效"""
task = MockRenderTask()
task.effects = ["invalid_effect:params"]
builder = FFmpegCommandBuilder(task, mock_config)
builder = FFmpegCommandBuilder(task)
filter_args = []
result_input, result_index = builder._add_effects(filter_args, "[0:v]", 1)
@@ -145,12 +135,12 @@ class TestFFmpegCommandBuilder:
assert result_input == "[0:v]" # 输入流不变
assert result_index == 1 # 索引不变
def test_add_effects_no_effects(self, mock_config):
def test_add_effects_no_effects(self):
"""测试无特效情况"""
task = MockRenderTask()
task.effects = []
builder = FFmpegCommandBuilder(task, mock_config)
builder = FFmpegCommandBuilder(task)
filter_args = []
result_input, result_index = builder._add_effects(filter_args, "[0:v]", 1)
@@ -159,11 +149,11 @@ class TestFFmpegCommandBuilder:
assert result_index == 1 # 索引不变
assert len(filter_args) == 0 # 无滤镜添加
def test_build_command_copy_mode(self, simple_task, mock_config):
def test_build_command_copy_mode(self, simple_task):
"""测试构建复制模式命令"""
simple_task.input_files = ["single_file.mp4"]
builder = FFmpegCommandBuilder(simple_task, mock_config)
builder = FFmpegCommandBuilder(simple_task)
command = builder.build_command()
validation = FFmpegValidator.validate_ffmpeg_command(command)
@@ -173,13 +163,13 @@ class TestFFmpegCommandBuilder:
command_str = " ".join(command)
assert "-c copy" in command_str
def test_build_command_concat_mode(self, mock_config):
def test_build_command_concat_mode(self):
"""测试构建拼接模式命令"""
task = MockRenderTask()
task.input_files = ["file1.mp4", "file2.mp4"]
task.effects = []
builder = FFmpegCommandBuilder(task, mock_config)
builder = FFmpegCommandBuilder(task)
command = builder.build_command()
validation = FFmpegValidator.validate_ffmpeg_command(command)
@@ -190,9 +180,9 @@ class TestFFmpegCommandBuilder:
command_str = " ".join(command)
assert "concat=" in command_str
def test_build_command_encode_mode(self, task_with_effects, mock_config):
def test_build_command_encode_mode(self, task_with_effects):
"""测试构建编码模式命令"""
builder = FFmpegCommandBuilder(task_with_effects, mock_config)
builder = FFmpegCommandBuilder(task_with_effects)
command = builder.build_command()
validation = FFmpegValidator.validate_ffmpeg_command(command)
@@ -203,15 +193,15 @@ class TestFFmpegCommandBuilder:
command_str = " ".join(command)
assert "-c:v h264" in command_str
@patch('entity.effects.registry.get_processor')
def test_effect_processor_integration(self, mock_get_processor, mock_config):
@patch("entity.effects.registry.get_processor")
def test_effect_processor_integration(self, mock_get_processor):
"""测试与特效处理器的集成"""
# 模拟特效处理器
mock_processor = Mock()
mock_processor.frame_rate = 25
mock_processor.generate_filter_args.return_value = (
["[0:v]zoompan=z=2.0:x=iw/2:y=ih/2:d=1[v_eff1]"],
"[v_eff1]"
"[v_eff1]",
)
mock_get_processor.return_value = mock_processor
@@ -219,7 +209,7 @@ class TestFFmpegCommandBuilder:
task.effects = ["zoom:0,2.0,3.0"]
task.frame_rate = 30
builder = FFmpegCommandBuilder(task, mock_config)
builder = FFmpegCommandBuilder(task)
filter_args = []
builder._add_effects(filter_args, "[0:v]", 1)
@@ -228,12 +218,12 @@ class TestFFmpegCommandBuilder:
mock_processor.generate_filter_args.assert_called_once_with("[0:v]", 1)
assert mock_processor.frame_rate == 30 # 帧率应该被设置
def test_error_handling_missing_input(self, mock_config):
def test_error_handling_missing_input(self):
"""测试缺少输入文件的错误处理"""
task = MockRenderTask()
task.input_files = []
builder = FFmpegCommandBuilder(task, mock_config)
builder = FFmpegCommandBuilder(task)
# 构建命令时应该处理错误情况
# 具体的错误处理依赖于实现
@@ -241,4 +231,4 @@ class TestFFmpegCommandBuilder:
# 验证至少返回了基本的ffmpeg命令结构
assert isinstance(command, list)
assert len(command) > 0
assert len(command) > 0