修改AI创作界面和后台视频模型添加选择是否支持全能或者收尾帧

This commit is contained in:
2026-07-02 11:38:11 +08:00
parent 8b21d7cdde
commit c2b203f658
11 changed files with 1727 additions and 138 deletions
@@ -0,0 +1,46 @@
"""d4e5f6a7b8c9 - 视频引擎增加首尾帧和全能参考支持字段
Revision ID: d4e5f6a7b8c9
Revises: 6idufv2q1c
Create Date: 2026-07-02 00:00:00.000000
该文件包含 2026-07-02 的数据库迁移内容:
1. 视频引擎表增加 supports_first_last_frame 字段(是否支持首尾帧模式)
2. 视频引擎表增加 supports_universal_reference 字段(是否支持全能参考模式)
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
revision: str = 'd4e5f6a7b8c9'
down_revision: Union[str, None] = '6idufv2q1c'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.add_column(
'video_engines',
sa.Column(
'supports_first_last_frame',
sa.Boolean(),
server_default=sa.text('false'),
nullable=False,
),
)
op.add_column(
'video_engines',
sa.Column(
'supports_universal_reference',
sa.Boolean(),
server_default=sa.text('true'),
nullable=False,
),
)
def downgrade() -> None:
op.drop_column('video_engines', 'supports_universal_reference')
op.drop_column('video_engines', 'supports_first_last_frame')
@@ -51,5 +51,7 @@ async def list_active_engines(
"supported_durations": durations,
"max_image_count": e.max_image_count,
"max_video_count": e.max_video_count,
"supports_first_last_frame": e.supports_first_last_frame,
"supports_universal_reference": e.supports_universal_reference,
})
return {"items": items}
+2
View File
@@ -19,6 +19,8 @@ class VideoEngine(Base, TimestampMixin):
max_duration: Mapped[int] = mapped_column(Integer, default=15)
max_image_count: Mapped[int] = mapped_column(Integer, default=2)
max_video_count: Mapped[int] = mapped_column(Integer, default=0)
supports_first_last_frame: Mapped[bool] = mapped_column(Boolean, default=False)
supports_universal_reference: Mapped[bool] = mapped_column(Boolean, default=True)
generate_url: Mapped[str | None] = mapped_column(String(512), nullable=True, default="")
query_url: Mapped[str | None] = mapped_column(String(512), nullable=True, default="")
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
@@ -15,6 +15,8 @@ class VideoEngineCreate(BaseModel):
max_duration: int = Field(default=15)
max_image_count: int = Field(default=2)
max_video_count: int = Field(default=0)
supports_first_last_frame: bool = Field(default=False, description="是否支持首尾帧模式")
supports_universal_reference: bool = Field(default=True, description="是否支持全能参考模式")
generate_url: str = Field(default="", max_length=512)
query_url: str = Field(default="", max_length=512)
is_active: bool = True
@@ -37,6 +39,8 @@ class VideoEnginePublic(BaseModel):
supported_durations: list[int] = []
max_image_count: int = 2
max_video_count: int = 0
supports_first_last_frame: bool = False
supports_universal_reference: bool = True
class VideoEngineListResponse(BaseModel):
+5 -2
View File
@@ -126,12 +126,15 @@ async def submit_video_task(
for ref in refs:
ref_type = ref.get("type")
ref_url = ref.get("url", "")
ref_role = ref.get("role")
if ref_type == "image" and ref_url:
resolved = _resolve_url(ref_url)
content.append({"type": "image_url", "image_url": {"url": resolved},"role":"reference_image"})
role = ref_role if ref_role in ("first_frame", "last_frame") else "reference_image"
content.append({"type": "image_url", "image_url": {"url": resolved}, "role": role})
elif ref_type == "video" and ref_url:
resolved = _resolve_url(ref_url)
content.append({"type": "video_url", "video_url": {"url": resolved},"role":"reference_video"})
role = ref_role if ref_role else "reference_video"
content.append({"type": "video_url", "video_url": {"url": resolved}, "role": role})
except (json.JSONDecodeError, TypeError):
pass