Files
xiaoxia-saas/apps/worker/video_processing/watermark_engine.py
T
CI Bot 9587f02df2
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 16s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m10s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m39s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m43s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 2m13s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 35s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 34s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m8s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 48s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m47s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m40s
AI Code Review / AI Code Review (pull_request) Successful in 6m39s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Successful in 3m25s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m24s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 22s
test(wave115): 抽离watermark_config领域模型 + 76单测
- 抽离WatermarkConfig数据类、9宫格位置常量、位置计算、滤镜构建到packages/domain/watermark_config.py
- 新增has_effect()/get_position_names()/get_position_display_name()工具函数
- watermark_engine.py: 314→117行 (-63%),保留WatermarkEngine薄包装+模块级向后兼容导入
- 76个纯逻辑单测全绿,原有48个测试无回归
- 合计124 passed
2026-07-27 07:20:25 +08:00

114 lines
3.3 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""水印引擎 — 基于 FFmpeg overlay 滤镜的水印叠加.
支持:
- 图片水印(PNG/logo
- 文字水印(drawtext
- 9宫格位置 + 边距配置
- 透明度/大小缩放
- 滚动水印(跑马灯)
注:核心领域模型已抽离到 packages/domain/watermark_config.py
本模块保留薄包装层,确保向后兼容。
"""
from __future__ import annotations
import logging
from typing import Any
from packages.domain.watermark_config import ( # noqa: F401 — 向后兼容
WATERMARK_POSITIONS,
WatermarkConfig,
build_image_watermark_filter as _build_image_watermark_filter,
build_text_watermark_filter as _build_text_watermark_filter,
calc_position as _calc_position_base,
calc_scroll_x as _calc_scroll_x_base,
)
logger = logging.getLogger(__name__)
class WatermarkEngine:
"""水印引擎 — 生成 FFmpeg 水印滤镜.
薄包装层,实际逻辑委托给 packages.domain.watermark_config。
"""
@staticmethod
def calc_position(
position: str,
output_width: int,
output_height: int,
wm_width: int,
wm_height: int,
margin_x: int,
margin_y: int,
) -> tuple[int, int]:
"""根据9宫格位置计算水印坐标 (x, y).
坐标系:左上角为 (0, 0)
"""
return _calc_position_base(position, output_width, output_height, wm_width, wm_height, margin_x, margin_y)
@staticmethod
def calc_scroll_x(position: str, output_width: int, wm_width: int, speed: int) -> str:
"""生成滚动水印的 x 坐标表达式.
从右向左滚动(跑马灯效果)
"""
return _calc_scroll_x_base(position, output_width, wm_width, speed)
@staticmethod
def build_image_watermark_filter(
input_video_label: str,
wm_image_path: str,
output_width: int,
output_height: int,
output_label: str,
config: WatermarkConfig,
) -> tuple[str, list[str]]:
"""构建图片水印滤镜链.
Args:
input_video_label: 输入视频标签,如 "[final_video]"
wm_image_path: 水印图片本地路径
output_width: 输出视频宽度
output_height: 输出视频高度
output_label: 输出标签
config: 水印配置
Returns:
(filter_complex_str, input_args_list)
input_args 是 ["-i", wm_image_path] 格式
"""
return _build_image_watermark_filter(
input_video_label,
wm_image_path,
output_width,
output_height,
output_label,
config,
)
@staticmethod
def build_text_watermark_filter(
input_video_label: str,
output_label: str,
config: WatermarkConfig,
output_width: int,
output_height: int,
) -> str:
"""构建文字水印滤镜(drawtext.
Args:
input_video_label: 输入视频标签
output_label: 输出标签
config: 水印配置
output_width: 输出宽度
output_height: 输出高度
Returns:
FFmpeg filter 字符串
"""
return _build_text_watermark_filter(input_video_label, output_label, config, output_width, output_height)