From fc925ef3b3072544704c416576eeada767d272ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=B5=E5=BA=94?= Date: Sun, 13 Sep 2026 21:23:19 +0800 Subject: [PATCH] =?UTF-8?q?fix(lipsync):=20video=5Furl=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E5=90=8D=E6=A0=A1=E9=AA=8C=E6=94=BE=E5=AE=BD=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81MOV/M4V/WebM/AVI/MKV/3GP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iPhone等设备拍摄的视频转h264后容器保留.MOV扩展名, 原校验仅允许.mp4导致对口型接口返回422。 同步更新单测。 --- apps/api/app/schemas/lipsync.py | 7 +++++-- tests/unit/test_lipsync_routes.py | 17 ++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/apps/api/app/schemas/lipsync.py b/apps/api/app/schemas/lipsync.py index 48b5aded5..2c0bff8a8 100644 --- a/apps/api/app/schemas/lipsync.py +++ b/apps/api/app/schemas/lipsync.py @@ -82,8 +82,11 @@ class CreateLipsyncJobRequest(BaseModel): if not video.startswith(("http://", "https://")): raise ValueError("video_url 必须是 HTTP/HTTPS URL") lower = video.lower().split("?")[0] - if not lower.endswith(".mp4"): - raise ValueError("video_url 仅支持 MP4 格式") + allowed_video_exts = (".mp4", ".mov", ".m4v", ".webm", ".avi", ".mkv", ".3gp") + if not any(lower.endswith(ext) for ext in allowed_video_exts): + raise ValueError( + "video_url 格式不支持,仅支持: " + ", ".join(allowed_video_exts) + ) has_audio = bool((self.audio_url or "").strip()) has_tts = bool((self.voice_id or "").strip()) and bool((self.script_text or "").strip()) diff --git a/tests/unit/test_lipsync_routes.py b/tests/unit/test_lipsync_routes.py index 5a7fdfd65..9bfbcc735 100644 --- a/tests/unit/test_lipsync_routes.py +++ b/tests/unit/test_lipsync_routes.py @@ -91,16 +91,27 @@ class TestSchemaValidation: assert req.voice_id == "longxiaochun_v3" assert req.script_text == "大家好,欢迎来到直播间" - def test_invalid_video_url_not_mp4(self): + def test_invalid_video_url_unsupported_ext(self): from app.schemas.lipsync import CreateLipsyncJobRequest - with pytest.raises(ValueError, match="MP4"): + # 不支持的扩展名(.txt)应报错 + with pytest.raises(ValueError, match="格式不支持"): CreateLipsyncJobRequest( - video_url="https://example.com/video.mov", + video_url="https://example.com/video.txt", voice_id="longxiaochun_v3", script_text="测试文本", ) + def test_mov_video_url_accepted(self): + from app.schemas.lipsync import CreateLipsyncJobRequest + + # .MOV 是 iPhone 拍摄的常见容器,h264 编码可直接被 MediaKit 处理 + req = CreateLipsyncJobRequest( + video_url="https://example.com/video.mov", + audio_url="https://example.com/audio.mp3", + ) + assert req.video_url.endswith(".mov") + def test_invalid_video_url_empty(self): from app.schemas.lipsync import CreateLipsyncJobRequest