{% extends "base.html" %} {% block title %}{{ brand.home_title }} {% endblock %} {% block topbar %}{% endblock %} {% block content %}
{% set _prof = client_profile or {} %} {% if _prof.notice %}
公告 {{ _prof.notice }}
{% endif %} {% if _prof.kill_switch %} {% endif %} {% if device_state and device_state.known and not device_state.ok %} {% endif %} {% if fresh_hint %}
新设备{{ fresh_hint }}
{% endif %} {% if plan_expiring %}
套餐{{ plan_expiring }}
{% endif %} {% set selected_creation_mode = request.form.get('creation_mode') or selected_creation_mode or 'clone' %} {% set selected_aspect_ratio = request.form.get('aspect_ratio') or selected_aspect_ratio or '9:16' %} {% set selected_h3_resolution = request.form.get('h3_resolution') or selected_h3_resolution or '480p' %}
{{ brand.home_title }}

创建你的AI视频项目

⚙️ 创作配置
1选择创作方式
2上传原视频
2创作剧情脚本
点击按钮后自动生成剧情要求,生成后可编辑再提交
3广告植入要求可上传多张图(产品/人物/场景),数量不限;视觉理解最多取前 9 张。每张图下方选「产品 / 人物 / 场景」:标了几张人物图,成片里就正好有几个人物,外形照对应那张人物图来。
3上传图片(产品 / 人物 / 场景,选填) 可上传多张,数量不限;视觉理解最多取前 9 张。每张图下方可单独改角色:加几张人物图,成片里就正好有几个人物,外形照对应那张人物图来。
(每任务重复入队,生成不同成片) 成片完成自动加 _时间戳 复制;目录优先级:本框 > 设置默认输出目录 > out 目录
{% if selected_creation_mode == 'clone' %}3{% else %}4{% endif %}成片规格和视频生成参数
跟随原视频
✓ 计费承诺:编排失败全额退积分,生成失败免费重跑,不出片不扣分。
{% if error %}
{{ error }}
{% endif %} {% if message %}
{{ message }}
{% endif %} {% set project_groups = project_groups|default([], true) %} {% set selected_group = selected_group|default('all', true) %} {% set selected_group_name = selected_group_name|default('全部项目', true) %} {% set all_projects = all_projects|default(projects, true) %} {% set all_project_count = all_project_count|default(projects|length) %} {% set ungrouped_project_count = ungrouped_project_count|default(projects|length) %} {# ── 服务端分页上下文(?page=&size=):变量缺失时按"单页全量"兜底,保证老调用不炸 ── #} {% set page_projects = page_projects|default(projects, true) %} {% set page = page|default(1) %} {% set page_count = page_count|default(1) %} {% set page_size = page_size|default(page_projects|length) %} {% set size_param = size_param|default('20') %} {% set page_size_options = page_size_options|default(['20', '50', '100', '500', '1000', 'all']) %} {% set page_size_labels = page_size_labels|default({}) %} {% set pagination_enabled = pagination_enabled|default(true) %} {% set total_count = total_count|default(page_projects|length) %} {# 轮询用的 URL:优先服务端给的(含当前页),老调用缺变量时按当前分组/每页数量现算,确保可序列化。 轮询抓卡片必须带上当前搜索/筛选条件(q/mode/status),否则筛选页里补插的卡片会是不匹配的项目。 #} {% set _poll_qs = (('q=' ~ (filter_q|urlencode)) if filter_q else '') ~ (('&mode=' ~ filter_mode) if filter_mode else '') ~ (('&status=' ~ filter_status) if filter_status else '') %} {% set home_page_url = home_page_url|default(url_for('home', group=selected_group, size=size_param, page=page) ~ (('&' ~ _poll_qs) if _poll_qs else '')) %} {% set home_first_page_url = home_first_page_url|default(url_for('home', group=selected_group, size=size_param, page=1) ~ (('&' ~ _poll_qs) if _poll_qs else '')) %} {# 分页控件(列表上下各一处):首页 / 上一页 / 下一页 / 末页 + 每页数量 + 跳到指定页。 每页数量用下拉选择框(用户要求);搜索/筛选参数在切换时透传,不让结果跳变。 #} {% macro render_pagination_bar(where) %} {% set _f_qs = (('q=' ~ (filter_q|urlencode)) if filter_q else '') ~ (('&mode=' ~ filter_mode) if filter_mode else '') ~ (('&status=' ~ filter_status) if filter_status else '') %}
{% if pagination_enabled and page_count > 1 %} {% endif %} {% if pagination_enabled and page_count > 1 %}第 {{ page }}/{{ page_count }} 页 · {% endif %}共 {{ total_count }} 个项目{% if pagination_enabled and total_count %}(本页 {{ page_projects|length }} 个){% endif %}
{% endmacro %}

项目列表 · {{ selected_group_name }}

按分组查看和整理项目;列表按服务端分页展示(每页数量与页码见列表上下方),也可勾选本页项目批量删除。
{# 批量中断(用户要求):勾选里含运行中/排队中任务时可用,AJAX 提交只刷新列表 #} {# 中断所有任务(用户要求):不限勾选,中断当前列表全部运行中/排队中任务 #}
{# 搜索 + 创作方式/状态筛选(用户要求:标题+图片素材名+项目号模糊搜索;创作方式/生成状态快速筛选)#}
{% if filter_q or filter_mode or filter_status %} 清除 {% endif %}
当前 {{ projects|length }} / 共 {% if filter_q or filter_mode or filter_status %}{{ total_count }} 个(已筛选,全部 {{ all_project_count }}){% else %}{{ all_project_count }} 个项目{% endif %}
{# 轮询自动插入失败/新任务不在本页时的提示条(JS 控制显隐,带可点的刷新/回第一页链接) #} {{ render_pagination_bar('top') }}
{% for item in page_projects %}
{% if item.workflow_active %}
{% if item.workflow.status == 'queued' %}排队中{% elif item.workflow.status == 'cancelling' %}正在中断{% else %}运行中{% endif %} {% if item.backend_label %} {# 运行中也在状态区标注后端(取自项目记录);具体阶段文案由服务端动态产出(如"云端视频生成 1/4") #} {{ '☁ 云端' if item.backend_label == 'cloud' else '🖥 本机' }} {% endif %}
{% if item.workflow.status == 'queued' %}等待前序项目完成{% else %}一键成片后台任务{% endif %} {{ item.workflow.detail or '正在准备任务...' }}
{# 生成过程最后一行(API 阶段的模型思考/正文/状态/重试/错误):实时显示 + 可点进项目页看完整过程。 数据来自 GET /projects//stream(?tail=1&follow=0),没有日志时不占位。 #}
{% elif item.final_video_url %} {# 列表页不自动拉视频流(4K 成片预加载曾占满浏览器 6 连接导致整站卡死)。 封面 = 服务端从成片抽帧的真实预览图(~20KB jpg,一次性生成永久复用), 点击在弹层里才真正加载视频。抽帧失败时 CSS 渐变底兜底(onerror 移除 img)。 #} {% else %}
🎬 暂无最终视频 完成最后一步视频生成后会自动显示
{% endif %}
{% if item.backend_label %} {# 云端/本机生成标识:固定网格头行右侧(与勾选框同一水平带); title 里给出完整后端地址 · 取自本项目生成时的记录 #} {{ '☁ 云端生成' if item.backend_label == 'cloud' else '🖥 本机生成' }} {% endif %}
{% if item.workflow_active %}
{{ item.name }}
{% else %}
{% endif %}
{{ item.id }}
{# 开始生成时刻(= 执行开始):用户要求放在"所属分组"后面(原先挂在 token 行尾) #} {% if item.token_started_at %}开始生成 {{ item.token_started_at[:16] }}{% endif %}
{% if item.show_one_click_total_elapsed %} {# 耗时区放「所属分组」之后(用户要求);总耗时只算执行(API + 预运行 + 视频生成 + 后处理), 不含排队等待——起点 data-exec-started=第一次真正开跑(API 阶段开始), 不是入队/创建时刻。运行中由前端按 data-* 实时累加。 #} {% endif %} {% if item.show_video_generation_elapsed %} {% endif %}
{# API 消耗行(用户要求):数值默认 ×100 展示;「开始生成」时刻已移至"所属分组"后; 恒渲染占位,避免"有/无数据"导致卡片内部错位(用户要求布局固定) #} API 消耗 {% if item.token_wan %}{{ '%g'|format(item.token_wan) }} 万 tokens{% else %}—{% endif %} {% if item.workflow_active %}
生成进行中任务正在运行,完成后这里显示最终状态
{% elif item.workflow.status in ['failed', 'cancelled', 'interrupted'] %}
{% if item.workflow.status == 'failed' %}任务失败{% elif item.workflow.status == 'cancelled' %}任务已中断{% else %}任务异常停止{% endif %} {% if item.workflow.detail %}{{ item.workflow.detail }}{% endif %}
{% else %}
状态正常任务已完成,点击下方"进入"查看成片与详情
{% endif %}
{% endfor %}
“{{ selected_group_name }}”中暂无项目,可切换其他分组,或创建新项目后移动到这里。
{{ render_pagination_bar('bottom') }}
{% if _prof.eula_version and not _prof.eula_accepted %} {% endif %}
{% endblock %}