feat: 优化学习视频转写与字幕清洗
This commit is contained in:
+66
-3
@@ -292,13 +292,13 @@ def test_resolve_incomplete_candidate_skipped(tmp_path) -> None:
|
||||
empty = tmp_path / "empty"
|
||||
empty.mkdir()
|
||||
resolved = resolve_model_path({}, env={}, candidates=[empty])
|
||||
assert resolved == "large-v3"
|
||||
assert resolved == "large-v2"
|
||||
|
||||
|
||||
def test_resolve_fallback_remote() -> None:
|
||||
"""验证全部本地候选缺失时回退到远端 large-v3 作为最后兜底。"""
|
||||
"""验证全部本地候选缺失时回退到远端 large-v2 作为最后兜底。"""
|
||||
resolved = resolve_model_path({}, env={}, candidates=[])
|
||||
assert resolved == "large-v3"
|
||||
assert resolved == "large-v2"
|
||||
|
||||
|
||||
def test_format_timestamp() -> None:
|
||||
@@ -1497,5 +1497,68 @@ def test_whisper_decode_full_cleanup_jp_hallucination(tmp_path, monkeypatch) ->
|
||||
assert all(t != "-" for t in text_lines)
|
||||
|
||||
|
||||
def test_whisper_decode_full_filters_short_moan(tmp_path, monkeypatch) -> None:
|
||||
"""decode_full=true 时纯呻吟碎片整条删除,真实短词保留(2026-09 决策)。"""
|
||||
class MoanModel:
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def transcribe(self, path, **kwargs):
|
||||
# 混合:正常句 + 纯呻吟碎片 + 真实短词(都应保留)。
|
||||
return (
|
||||
[
|
||||
FakeSegment(0, 2, "気持ちいい"), # 正常
|
||||
FakeSegment(2, 3, "あ〜"), # 纯呻吟 → 删
|
||||
FakeSegment(3, 4, "ん?"), # 纯呻吟 → 删
|
||||
FakeSegment(4, 5, "そこ"), # 真实短词 → 保留
|
||||
FakeSegment(5, 6, "やばい"), # 真实短词 → 保留
|
||||
],
|
||||
None,
|
||||
)
|
||||
|
||||
monkeypatch.setitem(
|
||||
sys.modules, "faster_whisper", types.SimpleNamespace(WhisperModel=lambda *a, **k: MoanModel())
|
||||
)
|
||||
_make_wav(tmp_path / "audio.wav", 5)
|
||||
resp = whisper_invoke(
|
||||
_whisper_request(tmp_path, params={"language": "ja", "decode_full": True})
|
||||
)
|
||||
assert resp.status == "completed"
|
||||
content = Path(resp.outputs["srt_uri"]).read_text(encoding="utf-8")
|
||||
# 纯呻吟碎片被整条删除;真实短词与正常句保留。
|
||||
assert "あ〜" not in content
|
||||
assert "ん?" not in content
|
||||
assert "気持ちいい" in content
|
||||
assert "そこ" in content
|
||||
assert "やばい" in content
|
||||
assert content.count("-->") == 3 # 5 段 - 2 段呻吟 = 3 条
|
||||
|
||||
|
||||
def test_whisper_decode_full_short_moan_can_disable(tmp_path, monkeypatch) -> None:
|
||||
"""short_moan_max_chars=0 时关闭短呻吟过滤,所有内容原样保留。"""
|
||||
class MoanModel2:
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def transcribe(self, path, **kwargs):
|
||||
return ([FakeSegment(0, 1, "あ〜"), FakeSegment(1, 2, "そこ")], None)
|
||||
|
||||
monkeypatch.setitem(
|
||||
sys.modules, "faster_whisper", types.SimpleNamespace(WhisperModel=lambda *a, **k: MoanModel2())
|
||||
)
|
||||
_make_wav(tmp_path / "audio.wav", 5)
|
||||
resp = whisper_invoke(
|
||||
_whisper_request(
|
||||
tmp_path,
|
||||
params={"language": "ja", "decode_full": True, "short_moan_max_chars": 0},
|
||||
)
|
||||
)
|
||||
assert resp.status == "completed"
|
||||
content = Path(resp.outputs["srt_uri"]).read_text(encoding="utf-8")
|
||||
assert "あ〜" in content
|
||||
assert "そこ" in content
|
||||
assert content.count("-->") == 2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user