mirror of
https://github.com/linyqh/NarratoAI.git
synced 2026-09-09 21:49:06 +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:
|
if start >= 0 and end > start:
|
||||||
parsed = load_json_candidate(cleaned[start : end + 1])
|
parsed = load_json_candidate(cleaned[start : end + 1])
|
||||||
|
|
||||||
items = []
|
items: list[dict[str, Any]] = []
|
||||||
if isinstance(parsed, dict):
|
if isinstance(parsed, dict):
|
||||||
raw_items = parsed.get("items")
|
raw_items = parsed.get("items")
|
||||||
if isinstance(raw_items, list):
|
if isinstance(raw_items, list):
|
||||||
items = [item for item in raw_items if isinstance(item, dict)]
|
items = [item for item in raw_items if isinstance(item, dict)]
|
||||||
|
|
||||||
if items:
|
if not items:
|
||||||
return items
|
raise ValueError("解说文案格式错误,无法解析JSON或缺少items字段")
|
||||||
|
|
||||||
fallback_text = (cleaned[:200] + "...") if len(cleaned) > 200 else cleaned
|
return items
|
||||||
if not fallback_text:
|
|
||||||
fallback_text = "解说文案解析失败,请重试。"
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
"timestamp": "00:00:00,000-00:00:10,000",
|
|
||||||
"picture": "解析失败,使用默认内容",
|
|
||||||
"narration": fallback_text,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
def _resolve_frame_interval(self, frame_interval_input: int | float | None) -> float:
|
def _resolve_frame_interval(self, frame_interval_input: int | float | None) -> float:
|
||||||
interval = frame_interval_input
|
interval = frame_interval_input
|
||||||
|
|||||||
@ -141,6 +141,48 @@ class DocumentaryFrameAnalysisServiceScriptGenerationTests(unittest.IsolatedAsyn
|
|||||||
self.assertEqual("一只猫警觉地望向镜头。", result[0]["narration"])
|
self.assertEqual("一只猫警觉地望向镜头。", result[0]["narration"])
|
||||||
self.assertEqual(2, result[0]["OST"])
|
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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user