feat: ASS字幕移到顶部安全区并加透明度(零视差不变)
- srt-to-dual-eye-ass: an2底部→an8顶部对齐,MarginV改为可配margin_top(默认120), 字幕避开画面中央人脸高发区(B-1顶部安全区) - 文字填充&H80FFFFFF→&HB3FFFFFF(约70%透明),描边纯黑→&H80000000半透明黑 - A-1零视差保持不变:左右眼水平相对位置一致,字幕固定屏幕平面 - 新增3条测试(顶部对齐/自定义margin_top/invoke读参数),ass节点覆盖率100% - 新增docs/调查报告:双目视觉景深原理、字幕深度配置公式与遮挡解决方案
This commit is contained in:
@@ -666,6 +666,56 @@ def test_ass_parse_and_write(tmp_path) -> None:
|
||||
assert r"第一行\N第二行" in content
|
||||
|
||||
|
||||
def test_ass_top_aligned_and_translucent(tmp_path) -> None:
|
||||
"""验证字幕默认渲染到顶部安全区且文字/描边带透明度。
|
||||
|
||||
B-1:对齐 an8(顶部居中),MarginV 取顶部安全边距默认 120;
|
||||
透明度:文字填充 &HB3FFFFFF(约 70% 透明),描边 &H80000000(半透明黑),
|
||||
而左右眼水平相对位置一致保持零视差(A-1,字幕在屏幕平面)。"""
|
||||
entries = parse_srt(SAMPLE_SRT)
|
||||
output = tmp_path / "out.ass"
|
||||
write_ass(entries, output, "3840x1920")
|
||||
content = output.read_text(encoding="utf-8")
|
||||
# 顶部对齐 an8、顶部安全边距默认 120。
|
||||
assert r"{\an8}" in content
|
||||
assert r"{\an2}" not in content
|
||||
# 样式行:MarginV=120(顶部安全区),填充 &HB3FFFFFF,描边 &H80000000。
|
||||
assert "&HB3FFFFFF" in content
|
||||
assert "&H80000000" in content
|
||||
assert ",0,0,0,0,50,100,0,0,1,4,0,8,50,1920,120,1" in content
|
||||
# 左右眼两行文本一致(水平相对位置相同 → 零视差/A-1)。
|
||||
assert content.count(r"第一行\N第二行") == 2
|
||||
|
||||
|
||||
def test_ass_write_custom_margin_top(tmp_path) -> None:
|
||||
"""验证可通过 margin_top 覆盖顶部安全边距(不同分辨率下微调)。"""
|
||||
entries = parse_srt(SAMPLE_SRT)
|
||||
output = tmp_path / "out.ass"
|
||||
write_ass(entries, output, "1920x1080", margin_top=200)
|
||||
content = output.read_text(encoding="utf-8")
|
||||
# 1920 宽:每半幅 960;MarginV 用自定义 200。
|
||||
assert ",0,0,0,0,50,100,0,0,1,4,0,8,50,960,200,1" in content
|
||||
|
||||
|
||||
def test_ass_invoke_reads_margin_top(tmp_path) -> None:
|
||||
"""验证 invoke 从请求参数读取 margin_top 并反映到产物样式。"""
|
||||
source = tmp_path / "in.srt"
|
||||
source.write_text(SAMPLE_SRT, encoding="utf-8")
|
||||
response = ass_invoke(
|
||||
InvokeRequest(
|
||||
run_id="run_mt",
|
||||
node_instance_id="ni_mt",
|
||||
inputs={"cn_srt_uri": str(source)},
|
||||
params={"resolution": "1920x1080", "margin_top": 90},
|
||||
output_dir=str(tmp_path / "out"),
|
||||
)
|
||||
)
|
||||
assert response.status == "completed"
|
||||
content = Path(response.outputs["ass_uri"]).read_text(encoding="utf-8")
|
||||
assert "an8" in content
|
||||
assert ",0,0,0,0,50,100,0,0,1,4,0,8,50,960,90,1" in content
|
||||
|
||||
|
||||
def test_ass_parse_malformed(tmp_path) -> None:
|
||||
"""验证畸形 SRT 不会抛出异常且返回空条目或忽略坏行。"""
|
||||
source = tmp_path / "bad.srt"
|
||||
|
||||
Reference in New Issue
Block a user