优化故事版生成

This commit is contained in:
Azmat@qq.com
2026-08-21 18:22:50 +08:00
parent 158c66ac25
commit 409d1c2969
5 changed files with 181 additions and 15 deletions
+60 -6
View File
@@ -3,8 +3,9 @@
链路:ffmpeg 抽帧(均匀采样) → 帧内联进多模态 messages → 走现有文本模型路由 → 纯文本分镜稿。
两个「本来以为要新建、其实已经有」的前提:
1. **读图能力**:默认脚本模型(YunQi gemini-3.1-pro)本身是多模态的,OpenAI 兼容的
``content: [{type:"text"},{type:"image_url"}]`` 直接透传即可,不需要新 provider、新模型、新 key。
1. **读图能力**:拆视频是多模态(帧图 + 文本)。默认语言模型现在可能是纯文本豆包,
**不能再用 get_default_model(TEXT)**。固定钉 Gemini 3.1 Pro 官转
(``gemini-3.1-pro-preview``,展示名带「官转」优先)。
2. **ffmpeg**:第 5 阶段导出早就依赖它,已装进后端镜像(见 Dockerfile)。
**没有音轨**:帧里读不到口播,只能读画面上的字幕。这是刻意取舍——接语音转写要另开火山 ASR 服务、
@@ -198,6 +199,59 @@ def validate_digest_text(text: str) -> str:
return cleaned
# 拆视频必须会看图。默认文本模型现在常是纯文本豆包,传帧图会直接失败。
# 钉 Gemini 3.1 Pro;展示名带「官转」的优先(中转站官方 Gemini 通道)。
DIGEST_VISION_MODEL_NAME = "gemini-3.1-pro-preview"
def resolve_digest_model_config():
"""视频提炼用的多模态文本模型:Gemini 3.1 Pro 官转。找不到不回落默认语言模型。"""
from apps.ai.models import ModelConfig
qs = (
ModelConfig.objects.select_related("provider")
.filter(
capability=ModelConfig.Capability.TEXT,
status=ModelConfig.Status.ACTIVE,
provider__status="active",
)
)
def _blob(model) -> str:
return " ".join(
filter(
None,
[
model.name,
model.display_name,
getattr(model.provider, "name", ""),
getattr(model.provider, "display_name", ""),
],
)
)
ranked = []
for model in qs:
blob = _blob(model)
name_hit = "gemini-3.1" in model.name.lower() or "gemini-3.1" in (model.display_name or "").lower()
label_hit = "gemini 3.1" in (model.display_name or "").lower()
if not (name_hit or label_hit or model.name == DIGEST_VISION_MODEL_NAME):
continue
# 官转 > 精确模型名 > 其它 Gemini 3.1
score = 0
if "官转" in blob:
score += 100
if model.name == DIGEST_VISION_MODEL_NAME:
score += 20
if getattr(model.provider, "name", "") == "yunqi_gemini":
score += 5
ranked.append((score, model.created_at, model))
if not ranked:
return None
ranked.sort(key=lambda item: (-item[0], item[1]))
return ranked[0][2]
# --------------------------------------------------------------------------- #
# 入口:一次真实的计费调用
# --------------------------------------------------------------------------- #
@@ -206,15 +260,15 @@ def digest_project_video(*, project, user, upload) -> dict:
from django.db import transaction
from django.utils import timezone
from apps.ai.models import AITask, ModelConfig
from apps.ai.services import create_ai_task, execute_routed_text_request, get_default_model
from apps.ai.models import AITask
from apps.ai.services import create_ai_task, execute_routed_text_request
from apps.billing.services.ledger import charge_reserved_credit
frames, duration = frames_from_upload(upload)
model_config = get_default_model(ModelConfig.Capability.TEXT)
model_config = resolve_digest_model_config()
if model_config is None:
raise VideoDigestError("暂时没有可用的模型,请联系管理员")
raise VideoDigestError("视频提炼需要 Gemini 3.1 Pro(会看图),当前没有启用,请联系管理员")
product = getattr(project, "product", None)
messages = build_digest_messages(