mirror of
https://github.com/linyqh/NarratoAI.git
synced 2026-05-01 22:28:27 +00:00
fix(documentary): fail on malformed narration payload
This commit is contained in:
parent
d678bf62b1
commit
a8b6a5bb6b
@ -188,25 +188,16 @@ JSON 必须包含以下键:
|
||||
if start >= 0 and end > start:
|
||||
parsed = load_json_candidate(cleaned[start : end + 1])
|
||||
|
||||
items = []
|
||||
items: list[dict[str, Any]] = []
|
||||
if isinstance(parsed, dict):
|
||||
raw_items = parsed.get("items")
|
||||
if isinstance(raw_items, list):
|
||||
items = [item for item in raw_items if isinstance(item, dict)]
|
||||
|
||||
if items:
|
||||
return items
|
||||
if not items:
|
||||
raise ValueError("解说文案格式错误,无法解析JSON或缺少items字段")
|
||||
|
||||
fallback_text = (cleaned[:200] + "...") if len(cleaned) > 200 else cleaned
|
||||
if not fallback_text:
|
||||
fallback_text = "解说文案解析失败,请重试。"
|
||||
return [
|
||||
{
|
||||
"timestamp": "00:00:00,000-00:00:10,000",
|
||||
"picture": "解析失败,使用默认内容",
|
||||
"narration": fallback_text,
|
||||
}
|
||||
]
|
||||
return items
|
||||
|
||||
def _resolve_frame_interval(self, frame_interval_input: int | float | None) -> float:
|
||||
interval = frame_interval_input
|
||||
|
||||
@ -141,6 +141,48 @@ class DocumentaryFrameAnalysisServiceScriptGenerationTests(unittest.IsolatedAsyn
|
||||
self.assertEqual("一只猫警觉地望向镜头。", result[0]["narration"])
|
||||
self.assertEqual(2, result[0]["OST"])
|
||||
|
||||
async def test_generate_documentary_script_raises_when_narration_json_is_malformed(self):
|
||||
service = DocumentaryFrameAnalysisService()
|
||||
analysis_payload = {
|
||||
"batches": [
|
||||
{
|
||||
"batch_index": 0,
|
||||
"time_range": "00:00:00,000-00:00:03,000",
|
||||
"overall_activity_summary": "测试摘要",
|
||||
"fallback_summary": "",
|
||||
"frame_observations": [
|
||||
{"timestamp": "00:00:00,000", "observation": "镜头里有一只猫"},
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
with TemporaryDirectory() as temp_dir:
|
||||
analysis_path = Path(temp_dir) / "frame_analysis_test.json"
|
||||
analysis_path.write_text(json.dumps(analysis_payload, ensure_ascii=False), encoding="utf-8")
|
||||
|
||||
with patch.object(
|
||||
DocumentaryFrameAnalysisService,
|
||||
"analyze_video",
|
||||
AsyncMock(return_value={"analysis_json_path": str(analysis_path)}),
|
||||
), patch.dict(
|
||||
"app.services.documentary.frame_analysis_service.config.app",
|
||||
{
|
||||
"text_llm_provider": "openai",
|
||||
"text_openai_api_key": "test-key",
|
||||
"text_openai_model_name": "test-model",
|
||||
"text_openai_base_url": "https://example.com/v1",
|
||||
},
|
||||
), patch(
|
||||
"app.services.documentary.frame_analysis_service.generate_narration",
|
||||
return_value="malformed narration payload",
|
||||
):
|
||||
with self.assertRaises(Exception) as ctx:
|
||||
await service.generate_documentary_script(video_path="demo.mp4")
|
||||
|
||||
self.assertIn("解说文案格式错误", str(ctx.exception))
|
||||
self.assertIn("items", str(ctx.exception))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user