|
@@ -413,8 +413,40 @@ class VideoIdentifier:
|
|
if hasattr(response, '_error') and response._error:
|
|
if hasattr(response, '_error') and response._error:
|
|
raise Exception(f"生成错误: {response._error}")
|
|
raise Exception(f"生成错误: {response._error}")
|
|
|
|
|
|
|
|
+ # 安全获取文本:避免在无 Part 时访问 response.text 抛错
|
|
|
|
+ def safe_extract_text(resp: Any) -> str:
|
|
|
|
+ try:
|
|
|
|
+ # 优先从 candidates 结构中提取
|
|
|
|
+ candidates = getattr(resp, 'candidates', None)
|
|
|
|
+ if candidates and len(candidates) > 0:
|
|
|
|
+ first = candidates[0]
|
|
|
|
+ # 记录 finish_reason 以便错误信息更清晰
|
|
|
|
+ finish_reason = getattr(first, 'finish_reason', None)
|
|
|
|
+ # parts 路径
|
|
|
|
+ content = getattr(first, 'content', None)
|
|
|
|
+ parts = getattr(content, 'parts', None) if content else None
|
|
|
|
+ if parts and len(parts) > 0:
|
|
|
|
+ # 兼容 text 或直接包含的内容
|
|
|
|
+ # 常见 part 为 {text: str}
|
|
|
|
+ part0 = parts[0]
|
|
|
|
+ text = getattr(part0, 'text', None) if hasattr(part0, 'text') else part0.get('text') if isinstance(part0, dict) else None
|
|
|
|
+ if isinstance(text, str) and text.strip():
|
|
|
|
+ return text
|
|
|
|
+ # 若无 parts 或为空,根据 finish_reason 返回清晰错误
|
|
|
|
+ reason = str(finish_reason) if finish_reason is not None else 'unknown'
|
|
|
|
+ raise ValueError(f"无有效输出内容,finish_reason={reason}")
|
|
|
|
+
|
|
|
|
+ # 退化到 resp.text(可能抛错)
|
|
|
|
+ if hasattr(resp, 'text') and isinstance(resp.text, str) and resp.text.strip():
|
|
|
|
+ return resp.text
|
|
|
|
+
|
|
|
|
+ raise ValueError("响应中没有可用的文本内容")
|
|
|
|
+ except Exception as ex:
|
|
|
|
+ raise ex
|
|
|
|
+
|
|
try:
|
|
try:
|
|
- parsed = json.loads(response.text.strip())
|
|
|
|
|
|
+ text_payload = safe_extract_text(response).strip()
|
|
|
|
+ parsed = json.loads(text_payload)
|
|
if not isinstance(parsed, dict):
|
|
if not isinstance(parsed, dict):
|
|
raise ValueError("响应格式错误:非字典结构")
|
|
raise ValueError("响应格式错误:非字典结构")
|
|
|
|
|
|
@@ -449,6 +481,18 @@ class VideoIdentifier:
|
|
'ocr_content': '关键帧分析失败:JSON解析错误'
|
|
'ocr_content': '关键帧分析失败:JSON解析错误'
|
|
}]
|
|
}]
|
|
}
|
|
}
|
|
|
|
+ except Exception as e:
|
|
|
|
+ # 捕获无 Part 或 finish_reason 封锁等导致的无法提取文本问题
|
|
|
|
+ err_msg = str(e)
|
|
|
|
+ return {
|
|
|
|
+ 'url': url, 'duration': duration,
|
|
|
|
+ 'asr_content': f'处理失败: {err_msg}',
|
|
|
|
+ 'iframe_details': [{
|
|
|
|
+ 'time_start': 0, 'time_end': 0,
|
|
|
|
+ 'content': f'处理失败: {err_msg}',
|
|
|
|
+ 'ocr_content': f'处理失败: {err_msg}'
|
|
|
|
+ }]
|
|
|
|
+ }
|
|
|
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
return {
|
|
return {
|