diff --git a/docs/API文档/Seedance 2.0 1080P.md b/docs/API文档/Seedance 2.0 1080P.md new file mode 100644 index 0000000..a713313 --- /dev/null +++ b/docs/API文档/Seedance 2.0 1080P.md @@ -0,0 +1,85 @@ +# [请填写客户名称]Seedance 2.0 1080P + +> 本文档仅供方舟保底客户查阅,请勿发给没有签约保底的客户 + +### 功能说明 + +⚠️❗️❗️:目前seedance2.0产出的1080p暂时无法支持产物受信功能,即seedance2.0产出的含有人脸的1080p视频将接受安全审查,如果您需要参考含有人脸的1080p视频,请您将该视频上传至虚拟素材库 + +#### **功能1 输出视频分辨率 支持 1080P** + +* **上线时间**:预计国内外4月16日22:00完成上线 + +* **用户范围**: + + * **“抢先体验计划”:功能上线后 72 小时内,部分用户可抢先体验**,官网文档暂不更新 + + * 72 小时后,面向全部用户开放,官网文档同步公开 + +* **支持模型**:仅限Seedance 2.0(Seedance 2.0 fast 不支持) + +* **使用方式:**在请求参数`resolution`中传入`1080p` + +```c++ +curl https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $ARK_API_KEY" \ + -d '{ + "model": "doubao-seedance-2-0-260128", + "content": [ + { + "type": "text", + "text": "全程使用视频1的第一视角构图,全程使用音频1作为背景音乐。第一人称视角果茶宣传广告,seedance牌「苹苹安安」苹果果茶限定款;首帧为图片1,你的手摘下一颗带晨露的阿克苏红苹果,轻脆的苹果碰撞声;2-4 秒:快速切镜,你的手将苹果块投入雪克杯,加入冰块与茶底,用力摇晃,冰块碰撞声与摇晃声卡点轻快鼓点,背景音:「鲜切现摇」;4-6 秒:第一人称成品特写,分层果茶倒入透明杯,你的手轻挤奶盖在顶部铺展,在杯身贴上粉红包标,镜头拉近看奶盖与果茶的分层纹理;6-8 秒:第一人称手持举杯,你将图片2中的果茶举到镜头前(模拟递到观众面前的视角),杯身标签清晰可见,背景音「来一口鲜爽」,尾帧定格为图片2。背景声音统一为女生音色。" + }, + { + "type": "image_url", + "image_url": { + "url": "https://ark-project.tos-cn-beijing.volces.com/doc_image/r2v_tea_pic1.jpg" + }, + "role": "reference_image" + }, + { + "type": "image_url", + "image_url": { + "url": "https://ark-project.tos-cn-beijing.volces.com/doc_image/r2v_tea_pic2.jpg" + }, + "role": "reference_image" + }, + { + "type": "video_url", + "video_url": { + "url": "https://ark-project.tos-cn-beijing.volces.com/doc_video/r2v_tea_video1.mp4" + }, + "role": "reference_video" + }, + { + "type": "audio_url", + "audio_url": { + "url": "https://ark-project.tos-cn-beijing.volces.com/doc_audio/r2v_tea_audio1.mp3" + }, + "role": "reference_audio" + } + ], + "resolution": "1080p", + "generate_audio":true, + "ratio": "16:9", + "duration": 11, + "watermark": false +}' +``` + +#### **功能2 输入视频分辨率 支持 1080P** + +* **功能说明**:对输入视频的总像素限制扩大至 2086876(2206x946),支持传入1080P视频作为参考 + +* **上线时间**:预计国内外4月16日 22:00 完成上线 + +* **用户范围**:全部用户可用,官网文档同步公开 + +* **支持模型**:Seedance 2.0、Seedance 2.0 fast 均支持 + +### 费用说明 + +1080P 和 720P/480P 视频区分定价 + +价格详见:https://www.volcengine.com/docs/82379/1544106?lang=zh#02affcb8 diff --git a/docs/API文档/old-Seedance 2.0 & 2.0 fast API文档(邀测用户版).md b/docs/API文档/old-Seedance 2.0 & 2.0 fast API文档(邀测用户版).md deleted file mode 100644 index 969cf38..0000000 --- a/docs/API文档/old-Seedance 2.0 & 2.0 fast API文档(邀测用户版).md +++ /dev/null @@ -1,692 +0,0 @@ -# 【申请权限填客户名称】Seedance 2.0 & 2.0 fast API文档(邀测用户版) - -该文档目前仅限开白客户使用,发送前请和销管确认客户是否在开白名单内 - -***【❗️❗️❗️】该文档限制客户申请权限,只有返回了服务协议的客户方可申请*** - -本文介绍 Seedance 2.0 & 2.0 fast 模型相较于存量模型 **新增/配置有区别 **的 API 参数介绍,存量 API 参数的完整介绍参见 [视频生成 API](https://www.volcengine.com/docs/82379/1520758?lang=zh)。 - -> 本文档仅限预览及邀测用户使用: -> -> * 不承诺正式API上线100%一致。 -> -> * 仅限邀测用户阅读,请勿截图/分享给其他人员。 -> -> * 您上传的内容请确保由您原创或已取得授权。 - -# 模型能力 - -> **Seedance 2.0 和 Seedance 2.0 fast 提供的模型能力一致,**追求最高生成品质,推荐使用 **Seedance 2.0**;更注重成本与生成速度,不要求极限品质,推荐使用 **Seedance 2.0 fast**。 - -**Seedance 2.0 & 2.0 fast (有声视频/无声视频)** - -* **多模态参考生视频**:输入参考图片(0\~9)+参考视频(0\~3)+ 参考音频(0\~3)+ 文本提示词(可选)生成 1 个目标视频。支持生成全新视频、编辑视频、延长视频。 - -> **注意:不可单独输入音频,应至少包含 1 个参考视频或图片。** - -* **图生视频-首尾帧**:输入首帧图片+尾帧图片+文本提示词(可选)生成 1 个目标视频。 - -* **图生视频-首帧**:输入首帧图片+文本提示词(可选)生成 1 个目标视频。 - -* **文生视频**:输入文本提示词生成 1 个目标视频。 - - - -**模型能力对比表:** - -| 模型名称 | | [Seedance 2.0](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-2-0) | [Seedance 2.0 fast](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-2-0-fast\&projectName=default) | [Seedance 1.5 pro](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-1-5-pro\&projectName=default) | [Seedance 1.0 pro ](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-1-0-pro\&projectName=default) | [Seedance 1.0 pro fast ](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-1-0-pro-fast\&projectName=default) | [Seedance 1.0 lite i2v](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-1-0-lite-i2v\&projectName=default) | [Seedance-1.0 lite t2v ](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-1-0-lite-t2v) | -| ------------ | -------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -| Model ID | | doubao-seedance-2-0-260128 | doubao-seedance-2-0-fast-260128 | doubao-seedance-1-5-pro-251215 | doubao-seedance-1-0-pro-250528 | doubao-seedance-1-0-pro-fast-251015 | doubao-seedance-1-0-lite-i2v-250428 | doubao-seedance-1-0-lite-t2v-250428 | -| 文生视频 | | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | -| 图生视频-首帧 | | ✅ | | ✅ | ✅ | ✅ | ✅ | ❌ | -| 图生视频-首尾帧 | | ✅ | | ✅ | ✅ | ❌ | ✅ | ❌ | -| 多模态参考【New】 | 图片参考 | ✅ | | ❌ | ❌ | ❌ | ✅ | ❌ | -| | 视频参考 | ✅ | | ❌ | ❌ | ❌ | ❌ | ❌ | -| | 组合参考 | ✅ | | ❌ | ❌ | ❌ | ❌ | ❌ | -| 编辑视频【New】 | | ✅ | | ❌ | ❌ | ❌ | ❌ | ❌ | -| 延长视频【New】 | | ✅ | | ❌ | ❌ | ❌ | ❌ | ❌ | -| 生成有声视频 | | ✅ | | ✅ | ❌ | ❌ | ❌ | ❌ | -| 联网搜索增强【New】 | | ✅ | | ❌ | [❌](https://p9-arcosite.byteimg.com/obj/tos-cn-i-goo7wpa0wc/f359753773c94d97885008ca1223c9bc) | ❌ | ❌ | ❌ | -| 样片模式 | | ❌ | | ✅ | ❌ | ❌ | ❌ | ❌ | -| 返回视频尾帧 | | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | -| 输出视频规格 | 输出分辨率 | 480p, 720p | | 480p, 720p, 1080p | 480p, 720p, 1080p | 480p, 720p, 1080p | 480p, 720p, 1080p | 480p, 720p, 1080p | -| | 输出宽高比 | 21:9, 16:9, 4:3, 1:1, 3:4, 9:16 | | | | | | | -| | 输出时长 | 4\~15 秒 | | 4\~12 秒 | 2\~12 秒 | 2\~12 秒 | 2\~12 秒 | 2\~12 秒 | -| | 输出视频格式 | mp4 | | mp4 | mp4 | mp4 | mp4 | mp4 | -| 离线推理 | | [❌](https://p9-arcosite.byteimg.com/obj/tos-cn-i-goo7wpa0wc/f359753773c94d97885008ca1223c9bc) | | ✅ | ✅ | ✅ | ✅ | ✅ | -| 在线推理限流 | RPM | 600 | | 600 | 600 | 600 | 300 | 300 | -| | 并发数 | 10 | | 10 | 10 | 10 | 5 | 5 | -| 离线推理限流 | TPD | - | | 5000亿 | 5000亿 | 5000亿 | 2500亿 | 2500亿 | - - - - - -# Creat-创建视频生成任务 - -> POST https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks - -## 请求参数 - - - -#### **content** `object[]` `必选` - -输入给模型,生成视频的信息,支持文本、图片、音频、视频、样片任务 ID。支持以下几种组合: - -* **文本** - -* **文本(可选)+ 图片** - -* **文本(可选)+ 视频** - -* **文本(可选)+ 图片 + 音频** - -* **文本(可选)+ 图片 + 视频** - -* **文本(可选)+ 视频 + 音频** - -* **文本(可选)+ 图片 + 视频 + 音频** - -*** - -**信息类型:** - -* **文本信息**`object` - -输入给模型的提示词信息。 - -*** - -content.**type **`string` `必选` - -输入内容的类型,此处应为 **text**。 - -*** - -content.**text **`string` `必选` - -输入给模型的文本提示词,描述期望生成的视频。 - -支持中英文。建议中文不超过500字,英文不超过1000词。字数过多信息容易分散,模型可能因此忽略细节,只关注重点,造成视频缺失部分元素。提示词的更多使用技巧请参见 [Seedance 提示词指南](https://www.volcengine.com/docs/82379/1587797)。 - - - - - -* **图片信息** `object` - -输入给模型的图片信息。 - -*** - -content.**type **`string` `必选` - -输入内容的类型,此处应为 **image\_url**。 - -*** - -content.**image\_url **`object` `必选` - -输入给模型的图片对象。 - -*** - -content.image\_url.**url **`string` `必选` - -图片 URL 、图片 Base64 编码、素材 ID。 - -* 图片 URL:填入图片的公网 URL。 - -* Base64 编码:将本地文件转换为 Base64 编码字符串,然后提交给大模型。遵循格式:data:image/<图片格式>;base64,\,注意 <图片格式> 需小写,如 data:image/png;base64,{base64\_image}。 - -* 素材 ID:用于视频生成的预置素材及虚拟人像的 ID,遵循格式:asset://\,可从 [素材&虚拟人像库](https://console.volcengine.com/ark-stg/region:ark-stg+cn-beijing/experience/vision?modelId=doubao-seedance-2-0-260128) 获取,详细使用请参见[文档](https://www.volcengine.com/docs/82379/2223965?lang=zh)。 - -> **传入单张图片要求** -> -> * 格式:jpeg、png、webp、bmp、tiff、gif -> -> * 宽高比(宽/高): (0.4, 2.5) -> -> * 宽高长度(px):(300, 6000) -> -> * 大小:单张图片小于 30 MB。请求体大小不超过 64 MB。大文件请勿使用Base64编码。 -> -> * 图片数量: -> -> * 图生视频-首帧:1 张 -> -> * 图生视频-首尾帧:2 张 -> -> * Seedance 2.0 & 2.0 fast 多模态参考生视频:1\~9 张 - -*** - -content.**role **`string` `条件必填` - -图片的位置或用途。 - -> **注意** -> -> * **图生视频-首帧**、**图生视频-首尾帧**、**多模态参考生视频**(包括参考图、视频、音频)为 3 种互斥场景,**不可混用**。 -> -> * **多模态参考生视频**可通过提示词指定参考图片作为首帧/尾帧,间接实现“首尾帧+多模态参考”效果。若需严格保障首尾帧和指定图片一致,**优先使用图生视频-首尾帧**(配置 role 为 **first\_frame / last\_frame**)。 - -*** - -**图生视频-首帧** - -> 需要传入1个 image\_url 对象 - -* **字段role取值:** - - * **first\_frame 或不填** - -*** - -**图生视频-首尾帧** - -> 需要传入2个 image\_url 对象 - -* **字段role取值:** - - * 首帧图片对应的字段 role 为:**first\_frame**,必填 - - * 尾帧图片对应的字段 role 为:**last\_frame**,必填 - -*** - -**图生视频-参考图 ** - -> 可传入 1\~9 个 image\_url 对象 - -* **字段role取值**: - - * 每张参考图对应的字段 role 均为:**reference\_image**,必填 - - - - - -* **视频信息** `object` - -输入给模型的视频信息。仅 Seedance 2.0 & 2.0 fast 支持输入视频。 - -*** - -content.**type **`string` `必选` - -输入内容的类型,此处应为 **video\_url**。 - -*** - -content.**video\_url **`object` `必选` - -输入给模型的视频对象。 - -*** - -content.video\_url.**url **`string` `必选` - -视频URL、素材 ID。 - -* 视频 URL:填入视频的公网 URL。 - -* 素材 ID:用于视频生成的预置素材及虚拟人像视频的 ID,遵循格式:asset://\。可从[素材&虚拟人像库](https://console.volcengine.com/ark-stg/region:ark-stg+cn-beijing/experience/vision?modelId=doubao-seedance-2-0-260128)获取。 - -> **传入单个视频要求** -> -> * 视频格式:mp4、mov。 -> -> * 分辨率:480p、720p -> -> * 时长:单个视频时长 \[2, 15] s,最多传入 3 个参考视频,所有视频总时长不超过 15s。 -> -> * 尺寸: -> -> * 宽高比(宽/高):\[0.4, 2.5] -> -> * 宽高长度(px):\[300, 6000] -> -> * 画面像素(宽 × 高):\[409600, 927408] ,示例: -> -> * 画面尺寸 640×640=409600 满足最小值 ; -> -> * 画面尺寸 834×1112=927408 满足最大值。 -> -> * 大小:单个视频不超过 50 MB。 -> -> * 帧率 (FPS):\[24, 60] - -*** - -content.**role **`string` `条件必填` - -视频的位置或用途。当前仅支持 **reference\_video**。 - - - - - -* **音频信息 **`object` - -输入给模型的音频信息。仅 Seedance 2.0 & 2.0 fast 支持输入音频。注意不可单独输入音频,应至少包含 1 个参考视频或图片。 - -*** - -content.**type **`string` `必选` - -输入内容的类型,此处应为 **audio\_url**。 - -*** - -content.**audio\_url **`object` `必选` - -输入给模型的音频对象。 - -*** - -content.audio\_url.**url **`string` `必选` - -音频 URL 、音频 Base64 编码、素材 ID。 - -* 音频 URL:填入音频的公网 URL。 - -* Base64 编码:将本地文件转换为 Base64 编码字符串,然后提交给大模型。遵循格式:data:audio/<音频格式>;base64,\,注意 <音频格式> 需小写,如 data:audio/wav;base64,{base64\_audio}。 - -* 素材 ID:用于视频生成的虚拟人的音频素材 ID,遵循格式:asset://\。可从[素材&虚拟人像库](https://console.volcengine.com/ark-stg/region:ark-stg+cn-beijing/experience/vision?modelId=doubao-seedance-2-0-260128)获取。 - -> **传入单个音频要求** -> -> * 格式:wav、mp3 -> -> * 时长:单个音频时长 \[2, 15] s,最多传入 3 段参考音频,所有音频总时长不超过 15 s。 -> -> * 大小:单个音频不超过 15 MB,请求体大小不超过 64 MB。大文件请勿使用Base64编码。 - -*** - -content.**role **`string` `条件必填` - -音频的位置或用途。当前仅支持 **reference\_audio** 。 - - - -#### **service\_tier** `string` - - Seedance 2.0 & 2.0 fast 暂不支持 - - - -#### **generate\_audio **`boolean` - -> Seedance 2.0 & 2.0 fast 默认值: true - -控制生成的视频是否包含与画面同步的声音。 - -* true:模型输出的视频包含同步音频。模型会基于文本提示词与视觉内容,自动生成与之匹配的人声、音效及背景音乐。建议将对话部分置于双引号内,以优化音频生成效果。例如:男人叫住女人说:“你记住,以后不可以用手指指月亮。” - -* false:模型输出的视频为无声视频。 - -> **说明** -> -> 生成的有声视频均为单声道,和传入的音频声道数无关。 - -#### - -#### **draft **`boolean` - - Seedance 2.0 & 2.0 fast 暂不支持 - - - -#### **tools **`object[]` - -> 仅 Seedance 2.0 & 2.0 fast 支持 - -配置模型要调用的工具。 - -*** - -tools.**type **`string` - -指定使用的工具类型。 - -* web\_search:联网搜索工具。 - -> **说明** -> -> * 开启联网搜索后,模型会根据用户的提示词自主判断是否搜索互联网内容(如商品、天气等)。可提升生成视频的时效性,但也会增加一定的时延。 -> -> * 实际搜索次数可通过 [查询视频生成任务 API](https://www.volcengine.com/docs/82379/1521309?lang=zh) 返回的 usage.tool\_usage.**web\_search** 字段获取,如果为 0 表示未搜索。 - - - -#### **resolution ** `string` - -> Seedance 2.0 & 2.0 fast 默认值:720p - -视频分辨率,取值范围: - -* 480p - -* 720p - - - -#### **ratio **`string` - -> Seedance 2.0 & 2.0 fast 默认值: adaptive - -生成视频的宽高比例。不同宽高比对应的宽高像素值见下方表格。 - -* 16:9 - -* 4:3 - -* 1:1 - -* 3:4 - -* 9:16 - -* 21:9 - -* adaptive:根据输入自动选择最合适的宽高比 - -> **adaptive 适配规则** -> -> 当配置 **ratio** 为 adaptive 时,模型会根据生成场景自动适配宽高比;实际生成的视频宽高比可通过 [查询视频生成任务 API](https://www.volcengine.com/docs/82379/1521309?lang=zh) 返回的 **ratio** 字段获取。 -> -> * 文生视频:根据输入的提示词,智能选择最合适的宽高比。 -> -> * 首帧 / 首尾帧生视频:根据上传的首帧图片比例,自动选择最接近的宽高比。 -> -> * 多模态参考生视频:根据用户提示词意图判断,如果是首帧生视频/编辑视频/延长视频,以该图片/视频为准选择最接近的宽高比;否则,以传入的第一个媒体文件为准(优先级:视频>图片)选择最接近的宽高比。 - -*** - -**不同宽高比对应的宽高像素值:** - -| 分辨率 | 宽高比 | 宽高像素值 | -| ---- | ---- | -------- | -| 480p | 16:9 | 864×496 | -| | 4:3 | 752×560 | -| | 1:1 | 640×640 | -| | 3:4 | 560×752 | -| | 9:16 | 496×864 | -| | 21:9 | 992×432 | -| 720p | 16:9 | 1280×720 | -| | 4:3 | 1112×834 | -| | 1:1 | 960×960 | -| | 3:4 | 834×1112 | -| | 9:16 | 720×1280 | -| | 21:9 | 1470×630 | - - - -#### **duration** `integer` - -> Seedance 2.0 & 2.0 fast 默认值:5 - -生成视频时长,仅支持整数,单位:秒。 - -取值范围: - -* \[4,15] 或设置为-1 - -> **配置方法** -> -> * 指定具体时长:支持有效范围内的任一整数。 -> -> * 智能指定:设置为 -1,表示由模型在有效范围内自主选择合适的视频长度(整数秒)。实际生成视频的时长可通过 [查询视频生成任务 API](https://www.volcengine.com/docs/82379/1521309?lang=zh) 返回的 **duration** 字段获取。注意视频时长与计费相关,请谨慎设置。 - - - -#### **frames** `integer` - -Seedance 2.0 & 2.0 fast 暂不支持 - - - -#### **camera\_fixed** `boolean` - - Seedance 2.0 & 2.0 fast 暂不支持 - - - -# Get/List-查询视频生成任务/列表 - -> 查询视频生成任务:GET https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks/{id} -> -> 查询视频生成任务列表:GET https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks?page\_num={page\_num}\&page\_size={page\_size}\&filter.status={filter.status}\&filter.task\_ids={filter.task\_ids}\&filter.model={filter.model} - -## 响应参数 - -#### **tools **`object[]` - -> 仅 Seedance 2.0 & 2.0 fast 支持 - -配置模型要调用的工具。 - -*** - -tools.**type **`string` - -指定使用的工具类型。 - -* web\_search:联网搜索工具。 - - - -#### **usage** `object` - -本次请求的 token 用量。 - -*** - -usage.**completion\_tokens** `integer` - -模型输出视频花费的 token 数量。 - -*** - -usage.**total\_tokens** `integer` - -本次请求消耗的总 token 数量。 - -*** - -usage.**tool\_usage **`object` - -> 仅 Seedance 2.0 & 2.0 fast 支持 - -使用工具的用量信息。 - -*** - -usage.tool\_usage.**web\_search **`integer` - -实际调用联网搜索工具的次数,仅开启联网搜索时返回。 - - - -# 调用简介及示例 - -## 流程简介 - -任务接口是异步接口,视频生成任务流程 - -1. 创建视频生成任务接口创建视频生成任务 - -2. 定时使用查询接口查询视频生成任务状态 - - 1. 任务 running,过段时间再查询任务状态 - - 2. 任务完成,返回视频链接,在24小时内下载生成的视频文件 - -## 1. 创建视频生成任务 - -> 以下示例仅展示 Seedance 2.0 & 2.0 fast 新增能力,更多视频生成示例详见 [创建视频生成任务 API](https://www.volcengine.com/docs/82379/1520757)。 - -### 多模态参考 - -### 编辑视频 - -### 延长视频 - -### 使用联网搜索 - -仅支持文本生视频 - -## 2. 查询视频生成任务 - -# 最佳实践-使用公共虚拟人像生成视频 - -平台提供公共虚拟人像素材库,目前您可以使用其中的图像素材来创建一个统一、完备的视频主角。帮助您更好地控制主角,并确保其形象在多段视频中保持一致,避免因为真人人脸限制导致角色无法统一的问题。 - -素材模态目前包含图片,并提供人物背景描述。每个素材对应一个独立素材 ID (asset ID),在体验中心的视频生成任务中,指定角色人脸生成视频。 - -1. 在浏览器中打开[体验中心](https://console.volcengine.com/ark/region:ark+cn-beijing/experience/vision?modelId=doubao-seedance-2-0-260128\&tab=GenVideo),点击输入框下方的 **虚拟人像库** 页签。 - -2. 检索需要使用的人像,支持使用自然语言检索及筛选框组合筛选。 - -| 输入:文本 | 输入:虚拟人像、图片 | 输出 | -| ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -- | -| **图片1**中美妆博主用中文进行介绍,妆容改为明艳大气,去掉脸部反光,笑容甜美,近景镜头,手持**图片2**的面霜面向镜头展示,清新简约背景,元气甜美风格。博主台词:挖到本命面霜了!质地像云朵一样软糯,一抹就吸收,熬夜急救、补水保湿全搞定,素颜都自带柔光感。 | ![Image Token: HTf6bPRukoWaW4xnCSlcvKtUn7c](images/HTf6bPRukoWaW4xnCSlcvKtUn7c.png)![Image Token: YfCDbzJlqo4yzZxCmdscWdsInCf](images/YfCDbzJlqo4yzZxCmdscWdsInCf.jpeg) | | - - - -在 [Video Generation API](https://www.volcengine.com/docs/82379/1520758) 的 **content.<模态>\_url.url** 字段中使用 素材 URI 生成视频。 - -> 输入的参考内容,包括人像素材,需符合视频生成限制,具体信息请查看使用限制。 -> -> **注意**: -> -> * 首次在 API 中使用虚拟人像素材 Asset URI 前,需先在[方舟体验中心](https://console.volcengine.com/ark/region:ark+cn-beijing/experience/vision?modelId=doubao-seedance-2-0-260128\&tab=GenVideo)提交一次视频生成任务,阅读并同意弹出的 **虚拟人像库使用协议**。 -> -> * 体验中心支持体验视频生成能力。默认单次生成 4 段视频,为节约成本,建议设置为每次生成 1 条,具体方式可参考[虚拟人像库](https://www.volcengine.com/docs/82379/2223965?lang=zh)。 - -同意协议的操作方式如下: - -![Image Token: LK8ybUN9Ko2KkQxq2FdclVQtnkh](images/LK8ybUN9Ko2KkQxq2FdclVQtnkh.gif) - -示例代码: - -# 使用自有虚拟人像素材生成视频(线下提交) - -方舟提供私域人像素材库,您可在视频生成中使用自有虚拟人物或真人(仅限素人)素材,生成短剧等更定制化的视频内容。平台将对您提供的素材进行审核,规避可能产生的法律风险。 - -* 自有素材需入库后使用,您可将虚拟人像或真人素材发送给销售代表,同时完成合规承诺函及其他证明材料的准备。 - -* 入库后,您可使用素材的 Asset ID,在视频生成 API 中使用自有素材。 - -> **重要**: -> -> * 对虚拟人像素材,您需签署虚拟人像素材合规承诺函,并提供签署承诺函所需的材料。 -> -> * 对真实人物素材,除承诺函外,您还需额外提供真人授权材料。 -> -> * 具体流程及所需材料,请和您的销售代表确认。 - -提交自有人像素材时,需按人物将素材分组: - -* 每个人物为一个素材组。 - -* 每组可包含多个素材文件,素材文件对应唯一 ID (asset ID)。 - -## 入库流程 - -提交自有虚拟人像素材方式大致如下,请联系您的销售代表了解详情。 - -1. 准备素材文件,完成承诺函签署,并准备其他证明材料。 - -2. 准备素材文件,完成承诺函签署,并准备其他证明材料。 - - * 每个人物素材需至少提供一张正面图片文件。此外,您可按需提供该人物的其他图片、视频素材。 - - * 需确保每个人物组中的素材与该正面图片为同一人物。 - - * 每个人物创建一个文件夹(命名:“*虚拟人像 1-<人像名>*”) - - 提交素材文件夹示例: - - ![Image Token: XMQ9bz6vhof7vxxsac8cqIZmneB](images/XMQ9bz6vhof7vxxsac8cqIZmneB.png) - - > **注意**: - > - > * 以上示例仅供参考,您可根据视频创作需求,提交虚拟人物素材。 - > - > * 您仅需上传视频生成任务中需要使用的素材。 - - * 素材文件需满足视频生成 API 对输入文件的要求: - - > **传入单张图片要求** - > - > * 格式:jpeg、png、webp、bmp、tiff、gif - > - > * 宽高比(宽/高): (0.4, 2.5) - > - > * 宽高长度(px):(300, 6000) - > - > * 大小:单张图片小于 30 MB。请求体大小不超过 64 MB。大文件请勿使用Base64编码。 - - - - > **传入单个视频要求** - > - > * 视频格式:mp4、mov。 - > - > * 分辨率:480p、720p - > - > * 时长:单个视频时长 \[2, 15] s,最多传入 3 个参考视频,所有视频总时长不超过 15s。 - > - > * 尺寸: - > - > * 宽高比(宽/高):\[0.4, 2.5] - > - > * 宽高长度(px):\[300, 6000] - > - > * 画面像素(宽 × 高):\[409600, 927408] ,示例: - > - > * 画面尺寸 640×640=409600 满足最小值 ; - > - > * 画面尺寸 834×1112=927408 满足最大值。 - > - > * 大小:单个视频不超过 50 MB。 - > - > * 帧率 (FPS):\[24, 60] - - - - > **注意**: - > - > 有关提交流程、承诺函签署所需材料的具体信息,请联系您的销售代表了解详情。 - -3. 方舟将对您提供的素材进行审核,通过审核的素材将被上传至虚拟人像库。 - -4. 入库后,每个人物组素材将通过以下示例中的形式返回,您可解压后查看: - - ![Image Token: PKu6b3391oUbVKxxEGjchxBVnbg](images/PKu6b3391oUbVKxxEGjchxBVnbg.png) - -示例中: - -* Andy 为您提交的人物名称 - -* group-20260310035119-9mzqn 为该人物组的 ID - -* 解压后,可查看每张素材的 Asset ID,如: - -![Image Token: VV0ybrxNfouEhZxTjqCcX1epnzb](images/VV0ybrxNfouEhZxTjqCcX1epnzb.png) - -* 您可按 `asset: //` 规则拼接 URI,在 API 中使用对应素材生成视频: - -具体调用方式请参考 [最佳实践-使用虚拟人像生成视频](https://bytedance.larkoffice.com/wiki/SANpwJ9bgiKgrykLaMTcAB0InWc#share-YurKdrLfAocLErxsTWDcKidPnGd)。 - -## **注意事项** - -1. 首次在 API 中使用虚拟人像素材 Asset URI 前,需先在[方舟体验中心](https://console.volcengine.com/ark/region:ark+cn-beijing/experience/vision?modelId=doubao-seedance-2-0-260128\&tab=GenVideo)提交一次视频生成任务,阅读并同意弹出的 **虚拟人像库使用协议**,操作方式如下: - -![Image Token: IFfPbDgceoFXZCxdriIcnwkPnUc](images/IFfPbDgceoFXZCxdriIcnwkPnUc.gif) - -* 仅支持使用已入库素材生成视频。 diff --git a/docs/API文档/old-「保密信息」【申请权限填客户名称】Assets API 参考文档(邀测用户版).md b/docs/API文档/old-「保密信息」【申请权限填客户名称】Assets API 参考文档(邀测用户版).md deleted file mode 100644 index 75cb4f3..0000000 --- a/docs/API文档/old-「保密信息」【申请权限填客户名称】Assets API 参考文档(邀测用户版).md +++ /dev/null @@ -1,1201 +0,0 @@ -# 「⚠️保密信息」【申请权限填客户名称】Assets API 参考文档(邀测用户版) - -本文介绍素材资产(Assets)API 接口的参数。您可以使用以下 Assets API 接口创建、管理个人人像素材资产。 - -> 本文档仅限预览及邀测用户使用: -> -> * 不承诺正式 API 上线100%一致。 -> -> * 仅限邀测用户阅读,请勿截图/分享给其他人员。 -> -> * 您需确保上传的虚拟人像符合以下条件: -> -> * 您合法拥有该素材,并享有完整的使用及处分权限。素材不包含未获授权的第三方商标、标识类内容。 -> -> * 素材不得与任何自然人肖像或形象雷同,素材不存在抄袭、盗用情形,不会侵害任何第三方的人格权、知识产权等合法权益。 -> -> * 素材不包含违反法规、违背公序良俗、危害国家安全的内容。 - - - -# 素材资产(Assets)API 接口功能 - -> **素材资产的概念说明:** -> -> * **Asset(素材资产)**:一个素材文件(图片),是方舟 Seedance 2.0 系列模型可直接用于推理的可信资产。 -> -> * 仅需入库推理需使用的素材资产,不需使用的素材资产请勿入库。 -> -> * 仅可使用已入库素材资产的 Id (Asset ID) 进行视频生成,同一形象未入库素材无法使用。 -> -> * **Asset Group(素材资产组合)**:单个素材文件为一个 Asset,每个 Asset 属于一个 Asset Group。 -> -> * 可以使用素材组自由管理素材,例如可将同一人物、同一工作室或项目组的素材放入同一素材组合进行管理。 - -**Asset (Group) 创建接口:** - -1. CreateAssetGroup:创建素材资产组合。**首次创建素材资产组合时需在控制台签署授权函,详情参考 [ 私域虚拟人像素材库 (WIP)](https://bytedance.larkoffice.com/wiki/RtHgwpJgviwFXLkQ9hLcRooEnVe)** - -2. CreatAsset:创建素材资产。该接口可用于上传个人素材资产,创建素材资产后可利用返回字段中的素材 **Id (需处于 `active` 状态)**用于 Seedance 2.0 系列模型生成视频。 - - - -**Asset (Group) 管理接口:** - -* ListAssetGroups:查询素材资产组合列表。 - -* ListAssets:查询素材资产列表。 - -* GetAsset:查询素材资产信息。 - -* GetAssetGroup:查询素材资产组合信息。 - -* UpdateAssetGroup:更新素材资产组合信息。 - -* UpdateAsset:更新素材资产信息。 - - - -# 鉴权方式 - -调用素材资产(Assets)API 接口需使用 Access Key 鉴权,详情参考 [获取 API 访问密钥(AK/SK)](https://www.volcengine.com/docs/6257/64983?lang=zh)。 - - - -# 限流要求 - -* 并发数限制:账号下同一时刻在处理中的任务数量上限,超过此限制的任务将进入队列等待处理。**同时进行处理的asset创建任务不超过30。** - -* QPS 限流: API接口每秒查询请求的总数上限。超过此限制的查询请求会报错。 - -| 接口名 | 账号维度的 QPS 限流 | -| ---------------- | ------------ | -| CreateAssetGroup | 30 | -| CreateAsset | 30 | -| ListAssetGroups | 30 | -| ListAssets | 30 | -| GetAsset | 100 | -| GetAssetGroup | 100 | -| UpdateAsset | 30 | -| UpdateAssetGroup | 30 | - -# CreateAssetGroup - -> **POST **/open/CreateAssetGroup - -创建 Asset Group(素材资产组合)组合,用作素材资产管理。 - -> **首次创建 Asset Group(素材资产组合)需在控制台签署授权函,详情参考 [ 私域虚拟人像素材库 (WIP)](https://bytedance.larkoffice.com/wiki/RtHgwpJgviwFXLkQ9hLcRooEnVe)** - -### **Name** `string` `必填` - -Asset Group(素材资产组合)的名称,上限为 64 字符。 - -*** - -### **Description** `string` - -Asset Group(素材资产组合)的描述,上限为 300 字符。 - -*** - -### **GroupType **`string` - -Asset Group(素材资产组合)的类型。可选值: - -* AIGC:虚拟人像。 - -*** - -### **ProjectName **`string`** ** - -资源所属的项目名称,默认值为`default`。 - -若资源不在默认项目中,需填写正确的项目名称,获取项目名称,请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。 - -*** - - - -## 返回参数 - -### **Id** `string` - -Asset Group(素材资产组合)的 Id。 - -*** - -返回示例: - -```bash -{ - "Id": "group-2026**********-*****" -} -``` - - - -# CreateAsset - -> **POST **/open/CreateAsset - -向指定的Asset Group(素材资产组合)内创建Asset(素材资产)。 - - - -## 请求参数 - -### **GroupId** `string` `必填` - -Asset(素材资产)所属的 Asset Group(素材资产组合)的 Id。 - -*** - -### **URL** `string` `必填` - -传入的Asset(素材资产)的公共可访问地址。 - -*** - -### **Name** `string` - -Asset(素材资产)的名称,上限为64个字符。 - -*** - -### **AssetType `string` `必填`** - -Asset(素材资产)的类型,当前仅支持传入图像。可选值: - -* Image:Asset(素材资产)的类型为图像。 - -> **传入图像的要求说明** -> -> * 格式:jpeg、png、webp、bmp、tiff、gif、heic/heif -> -> * 宽高比(宽/高): (0.4, 2.5) -> -> * 宽高长度(px):(300, 6000) -> -> * 大小:单张图片小于 30 MB。 - -*** - -### **ProjectName** `string` - -资源所属的项目名称,默认值为`default`。 - -若资源不在默认项目中,需填写正确的项目名称,获取项目名称,请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。 - -> 需要和待传入的 Asset Group(素材资产组合)的 **ProjectName **保持一致。 - -*** - - - -## 返回参数 - -### **Id **`string` - -Asset(素材资产)的 Id。 - -*** - -返回示例: - -```bash -{ - "Id": "Asset-2026**********-*****" -} -``` - - - -# ListAssets - -> **POST **/open/ListAssets - -查询符合筛选条件的Assets(素材资产)列表。 - -## 请求参数 - -### **Filter** `object` `必填` - -搜索的过滤条件。 - -*** - -Filter.**GroupIds** `array` - -Asset(素材资产)所属的 Asset Group(素材资产组合)的 Id。 - -*** - -Filter.**GroupType** `string` `必填` - -Asset Group(素材资产组合)的类型。可选值: - -* AIGC:虚拟人像。 - -*** - -Filter.**Statuses** `array`** ** - -任务状态。 - -* Active:素材资产(Asset)已处理完毕,可以使用。 - -* Processing:素材资产(Asset)正在预处理,无法使用。 - -* Failed:素材资产(Asset)处理失败。 - -*** - -Filter.**Name** `string`** ** - -Asset(素材资产)的名称,上限为64个字符。 - -*** - -### **PageNumber** `int (i64)` `必填` - -搜索页码,可用于列表分页功能,从 1 开始。例如:"page\_number": 1,即返回第一页的搜索结果。 - -*** - -### **PageSize** `int (i64)` `必填` - -每页搜索结果的数量,上限为100。 - -*** - -### **SortBy** `string` - -用于排序的字段名称,默认值 `createTime`。支持以下类型: - -* CreateTime:根据创建时间排序。 - -* UpdateTime:根据更新时间排序。 - -* GroupId:根据资产素材组的 Id 排序。 - -*** - -### **SortOrder** `string` - -排序顺序,默认值 `Desc`。可选值: - -* Desc:降序 - -* Asc:升序 - -*** - -### **ProjectName** `string` - -资源所属的项目名称,默认值为`default`。 - -若资源不在默认项目中,需填写正确的项目名称,获取项目名称,请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。 - -*** - - - -## 返回参数 - -### **Items** `array[]` - -符合筛选条件的Asset(素材资产)数组。 - -*** - -Items.**Id** `string` - -Asset(素材资产)的 Id。 - -*** - -Items.**name** `string` - -Asset(素材资产)的名称,上限为64个字符。 - -*** - -Items.**URL** `string` - -Asset(素材资产)的公共可访问地址。 - -*** - -Items.**GroupId** `string` - -Asset(素材资产)所属的 Asset Group(素材资产组合)的 Id。 - -*** - -Items.**AssetType** `string` - -Asset(素材资产)的类型。 - -* Image:Asset(素材资产)的类型为图像。 - -*** - -Items.**Status** `string` - -任务状态。 - -* Active:素材资产(Asset)已处理完毕,可以使用。 - -* Processing:素材资产(Asset)正在预处理,无法使用。 - -* Failed:素材资产(Asset)处理失败。 - -*** - -Items.**Error** `object` - -错误信息。 - -*** - -Items.Error.**Code** `string` - -错误码。 - -*** - -Items.Error.**Message** `string` - -错误信息。 - -*** - -Items.**ProjectName** `string` - -资源所属的项目名称。 - -*** - -Items.**CreateTime **`string` - -创建时间。 - -*** - -Items.**UpdateTime **`string` - -更新时间。 - -*** - -### **TotalCount **`int (i64)` - -返回总数。 - -*** - -### **PageNumber **`int (i64)` - -返回的页数。 - -*** - -### **PageSize **`int (i64)` - -每页搜索结果的数量,上限为100。 - - - -# ListAssetGroups - -> **POST **/open/ListAssetGroups - -查询符合筛选条件的Asset Groups(素材资产组合)列表。 - -## 请求参数 - -### **Filter** `object` `必填` - -搜索的过滤条件。 - -*** - -Filter.**name** `string` - -Asset Group(素材资产组合)的名称,上限为64个字符。 - -*** - -Filter.**GroupIds** `array` - -Asset(素材资产)所属的 Asset Group(素材资产组合)的 Id。 - -*** - -Filter.**GroupType** `string`** **`必填` - -Asset Group(素材资产组合)的类型。可选值: - -* AIGC:虚拟人像。 - -*** - -### **PageNumber** `int (i64)` - -搜索页码,可用于列表分页功能,从 1 开始。例如:"page\_number": 1,即返回第一页的搜索结果。 - -*** - -### **PageSize** `int (i64)` - -每页搜索结果的数量,上限为100。 - -*** - -### **SortBy** `string` - -用于排序的字段名称,默认值 `createTime`。支持以下类型: - -* CreateTime:根据创建时间排序。 - -* UpdateTime:根据更新时间排序。 - -*** - -### **SortOrder** `string` - -排序顺序,默认值 `Desc`。可选值: - -* Desc:降序 - -* Asc:升序 - -*** - -### **ProjectName** `string` - -资源所属的项目名称,默认值为`default`。 - -若资源不在默认项目中,需填写正确的项目名称,获取项目名称,请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。 - -*** - - - -## 返回参数 - -### **TotalCount **`int (i64)` - -返回的 Asset Group(素材资产组合)的总数。 - -*** - -### **Items** `array[]` - -符合筛选条件的 Asset Group(素材资产组合)数组。 - -*** - -Items.**Id** `string` - -Asset Group(素材资产组合)的 Id。 - -*** - -Items.**Name** `string` - -Asset Group(素材资产组合)的名称,上限为64个字符。 - -*** - -Items.**Title** `string` - -Asset Group(素材资产组合)的标题。 - -> 即将下线,请直接使用参数 Name - -*** - -Items.**Description** `string` - -Asset Group(素材资产组合)的描述,上限为 300 字符。 - -*** - -Items.**GroupType** `string` - -Asset Group(素材资产组合)的类型。 - -* AIGC:虚拟人像。 - -*** - -Items.**ProjectName** `string` - -资源所属的项目名称。 - -*** - -Items.**CreateTime** `string` - -创建时间。 - -*** - -Items.**UpdateTime** `string` - -更新时间。 - -*** - -### **PageNumber **`int (i64)` - -返回的页数。 - -*** - -### **PageSize **`int (i64)` - -每页搜索结果的数量,上限为100。 - -*** - - - -# GetAssetGroup - -> **POST **/open/GetAssetGroup - -获取单个Asset Group(素材资产组合)信息。 - -## 请求参数 - - - -### **Id **`string` `必填` - -Asset Group(素材资产组合)的 Id - -*** - -### **ProjectName **`string` - -需要查询的 Asset Group(素材资产组合)所属的项目名称,默认值为`default`。 - -若资源不在默认项目中,需填写正确的项目名称,获取项目名称,请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。 - -*** - - - -## 返回参数 - -### **Id** `string` - -Asset Group(素材资产组合)的 Id。 - -*** - -### **Name** `string` - -Asset Group(素材资产组合)的名称,上限为64个字符。 - -*** - -### **Title** `string` - -Asset Group(素材资产组合)的标题。 - -> 即将下线,请直接使用参数 Name - -*** - -### **Description** `string` - -Asset Group(素材资产组合)的描述,上限为 300 字符。 - -*** - -### **GroupType **`string` - -Asset Group(素材资产组合)的类型。 - -* AIGC:虚拟人像 - -*** - -### **ProjectName **`string`** ** - -资源所属的项目名称。 - -*** - -### **CreateTime **`string` - -创建时间。 - -*** - -### **UpdateTime **`string` - -更新时间。 - -*** - -## - -# GetAsset - -> **POST **/open/GetAsset - -获取单个Asset(素材资产)信息。 - -## 请求参数 - - - -### **Id **`string` `必填` - -Asset(素材资产)的 Id。 - -*** - -### **ProjectName **`string` - -需要查询的 Asset(素材资产)所属的项目名称,默认值为`default`。 - -若资源不在默认项目中,需填写正确的项目名称,获取项目名称,请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。 - -*** - - - -## 返回参数 - -### **Id **`string` - -Asset(素材资产)的 Id。 - -*** - -### **Name** `string` - -Asset(素材资产)的名称,上限为64个字符。 - -*** - -### **URL **`string` - -Asset(素材资产)的访问地址。 - -*** - -### **AssetType **`string` - -Asset(素材资产)的类型。 - -* Image:Asset(素材资产)的类型为图像。 - -*** - -### **GroupId** `string` - -Asset(素材资产)所属的 Asset Group(素材资产组合)的 Id。 - -*** - -### **Status** `string` - -任务状态。 - -* Active:素材资产(Asset)已处理完毕,可以使用。 - -* Processing:素材资产(Asset)正在预处理,无法使用。 - -* Failed:素材资产(Asset)处理失败。 - -*** - -### **Error** `object` - -错误信息。 - -*** - -Error.**Code** `string` - -错误码。 - -*** - -Error.**Message** `string` - -错误信息。 - -*** - -### **CreateTime **`string` - -创建时间。 - -*** - -### **UpdateTime ** `string` - -更新时间。 - -*** - -### **ProjectName** `string` - -资源所属的项目名称。 - -*** - -## - -# **UpdateAssetGroup** - -> **POST **/open/UpdateAssetGroup - -更新单个 Asset Group(素材资产组合)信息。当前仅支持更新 Asset Group(素材资产组合)的 Name 和 Description。 - -## 请求参数 - -### **Id **`string` `必填` - -需要更新的 Asset Group(素材资产组合)的 Id - -*** - -### **Name **`string` - -需要更新的 Asset Group(素材资产组合)的新名称,上限为64个字符。 - -*** - -### **Description** `string` - -需要更新的 Asset Group(素材资产组合)的新描述,上限为 300 字符。 - -*** - -### **ProjectName** `string` - -需要更新的 Asset Group(素材资产组合)所属的项目名称,默认值为`default`。 - -若资源不在默认项目中,需填写正确的项目名称,获取项目名称,请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。 - -*** - - - -## 返回参数 - -### **Id** `string` - -Asset Group(素材资产组合)的 Id。 - -*** - - - - - -# **UpdateAsset** - -> **POST **/open/UpdateAsset - -更新单个Asset(素材资产)信息。当前仅支持更新Asset(素材资产)的 Name。 - -## 请求参数 - -### **Id **`string` `必填` - -需要更新的 Asset(素材资产)的 Id - -*** - -### **Name **`string` - -需要更新的 Asset(素材资产)的新名称,上限为64个字符。 - -*** - -### **ProjectName** `string` - -需要更新的 Asset(素材资产)所属的项目名称,默认值为`default`。 - -若资源不在默认项目中,需填写正确的项目名称,获取项目名称,请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。 - -*** - - - -## 返回参数 - -### **Id** `string` - -Asset(素材资产)的 Id。 - -*** - - - -# 代码示例: - -> **以下示例为使用 Asset API 创建素材资产并用于视频生成的使用链路:** -> -> 1. **创建素材资产组合:**调用 **CreateAssetGroup** 接口创建一个素材资产组合(Asset Group),用于对同一项目或人物的素材进行统一管理。首次创建时需在控制台签署授权函。 -> -> 2. **上传素材资产并等待预处理完成:**调用 **CreateAsset** 接口上传图片素材,传入图片的公共访问URL及所属的Group ID,获得素材资产ID(Asset ID)。 -> 由于上传的素材资产需经过预处理后才能使用,可轮询调用 **GetAsset** 接口查询素材状态,直至状态变为 `Active`。若状态为 `Failed` 则表示处理失败。 -> -> 3. **在视频生成 API 中使用素材:**当素材资产状态为 `Active` 后,将素材ID按 `Asset://` 的格式拼接成URL,在视频生成API(如Seedance 2.0系列模型)的请求中,将该URL作为参考图像的 `image_url` 传入,即可使用该素材资产生成视频。 -> -> **API 鉴权方式区别说明** -> -> * **Asset API:**Access Key 鉴权,详情参考 [获取 API 访问密钥(AK/SK)](https://www.volcengine.com/docs/6257/64983?lang=zh)。 -> -> * **视频生成 API:**API Key 鉴权,详情参考 [管理 API Key](https://www.volcengine.com/docs/82379/1361424?lang=zh)。 -> -> **素材库[项目](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)(Project)隔离说明** -> -> * 向指定的 Asset Group(素材资产组合)内创建或查询 Asset(素材资产)时,需保证两者的 **ProjectName **一致 -> -> * Asset(素材资产)所属的 **ProjectName** 需与调用视频生成 API 接口时使用的 API key 所属的 **ProjectName** 一致 - -## 1. 创建素材资产组合 - -```go -package main - -import ( - "fmt" - - "github.com/bytedance/sonic" - "github.com/volcengine/volcengine-go-sdk/volcengine" - "github.com/volcengine/volcengine-go-sdk/volcengine/credentials" - "github.com/volcengine/volcengine-go-sdk/volcengine/session" - "github.com/volcengine/volcengine-go-sdk/volcengine/universal" -) - -func main() { - config := volcengine.NewConfig().WithCredentials(credentials.NewStaticCredentials("", "", "")).WithRegion("cn-beijing") - sess, _ := session.NewSession(config) - resp, err := universal.New(sess).DoCall( - universal.RequestUniversal{ - ServiceName: "ark", - Action: "CreateAssetGroup", - Version: "2024-01-01", - HttpMethod: universal.POST, - ContentType: universal.ApplicationJSON, - }, - //根据实际情况填写 - &map[string]any{ - "Name": "test", - "Description": "test", - "GroupType": "AIGC", - }, - ) - if err != nil { - return - } - if resp == nil { - return - } - respData, err := sonic.Marshal(resp) - fmt.Println(string(respData)) -} -``` - -返回示例 - -```json -{"ResponseMetadata":{"RequestId":"20260318155041036F7CB6362358FB40FC","Action":"CreateAssetGroup","Version":"2024-01-01","Service":"ark","Region":"cn-beijing"},"Result":{"Id":"group-2026**********-*****"}} -``` - - - -## 2. 上传素材资产并获取素材资产信息 - -```go -package main - -import ( - "errors" - "fmt" - "time" - - "github.com/bytedance/sonic" - "github.com/volcengine/volcengine-go-sdk/volcengine" - "github.com/volcengine/volcengine-go-sdk/volcengine/credentials" - "github.com/volcengine/volcengine-go-sdk/volcengine/session" - "github.com/volcengine/volcengine-go-sdk/volcengine/universal" -) - -const ( - region = "cn-beijing" - serviceName = "ark" - version = "2024-01-01" - - // 轮询配置 - pollInterval = 3 * time.Second - pollTimeout = 2 * time.Minute -) - -func main() { - // TODO: 替换为你的 AK / SK - ak := "" - sk := "" - - // TODO: 替换为你的实际参数 - groupID := "" - assetURL := "" - assetType := "Image" - projectName := "Default" - - config := volcengine.NewConfig(). - WithCredentials(credentials.NewStaticCredentials(ak, sk, "")). - WithRegion(region) - - sess, err := session.NewSession(config) - if err != nil { - fmt.Printf("create session failed: %v\n", err) - return - } - - client := universal.New(sess) - - // 1. 创建素材资产 - assetID, err := createAsset(client, groupID, assetURL, assetType, projectName) - if err != nil { - fmt.Printf("create asset failed: %v\n", err) - return - } - - fmt.Printf("asset created, AssetId = %s\n", assetID) - - // 2. 查询素材资产状态 - finalURL, err := waitForAssetActive(client, assetID, pollInterval, pollTimeout) - if err != nil { - fmt.Printf("poll asset failed: %v\n", err) - return - } - - fmt.Printf("asset is active, URL = %s\n", finalURL) -} - -// createAsset 调用 CreateAsset 并返回 AssetId -func createAsset(client *universal.Universal, groupID, url, assetType, projectName string) (string, error) { - resp, err := client.DoCall( - universal.RequestUniversal{ - ServiceName: serviceName, - Action: "CreateAsset", - Version: version, - HttpMethod: universal.POST, - ContentType: universal.ApplicationJSON, - }, - &map[string]any{ - "GroupId": groupID, - "URL": url, - "AssetType": assetType, - "ProjectName": projectName, - }, - ) - if err != nil { - return "", err - } - if resp == nil { - return "", errors.New("create asset response is nil") - } - - // 打印原始返回,便于排查 - respData, _ := sonic.Marshal(resp) - fmt.Printf("CreateAsset response: %s\n", string(respData)) - - assetID := extractString(resp, "Result", "Id") - if assetID == "" { - assetID = extractString(resp, "Result", "AssetId") - } - if assetID == "" { - assetID = extractString(resp, "Id") - } - if assetID == "" { - assetID = extractString(resp, "AssetId") - } - - if assetID == "" { - return "", fmt.Errorf("cannot find AssetId in response: %s", string(respData)) - } - - return assetID, nil -} - -// waitForAssetActive 查询 GetAsset,直到 Active / Failed / 超时 -func waitForAssetActive(client *universal.Universal, assetID string, interval, timeout time.Duration) (string, error) { - deadline := time.Now().Add(timeout) - - for { - if time.Now().After(deadline) { - return "", fmt.Errorf("polling timeout after %v, assetID=%s", timeout, assetID) - } - - status, url, errMsg, err := getAssetStatus(client, assetID) - if err != nil { - return "", err - } - - fmt.Printf("asset status: %s\n", status) - - switch status { - case "Processing": - time.Sleep(interval) - continue - case "Active": - if url == "" { - return "", fmt.Errorf("asset is Active but URL is empty, assetID=%s", assetID) - } - return url, nil - case "Failed": - if errMsg == "" { - errMsg = "unknown asset processing error" - } - return "", fmt.Errorf("asset processing failed: %s", errMsg) - default: - // 若返回其他状态,保守处理为继续查询 - fmt.Printf("unexpected status %q, continue polling...\n", status) - time.Sleep(interval) - } - } -} - -// getAssetStatus 调用 GetAsset,返回 Status / URL / Error -func getAssetStatus(client *universal.Universal, assetID string) (status, url, errMsg string, err error) { - resp, err := client.DoCall( - universal.RequestUniversal{ - ServiceName: serviceName, - Action: "GetAsset", - Version: version, - HttpMethod: universal.POST, - ContentType: universal.ApplicationJSON, - }, - &map[string]any{ - "Id": assetID, - }, - ) - if err != nil { - return "", "", "", err - } - if resp == nil { - return "", "", "", errors.New("get asset response is nil") - } - - // 打印原始返回,便于排查 - respData, _ := sonic.Marshal(resp) - fmt.Printf("GetAsset response: %s\n", string(respData)) - - // 兼容不同层级的字段位置 - status = extractString(resp, "Result", "Status") - if status == "" { - status = extractString(resp, "Status") - } - - url = extractString(resp, "Result", "URL") - if url == "" { - url = extractString(resp, "URL") - } - - errMsg = extractString(resp, "Result", "Error") - if errMsg == "" { - errMsg = extractString(resp, "Error") - } - - return status, url, errMsg, nil -} - -// extractString 从响应中按层级安全提取字符串 -func extractString(data any, keys ...string) string { - current := data - - for _, key := range keys { - switch v := current.(type) { - case map[string]any: - next, ok := v[key] - if !ok { - return "" - } - current = next - - case *map[string]any: - if v == nil { - return "" - } - next, ok := (*v)[key] - if !ok { - return "" - } - current = next - - default: - return "" - } - } - - switch v := current.(type) { - case string: - return v - case fmt.Stringer: - return v.String() - case nil: - return "" - default: - return fmt.Sprintf("%v", v) - } -} -``` - -返回示例 - -```json -CreateAsset response: {"ResponseMetadata":{"RequestId":"202603181520431F067112A17FC078A6DF","Action":"CreateAsset","Version":"2024-01-01","Service":"ark","Region":"cn-beijing"},"Result":{"Id":"Asset-2026**********-*****"}} -asset created, AssetId = asset-20260318072044-n8bcl -GetAsset response: {"ResponseMetadata":{"Service":"ark","Region":"cn-beijing","RequestId":"202603181520448A995106924553F77D0E","Action":"GetAsset","Version":"2024-01-01"},"Result":{"Name":"","GroupId":"group-2026**********-*****","CreateTime":"2026-03-18T07:20:44Z","ProjectName":"default","Id":"Asset-2026**********-*****","URL":"","AssetType":"Image","Status":"Processing","UpdateTime":"2026-03-18T07:20:44Z"}} -asset status: Processing -GetAsset response: {"Result":{"UpdateTime":"2026-03-18T07:20:47Z","ProjectName":"default","Id":"Asset-2026**********-*****","CreateTime":"2026-03-18T07:20:44Z","Name":"","URL":"","AssetType":"Image","GroupId":"group-2026**********-*****","Status":"Processing"},"ResponseMetadata":{"Version":"2024-01-01","Service":"ark","Region":"cn-beijing","RequestId":"2026031815204766FE2BA543E6FF666F66","Action":"GetAsset"}} -asset status: Processing -GetAsset response: {"ResponseMetadata":{"Version":"2024-01-01","Service":"ark","Region":"cn-beijing","RequestId":"202603181520511F067112A17FC078A75A","Action":"GetAsset"},"Result":{"Name":"","URL":"https://ark-media-asset-stg.tos-cn-beijing.volces.com/xxxx","AssetType":"Image","Status":"Active","Id":"Asset-2026**********-*****","GroupId":"group-2026**********-*****","CreateTime":"2026-03-18T07:20:44Z","UpdateTime":"2026-03-18T07:20:47Z","ProjectName":"default"}} -asset status: Active -asset is active, URL = https://ark-media-asset-stg.tos-cn-beijing.volces.com/xxxx -``` - - - -更多语言的示例代码详见: - -> 注意替换 Demo 中的 AK与SK,若需调用其他接口如 ListAssets,需替换 ACTION 与对应请求参数。 - -| **Python** | 创建素材资产组合: 上传素材资产并获取素材资产信息: | -| ---------- | --------------------------- | -| **Java** | 创建素材资产组合: 上传素材资产并获取素材资产信息: | -| **PHP** | 创建素材资产组合: 上传素材资产: | - - - -## 3. 素材资产用于视频生成 - -当上传的素材资产状态为 `Active` 时,可将素材 Id 按 `Asset: //` 的规则拼接 URL,以在 **视频生成 API **中使用对应的素材资产生成视频: - -```json - { - "type": "image_url", - "image_url": { - "url": "Asset://Asset-2026**********-*****" - }, - "role": "reference_image" - }, -``` - -使用素材资产生成视频的具体调用方式请参考[ 【申请权限填客户名称】Seedance 2.0 & 2.0 fast API文档(邀测用户版)](https://bytedance.larkoffice.com/wiki/SANpwJ9bgiKgrykLaMTcAB0InWc#share-ONSwd51ezoXCJqxkAm2cIC61nMX)。 - diff --git a/docs/API文档/seedance 2.0 系列教程.md b/docs/API文档/seedance 2.0 系列教程.md new file mode 100644 index 0000000..1b9e418 --- /dev/null +++ b/docs/API文档/seedance 2.0 系列教程.md @@ -0,0 +1,2233 @@ +seedance 2.0 系列模型(包括 seedance 2.0 和 seedance 2.0 fast )支持图像、视频、音频、文本等多种模态内容输入,具备视频生成、视频编辑、视频延长等能力,可高精度还原物品细节、音色、效果、风格、运镜等,保持稳定角色特征,赋予使用者如同导演般的掌控权。本文介绍 seedance 2.0 系列模型的专属能力,帮助您快速实现 [Video Generation API](https://www.volcengine.com/docs/82379/1520758) 调用。 +:::tip +请确保您的账户余额大于等于 200 元([前往充值](https://console.volcengine.com/finance/fund/recharge)),或已[购买资源包](https://console.volcengine.com/common-buy/fast/ark_bd%7C%7Cd682ppeeq1mp7kd5q0e0),否则无法开通 seedance 2.0 及 seedance 2.0 fast 模型。 +::: + +# 新手入门 +本入门教程专为 **API 新手用户** 设计,帮助您一键搭建 Python 开发环境、完成虚拟环境创建和方舟 SDK 安装,并提供直接可运行的 seedance 2.0 示例代码,您只需修改对应的输入素材,即可开始您的视频生成创作。 +**1. 准备工作** +在开始之前,请确保您已经完成以下准备: + +1. **注册账号**:确保您拥有火山引擎账号并已[登录](https://console.volcengine.com/)。 +2. **获取 API Key**:访问 [API Key 管理页面](https://console.volcengine.com/ark/region:ark+cn-beijing/apikey),点击 **创建 API Key**,并复制保存您的 API Key。注意请妥善保管您的 API Key,不要泄露给他人。 +3. [开通模型](https://console.volcengine.com/ark/region:ark+cn-beijing/openManagement?LLM=%7B%7D&advancedActiveKey=model&projectName=default&tab=ComputerVision):请确保您的账户余额大于等于 200 元,否则无法开通 seedance 2.0 及 seedance 2.0 fast 模型。 +4. **下载并解压文件**:点击下载下方附件,将其解压到您的本地目录(如桌面或“下载”文件夹)。 + + +**2.操作步骤** + +```mixin-react +return ( + +); +``` + +**3.运行说明** +运行脚本后,您将看到如下流程: + +1. **API Key 校验**:脚本会自动检测您本地是否配置了`ARK_API_KEY`环境变量。如果没有,会提示您手动输入。 +2. **素材预览**:脚本会自动在您的默认浏览器中弹出一个本地生成的 HTML 页面,直观地展示本次任务的文本提示词、待替换的参考图片以及原始参考视频。 +3. **任务创建与轮询**:脚本向火山方舟服务器发起异步请求。由于视频生成需要一定时间,控制台会每隔 30 秒打印一次任务状态(如 `running`等)。 +4. **获取结果**:任务成功后,控制台会输出一段最终生成的视频 URL。您可以复制该链接到浏览器下载或在线播放。 + +**4.下一步** +在成功跑通本示例后,您可以尝试修改 `python/demo_standard.py`,来打造您专属的视频生成任务: + +1. 修改文本提示词 + +找到代码中的 `user_content` 变量,更改为您想要的画面描述。 + +2. 替换输入素材 (图片、视频、音频) + +您可以将 `reference_image_url`、`reference_video_url` 和 `reference_audio_url` 替换为您自己的素材链接。 +**注意**:请确保 URL 是公网可公开访问的链接(建议存放在 TOS 对象存储服务中,并配置为公共读)。 + +3. 继续学习下文中丰富的使用示例。 + + +# 模型能力 +seedance 2.0 fast 和 seedance 2.0 的模型能力相同。追求最高生成品质,推荐使用 seedance 2.0;更注重成本与生成速度,不要求极限品质,推荐使用 seedance 2.0 fast。 + + +|模型名称 | |[seedance 2.0](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-2-0&projectName=default) |[seedance 2.0 fast](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-2-0-fast&projectName=default) | +|---|---|---|---| +|Model ID | |doubao\-seedance\-2\-0\-260128 |doubao\-seedance\-2\-0\-fast\-260128 | +|文生视频 | |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) | +|图生视频\-首帧 | |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) | +|图生视频\-首尾帧 | |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) | +|多模态参考【New】 |图片参考 |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) | +|^^|视频参考 |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) | +|^^|组合参考|![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |\ +| || | |\ +| |* 图片 + 音频| | |\ +| |* 图片 + 视频| | |\ +| |* 视频 + 音频| | |\ +| |* 图片 + 视频 + 音频 | | | +|编辑视频【New】 | |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) | +|延长视频【New】 | |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) | +|生成有声视频 | |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) | +|联网搜索增强【New】 | |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) | +|样片模式 | |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/f359753773c94d97885008ca1223c9bc~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/f359753773c94d97885008ca1223c9bc~tplv-goo7wpa0wc-image.image =20x) | +|返回视频尾帧 | |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ee51ce32c1914aed81ff95080bb7db1d~tplv-goo7wpa0wc-image.image =20x) | +|输出视频规格 |输出分辨率 |480p, 720p |480p, 720p | +| |输出宽高比 |21:9, 16:9, 4:3, 1:1, 3:4, 9:16 || +| |输出时长 |4~15 秒 |4~15 秒 | +| |输出视频格式 |mp4 |mp4 | +|离线推理 | |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/f359753773c94d97885008ca1223c9bc~tplv-goo7wpa0wc-image.image =20x) |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/f359753773c94d97885008ca1223c9bc~tplv-goo7wpa0wc-image.image =20x) | +|在线推理限流 |最大 RPM |企业用户:600|企业用户:600|\ +| | |个人用户:180 |个人用户:180 | +| |最大并发数 |企业用户:10|企业用户:10|\ +| | |个人用户:3 |个人用户:3 | +|离线推理限流 |TPD |\- |\- | + + +# 基础使用 + +## 多模态参考 +输入文本、参考图、视频(可带音轨)和音频等内容,来生成一段新视频。可继承参考图片的角色形象、视觉风格、画面构图;参考视频的主体内容、运镜方式、动作表现、整体风格;以及参考音频的音色、音乐旋律、对话内容等核心信息。 +效果预览如下(访问[模型卡片](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-2-0)查看更多示例): + + +|输入:文本 |输入:图片、视频、音频 |输出 | +|---|---|---| +|全程使用**视频1**的第一视角构图,全程使用**音频1**作为背景音乐。第一人称视角果茶宣传广告,seedance牌「苹苹安安」苹果果茶限定款;首帧为**图片1**,你的手摘下一颗带晨露的阿克苏红苹果,轻脆的苹果碰撞声;2\-4 秒:快速切镜,你的手将苹果块投入雪克杯,加入冰块与茶底,用力摇晃,冰块碰撞声与摇晃声卡点轻快鼓点,背景音:「鲜切现摇」;4\-6 秒:第一人称成品特写,分层果茶倒入透明杯,你的手轻挤奶盖在顶部铺展,在杯身贴上粉红包标,镜头拉近看奶盖与果茶的分层纹理;6\-8 秒:第一人称手持举杯,你将**图片2**中的果茶举到镜头前(模拟递到观众面前的视角),杯身标签清晰可见,背景音「来一口鲜爽」,尾帧定格为**图片2**。背景声音统一为女生音色。 |||\ +| || |\ +| | | | + + +```mixin-react +return ( + + contents = new ArrayList<>(); + + // 1. Text prompt + contents.add(Content.builder() + .type("text") + .text(prompt) + .build()); + + // 2. Reference image 1 + contents.add(Content.builder() + .type("image_url") + .imageUrl(CreateContentGenerationTaskRequest.ImageUrl.builder() + .url(refImage1) + .build()) + .role("reference_image") + .build()); + + // 3. Reference image 2 + contents.add(Content.builder() + .type("image_url") + .imageUrl(CreateContentGenerationTaskRequest.ImageUrl.builder() + .url(refImage2) + .build()) + .role("reference_image") + .build()); + + // 4. Reference video + contents.add(Content.builder() + .type("video_url") + .videoUrl(CreateContentGenerationTaskRequest.VideoUrl.builder() + .url(refVideo) + .build()) + .role("reference_video") + .build()); + + // 5. Reference audio + contents.add(Content.builder() + .type("audio_url") + .audioUrl(CreateContentGenerationTaskRequest.AudioUrl.builder() + .url(refAudio) + .build()) + .role("reference_audio") + .build()); + + // Create video generation task + CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder() + .generateAudio(generateAudio) + .model(modelId) + .content(contents) + .ratio(videoRatio) + .duration(videoDuration) + .watermark(showWatermark) + .build(); + + CreateContentGenerationTaskResult createResult = service.createContentGenerationTask(createRequest); + System.out.println("Task Created: " + createResult); + + // Get task details and poll status + String taskId = createResult.getId(); + pollTaskStatus(taskId); + \} + + /** + * Poll task status + * @param taskId Task ID + */ + + private static void pollTaskStatus(String taskId) \{ + GetContentGenerationTaskRequest getRequest = GetContentGenerationTaskRequest.builder() + .taskId(taskId) + .build(); + + System.out.println("----- polling task status -----"); + try \{ + while (true) \{ + GetContentGenerationTaskResponse getResponse = service.getContentGenerationTask(getRequest); + String status = getResponse.getStatus(); + + if ("succeeded".equalsIgnoreCase(status)) \{ + System.out.println("----- task succeeded -----"); + System.out.println(getResponse); + break; + \} else if ("failed".equalsIgnoreCase(status)) \{ + System.out.println("----- task failed -----"); + if (getResponse.getError() != null) \{ + System.out.println("Error: " + getResponse.getError().getMessage()); + \} + break; + \} else \{ + System.out.printf("Current status: %s, Retrying in 10 seconds...%n", status); + TimeUnit.SECONDS.sleep(10); + \} + \} + \} catch (InterruptedException ie) \{ + Thread.currentThread().interrupt(); + System.err.println("Polling interrupted"); + \} catch (Exception e) \{ + System.err.println("Error occurred: " + e.getMessage()); + \} finally \{ + service.shutdownExecutor(); + \} + \} +\} +\`\`\` + +`}> +); +``` + +:::tip + +* 您可任意组合以下模态内容,注意不支持“文本+音频”、“纯音频” 输入。 + * 文本 + * 图片:0~9 张 + * 视频:0~3 个 + * 音频:0~3 个 +* **进阶用法**:多模态生视频可通过提示词指定参考图片作为首帧/尾帧,间接实现“首尾帧+多模态参考”效果。若需严格保障首尾帧和指定图片一致,**优先使用图生视频\-首尾帧**(配置 role 为 first_frame/last_frame)。 +* 各个模态信息输入要求参见[多模态输入](/docs/82379/1366799#63a97f09)。 + +::: + +## 编辑视频 +您可以提供待编辑的视频、参考图片或音频,并结合使用提示词,完成多种视频编辑任务,例如:替换视频主体、视频中对象增删改、局部画面重绘/修复等。 +效果预览如下(访问[模型卡片](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-2-0)查看更多示例): + + +|输入:文本 |输入:视频&图片 |输出 | +|---|---|---| +|将**视频1**礼盒中的香水替换成**图像1**中的面霜,运镜不变 |||\ +| || |\ +| |![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/791b783fc6cd4394b13f41b66b5ff461~tplv-goo7wpa0wc-image.image =280x) | | + + +```mixin-react +return ( + + contents = new ArrayList<>(); + + // 1. Text prompt + contents.add(Content.builder() + .type("text") + .text(prompt) + .build()); + + // 2. Reference image 1 + contents.add(Content.builder() + .type("image_url") + .imageUrl(CreateContentGenerationTaskRequest.ImageUrl.builder() + .url(refImage1) + .build()) + .role("reference_image") + .build()); + + // 3. Reference video + contents.add(Content.builder() + .type("video_url") + .videoUrl(CreateContentGenerationTaskRequest.VideoUrl.builder() + .url(refVideo) + .build()) + .role("reference_video") + .build()); + + // Create video generation task + CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder() + .generateAudio(generateAudio) + .model(modelId) + .content(contents) + .ratio(videoRatio) + .duration(videoDuration) + .watermark(showWatermark) + .build(); + + CreateContentGenerationTaskResult createResult = service.createContentGenerationTask(createRequest); + System.out.println("Task Created: " + createResult); + + // Get task details and poll status + String taskId = createResult.getId(); + pollTaskStatus(taskId); + \} + + /** + * Poll task status + * @param taskId Task ID + */ + + private static void pollTaskStatus(String taskId) \{ + GetContentGenerationTaskRequest getRequest = GetContentGenerationTaskRequest.builder() + .taskId(taskId) + .build(); + + System.out.println("----- polling task status -----"); + try \{ + while (true) \{ + GetContentGenerationTaskResponse getResponse = service.getContentGenerationTask(getRequest); + String status = getResponse.getStatus(); + + if ("succeeded".equalsIgnoreCase(status)) \{ + System.out.println("----- task succeeded -----"); + System.out.println(getResponse); + break; + \} else if ("failed".equalsIgnoreCase(status)) \{ + System.out.println("----- task failed -----"); + if (getResponse.getError() != null) \{ + System.out.println("Error: " + getResponse.getError().getMessage()); + \} + break; + \} else \{ + System.out.printf("Current status: %s, Retrying in 10 seconds...%n", status); + TimeUnit.SECONDS.sleep(10); + \} + \} + \} catch (InterruptedException ie) \{ + Thread.currentThread().interrupt(); + System.err.println("Polling interrupted"); + \} catch (Exception e) \{ + System.err.println("Error occurred: " + e.getMessage()); + \} finally \{ + service.shutdownExecutor(); + \} + \} +\} +\`\`\` + +`}> +); +``` + + +## 延长视频 +在原有视频基础上,向前或者向后延长视频,或多个视频片段(最多 3 个视频片段)串联成一个连贯视频。 +效果预览如下(访问[模型卡片](https://console.volcengine.com/ark/region:ark+cn-beijing/model/detail?Id=doubao-seedance-2-0)查看更多示例): + + +|输入:文本 |输入:待延长视频 |输出 | +|---|---|---| +|**视频1**中的拱形窗户打开,进入美术馆室内,接**视频2**,之后镜头进入画内,接**视频3** |||\ +| || |\ +| || |\ +| || |\ +| || |\ +| | | | + + +```mixin-react +return ( + + contents = new ArrayList<>(); + + // 1. Text prompt + contents.add(Content.builder() + .type("text") + .text(prompt) + .build()); + + // 2. Reference video 1 + contents.add(Content.builder() + .type("video_url") + .videoUrl(CreateContentGenerationTaskRequest.VideoUrl.builder() + .url(refVideo1) + .build()) + .role("reference_video") + .build()); + + // 3. Reference video 2 + contents.add(Content.builder() + .type("video_url") + .videoUrl(CreateContentGenerationTaskRequest.VideoUrl.builder() + .url(refVideo2) + .build()) + .role("reference_video") + .build()); + + // 4. Reference video 3 + contents.add(Content.builder() + .type("video_url") + .videoUrl(CreateContentGenerationTaskRequest.VideoUrl.builder() + .url(refVideo3) + .build()) + .role("reference_video") + .build()); + + // Create video generation task + CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder() + .generateAudio(generateAudio) + .model(modelId) + .content(contents) + .ratio(videoRatio) + .duration(videoDuration) + .watermark(showWatermark) + .build(); + + CreateContentGenerationTaskResult createResult = service.createContentGenerationTask(createRequest); + System.out.println("Task Created: " + createResult); + + // Get task details and poll status + String taskId = createResult.getId(); + pollTaskStatus(taskId); + \} + + /** + * Poll task status + * @param taskId Task ID + */ + + private static void pollTaskStatus(String taskId) \{ + GetContentGenerationTaskRequest getRequest = GetContentGenerationTaskRequest.builder() + .taskId(taskId) + .build(); + + System.out.println("----- polling task status -----"); + try \{ + while (true) \{ + GetContentGenerationTaskResponse getResponse = service.getContentGenerationTask(getRequest); + String status = getResponse.getStatus(); + + if ("succeeded".equalsIgnoreCase(status)) \{ + System.out.println("----- task succeeded -----"); + System.out.println(getResponse); + break; + \} else if ("failed".equalsIgnoreCase(status)) \{ + System.out.println("----- task failed -----"); + if (getResponse.getError() != null) \{ + System.out.println("Error: " + getResponse.getError().getMessage()); + \} + break; + \} else \{ + System.out.printf("Current status: %s, Retrying in 10 seconds...%n", status); + TimeUnit.SECONDS.sleep(10); + \} + \} + \} catch (InterruptedException ie) \{ + Thread.currentThread().interrupt(); + System.err.println("Polling interrupted"); + \} catch (Exception e) \{ + System.err.println("Error occurred: " + e.getMessage()); + \} finally \{ + service.shutdownExecutor(); + \} + \} +\} +\`\`\` + +`}> +); +``` + +:::tip + +* 向前或向后延长 1 段视频,生成的视频一般只包含原视频的尾部画面。但您也可以通过提示词灵活控制,使其包含原视频内容。 例如:向前延长视频1,[延长内容描述...],**最后接视频1**。 +* 传入 2~3 段视频,补全中间过渡部分,生成的视频会包含原视频内容和新生成的视频内容。 + +::: + +## 使用联网搜索 +> 联网搜索能力仅适用于纯文本输入 + +seedance 2.0 新增支持调用联网搜索工具,通过配置 tools.**type** 参数为 web_search 即可开启联网搜索。 + +* 开启联网搜索后,模型会根据用户的提示词自主判断是否搜索互联网内容(如商品、天气等)。可提升生成视频的时效性,但也会增加一定的时延。 +* 实际搜索次数可通过 [查询视频生成任务 API](https://www.volcengine.com/docs/82379/1521309?lang=zh) 返回的 usage.tool_usage.**web_search** 字段获取,如果为 0 表示未搜索。 + + + +|输入:文本 |输出 | +|---|---| +|微距镜头对准叶片上翠绿的玻璃蛙。焦点逐渐从它光滑的皮肤,转移到它完全透明的腹部,一颗鲜红的心脏正在有力地、规律地收缩扩张。||\ +|:::tip| |\ +|联网搜索玻璃蛙的容貌特征。| |\ +|| |\ +|:::| | + + +```mixin-react +return ( + + contents = new ArrayList<>(); + + // text prompt + contents.add(Content.builder() + .type("text") + .text(prompt) + .build()); + + // Create a video generation task + CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder() + .model(modelId) + .content(contents) + .generateAudio(generateAudio) + .ratio(videoRatio) + .duration(videoDuration) + .watermark(showWatermark) + .tools(Collections.singletonList(webSearchTool)) + .build(); + CreateContentGenerationTaskResult createResult = service.createContentGenerationTask(createRequest); + System.out.println(createResult); + // Get the details of the task + String taskId = createResult.getId(); + GetContentGenerationTaskRequest getRequest = GetContentGenerationTaskRequest.builder() + .taskId(taskId) + .build(); + + // Polling query section + System.out.println("----- polling task status -----"); + while (true) \{ + try \{ + GetContentGenerationTaskResponse getResponse = service.getContentGenerationTask(getRequest); + String status = getResponse.getStatus(); + if ("succeeded".equalsIgnoreCase(status)) \{ + System.out.println("----- task succeeded -----"); + System.out.println(getResponse); + break; + \} else if ("failed".equalsIgnoreCase(status)) \{ + System.out.println("----- task failed -----"); + System.out.println("Error: " + getResponse.getStatus()); + break; + \} else \{ + System.out.printf("Current status: %s, Retrying in 10 seconds...", status); + TimeUnit.SECONDS.sleep(10); + \} + \} catch (InterruptedException ie) \{ + Thread.currentThread().interrupt(); + System.err.println("Polling interrupted"); + break; + \} + \} + \} +\} +\`\`\` + +`}> +); +``` + + +## 更多能力 +seedance 2.0 系列模型也支持文生视频、首帧图生视频、首尾帧图生视频、设置视频输出规格等通用基础能力,详情请参见 [视频生成教程-wip](/docs/82379/2298881)。 + +# 便利创作 +seedance 2.0 系列模型不支持直接上传含有真人人脸的参考图/视频。为便利创作者使用肖像,平台推出了以下解决方案。 + + +|方案 |介绍 | +|---|---| +|[使用虚拟人像](/docs/82379/2291680#2bf01416) |平台预置虚拟人像库,为创作者提供免费、合规、丰富多样的肖像素材。适用于需真人风格人脸但无需指定具体人物,追求零合规风险、快速创作的场景。 | +|[使用已授权真人素材](/docs/82379/2291680#f952d0c3) |支持使用已获得授权的真人肖像素材进行视频生成。 | +|[使用模型产物进行二创](/docs/82379/2291680#86c3831f) |本账号下部分模型生成的含人脸原始产物可作为输入素材,再次调用 seedance 2.0 系列模型进行二次创作,不会触发审核拦截。 | + + +## 使用虚拟人像 +对写实风格视频,可通过虚拟人像库预置人像来控制角色样貌。每个素材对应一个独立素材 ID (asset ID), 在 **content.<模态\>_url.url** 字段中传入 `asset://` 即可生成视频。浏览及检索虚拟人像请参见[虚拟人像库](/docs/82379/2223965)。 + + +|输入:文本 |输入:虚拟人像、图片 |输出 | +|---|---|---| +|固定机位,近景镜头,清新自然风格。在室内自然光下,**图片1**中美妆博主面带笑容,向镜头介绍**图片2**中的面霜。博主将手里的面霜展示给镜头,开心地说“挖到本命面霜了!”;接着她一边用手指轻轻蘸取面霜展示那种软糯感,一边说“质地像云朵一样软糯,一抹就吸收”;最后她把面霜涂抹在脸颊上,展示着水润透亮的皮肤,同时自信地说“熬夜急救、补水保湿全搞定”。要求画面中人物居中,完整展示人物的整个脑袋和上半身,始终对焦人脸,人脸始终清晰,纯净无任何字幕。|![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/946509d1f37f476c9ff29e0adaf187eb~tplv-goo7wpa0wc-image.image =200x) ||\ +|:::warning|> 虚拟人像| |\ +|Asset ID 仅用来向模型传入素材,提示词中仍需使用"**素材类型+序号**”格式引用素材,序号为请求体中该素材在同类素材中的排序。|| |\ +|正确用法:**图片1**中美妆博主|![图片](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/791b783fc6cd4394b13f41b66b5ff461~tplv-goo7wpa0wc-image.image =200x) | |\ +|错误用法:asset\-2026\*\*\*\*是美妆博主|> 产品图像 | |\ +|| | |\ +|:::| | | + + +```mixin-react +return ( + + contents = new ArrayList<>(); + + // 1. Text prompt + contents.add(Content.builder() + .type("text") + .text(prompt) + .build()); + + // 2. Reference image 1 + contents.add(Content.builder() + .type("image_url") + .imageUrl(CreateContentGenerationTaskRequest.ImageUrl.builder() + .url(refImage1) + .build()) + .role("reference_image") + .build()); + + // 3. Reference image 2 + contents.add(Content.builder() + .type("image_url") + .imageUrl(CreateContentGenerationTaskRequest.ImageUrl.builder() + .url(refImage2) + .build()) + .role("reference_image") + .build()); + + // Create video generation task + CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder() + .generateAudio(generateAudio) + .model(modelId) + .content(contents) + .ratio(videoRatio) + .duration(videoDuration) + .watermark(showWatermark) + .build(); + + CreateContentGenerationTaskResult createResult = service.createContentGenerationTask(createRequest); + System.out.println("Task Created: " + createResult); + + // Get task details and poll status + String taskId = createResult.getId(); + pollTaskStatus(taskId); + \} + + /** + * Poll task status + * @param taskId Task ID + */ + + private static void pollTaskStatus(String taskId) \{ + GetContentGenerationTaskRequest getRequest = GetContentGenerationTaskRequest.builder() + .taskId(taskId) + .build(); + + System.out.println("----- polling task status -----"); + try \{ + while (true) \{ + GetContentGenerationTaskResponse getResponse = service.getContentGenerationTask(getRequest); + String status = getResponse.getStatus(); + + if ("succeeded".equalsIgnoreCase(status)) \{ + System.out.println("----- task succeeded -----"); + System.out.println(getResponse); + break; + \} else if ("failed".equalsIgnoreCase(status)) \{ + System.out.println("----- task failed -----"); + if (getResponse.getError() != null) \{ + System.out.println("Error: " + getResponse.getError().getMessage()); + \} + break; + \} else \{ + System.out.printf("Current status: %s, Retrying in 10 seconds...%n", status); + TimeUnit.SECONDS.sleep(10); + \} + \} + \} catch (InterruptedException ie) \{ + Thread.currentThread().interrupt(); + System.err.println("Polling interrupted"); + \} catch (Exception e) \{ + System.err.println("Error occurred: " + e.getMessage()); + \} finally \{ + service.shutdownExecutor(); + \} + \} +\} +\`\`\` + +`}> +); +``` + + +## 使用已授权真人素材 +通过真人认证和本人授权后,可将该真人的相关素材(例如该真人的图片、视频、音频)上传至方舟。素材入库成功后,每个素材将获得一个独立素材 ID (asset ID), 在 **content.<模态\>_url.url** 字段中传入 `asset://`即可使用该素材生成视频。真人认证及素材入库流程请参见[录入真人形象素材](/docs/82379/2315856)。 +```Shell +... +"content": [ + { + "type": "text", + "text": "" + }, + { + "type": "image_url", + "image_url": { + "url": "asset://" + }, + "role": "reference_image" + }, + { + "type": "video_url", + "video_url": { + "url": "asset://" + }, + "role": "reference_video" + }, + { + "type": "audio_url", + "audio_url": { + "url": "asset://" + }, + "role": "reference_audio" + } + ] +... +``` + +  + +## 使用模型产物进行二创 +seedance 2.0 系列模型不支持直接上传含有真人人脸的参考图/视频。为了便利创作者在含人脸场景的二次创作需求,方舟平台信任以下模型生成的含人脸产物,您可使用**本账号下近30天内由以下模型生成的含人脸原始产物**,作为输入素材,再次调用 seedance 2.0 系列模型进行二次创作。 + +|信任产物范围 |生效时间|有效期|\ +| |> 信任该时间之后|> 从产物生成时间|\ +| |> 生成的产物 |> 开始计算 | +|---|---|---| +|seedance 2.0 及 2.0 fast 生成的含人脸视频 |2026年03月11日起 |30天 | +|seedance 2.0 及 2.0 fast 生成的含人脸视频对应的尾帧图片 |2026年04月16日起 |30天 | +|[Seedream 5.0 lite 文生图](https://www.volcengine.com/docs/82379/1824121?lang=zh#9695d195)得到的含人脸图片 |2026年04月16日起 |30天 | + +:::warning + +* 对于含人脸场景,方舟平台仅信任模型原始产物,二次剪辑或超过有效期后均不可使用。 +* 对于不含人脸场景,模型产物不存在受信问题,支持自由剪辑后进行二次创作。 + + +::: + +|输入:同账号生成的视频 |输出 | +|---|---| +|||\ +|||\ +|> [使用虚拟人像](/docs/82379/2291680#2bf01416)示例生成的视频 |> 输入:将面霜的颜色修改为白色。|\ +| |> ratio 修改为16:9 | + + +```mixin-react +return ( + + contents = new ArrayList<>(); + + // 1. Text prompt + contents.add(Content.builder() + .type("text") + .text(prompt) + .build()); + + // 2. Reference video + contents.add(Content.builder() + .type("video_url") + .videoUrl(CreateContentGenerationTaskRequest.VideoUrl.builder() + .url(refVideo) + .build()) + .role("reference_video") + .build()); + + // Create video generation task + CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder() + .generateAudio(generateAudio) + .model(modelId) + .content(contents) + .ratio(videoRatio) + .duration(videoDuration) + .watermark(showWatermark) + .build(); + + CreateContentGenerationTaskResult createResult = service.createContentGenerationTask(createRequest); + System.out.println("Task Created: " + createResult); + + // Get task details and poll status + String taskId = createResult.getId(); + pollTaskStatus(taskId); + \} + + /** + * Poll task status + * @param taskId Task ID + */ + + private static void pollTaskStatus(String taskId) \{ + GetContentGenerationTaskRequest getRequest = GetContentGenerationTaskRequest.builder() + .taskId(taskId) + .build(); + + System.out.println("----- polling task status -----"); + try \{ + while (true) \{ + GetContentGenerationTaskResponse getResponse = service.getContentGenerationTask(getRequest); + String status = getResponse.getStatus(); + + if ("succeeded".equalsIgnoreCase(status)) \{ + System.out.println("----- task succeeded -----"); + System.out.println(getResponse); + break; + \} else if ("failed".equalsIgnoreCase(status)) \{ + System.out.println("----- task failed -----"); + if (getResponse.getError() != null) \{ + System.out.println("Error: " + getResponse.getError().getMessage()); + \} + break; + \} else \{ + System.out.printf("Current status: %s, Retrying in 10 seconds...%n", status); + TimeUnit.SECONDS.sleep(10); + \} + \} + \} catch (InterruptedException ie) \{ + Thread.currentThread().interrupt(); + System.err.println("Polling interrupted"); + \} catch (Exception e) \{ + System.err.println("Error occurred: " + e.getMessage()); + \} finally \{ + service.shutdownExecutor(); + \} + \} +\} +\`\`\` + +`}> +); +``` + + +# 提示词技巧 +提示词中必须使用"**素材类型+序号**”格式引用素材,序号为请求体中该素材在同类素材中的排序。例如 「图片 n」指代`content`数组中第 n 个`type="image_url"`的参考图片(按数组顺序从1开始计数)。**注意不支持使用 Asset ID 指代素材。** +下文介绍多模态参考、编辑视频、延长视频的提示词典型公式,更多详细内容请参见[Seedance 2.0 系列提示词指南](/docs/82379/2222480)。 +:::tip +平台提供 **seedance 2.0 提示词优化技能**,方便您对提示词进行调优。 + +* 配置方式:可将技能文件配置到 Code Agent / AI Agent 中使用。以 OpenClaw 为例,下载该 SKILL.md 文件,复制完整内容至对话输入框中,并发送”请帮我安装这个技能”,等待工具自动完成安装。 +* 使用方式:在 AI 对话框输入 `/sd2-pe + 你的提示词内容`,开始调试提示词。 + + +::: +**多模态参考** + +* 图片参考:参考 / 提取 / 结合 +「图片 n」中的「主体 / 被参考元素描述」,生成「画面描述」,保持「主体 / 被参考元素描述」特征一致。 +* 视频参考:参考「视频 n」的「动作描述 / 运镜描述 / 特效描述」,生成「画面描述」,保持动作细节 / 运镜 / 特效一致。 +* 音频参考: + * 音色参考:「角色」说:“「台词」,音色参考「音频 n」。 + * 音频内容参考:理想出现时机 +「音频 n」。 + +**编辑视频** + +* 增加元素:清晰描述「元素特征」+「出现时机」+「出现位置」 +* 删除元素:点明需要删除的元素,对于保持不变的元素,在提示词中加以强调,表现更佳 +* 修改元素:清晰描述更换元素即可 + +**延长视频** + +* 延长视频:向前/向后延长「视频n」+「需延长的视频描述」 +* 轨道补全:「视频1」+「过渡画面描述」+接「视频2」+「过渡画面描述」+接「视频3」 + + +# 使用限制 +参见[使用限制](/docs/82379/1366799#66cb028f)。 + + diff --git a/docs/API文档/seedance模型价格.md b/docs/API文档/seedance模型价格.md new file mode 100644 index 0000000..4b3dd3c --- /dev/null +++ b/docs/API文档/seedance模型价格.md @@ -0,0 +1,481 @@ +不同模型服务支持的能力及单价各不相同,本文为您介绍各模型的计费公式及单价,方便您进行模型价格查阅和比较。 +:::tip + +* 如需了解计费方式及详细计费逻辑,请参见 [模型服务计费说明](/docs/82379/1544681)。 +* 支持通过 [价格计算器](https://www.volcengine.com/pricing?product=ark_bd&tab=2) **预估** 满足业务需求所需的费用。 +* 本文价格和 [定价详情页](https://www.volcengine.com/pricing?product=ark_bd&tab=1) 仅作为商品规格和价格的参考,具体可购买的商品规格及费用请以实际下单结果为准。 + +::: + +# 大语言模型 + +## 在线推理(常规) + + +|模型名称 |条件|输入|缓存存储|缓存输入|输出|\ +| |千 token |元/百万token |元/百万 token /小时 |元/百万token |元/百万token | +|---|---|---|---|---|---| +|doubao\-seed\-2.0\-pro |输入长度 [0, 32] |3.2 |0.017 |0.64 |16.0 | +|^^|输入长度 (32, 128] |4.8 |0.017 |0.96 |24.0 | +|^^|输入长度 (128, 256] |9.6 |0.017 |1.92 |48.0 | +|doubao\-seed\-2.0\-lite |输入长度 [0, 32] |0.6 |0.017 |0.12 |3.6 | +|^^|输入长度 (32, 128] |0.9 |0.017 |0.18 |5.4 | +|^^|输入长度 (128, 256] |1.8 |0.017 |0.36 |10.8 | +|doubao\-seed\-2.0\-mini |输入长度 [0, 32] |0.2 |0.017 |0.04 |2.0 | +|^^|输入长度 (32, 128] |0.4 |0.017 |0.08 |4.0 | +|^^|输入长度 (128, 256] |0.8 |0.017 |0.16 |8.0 | +|doubao\-seed\-2.0\-code |输入长度 [0, 32] |3.2 |0.017 |0.64 |16.0 | +|^^|输入长度 (32, 128] |4.8 |0.017 |0.96 |24.0 | +|^^|输入长度 (128, 256] |9.6 |0.017 |1.92 |48.0 | +|doubao\-seed\-1.8 |输入长度 [0, 32]|0.80 |0.017 |0.16 |2.00 |\ +| |且输出长度 [0, 0.2] | | | | | +|^^|输入长度 [0, 32]|0.80 |0.017 |0.16 |8.00 |\ +| |且输出长度 (0.2,+∞) | | | | | +|^^|输入长度 (32, 128] |1.20 |0.017 |0.16 |16.00 | +|^^|输入长度 (128, 256] |2.40 |0.017 |0.16 |24.00 | +|doubao\-seed\-character |输入长度 [0, 32] |0.80 |0.017 |0.16 |2.00 | +|^^|输入长度 (32, 128] |1.20 |0.017 |0.16 |6.00 | +|doubao\-seed\-code |输入长度 [0, 32] |1.20 |0.017 |0.24 |8.00 | +|^^|输入长度 (32, 128] |1.40 |0.017 |0.24 |12.00 | +|^^|输入长度 (128, 256] |2.80 |0.017 |0.24 |16.00 | +|doubao\-seed\-1.6 |输入长度 [0, 32]|0.80 |0.017 |0.16 |2.00 |\ +| |且输出长度 [0, 0.2] | | | | | +|^^|输入长度 [0, 32]|0.80 |0.017 |0.16 |8.00 |\ +| |且输出长度 (0.2,+∞) | | | | | +|^^|输入长度 (32, 128] |1.20 |0.017 |0.16 |16.00 | +|^^|输入长度 (128, 256] |2.40 |0.017 |0.16 |24.00 | +|doubao\-seed\-1.6\-lite |输入长度 [0, 32]|0.30 |0.017 |0.06 |0.60 |\ +| |且输出长度 [0, 0.2] | | | | | +|^^|输入长度 [0, 32]|0.30 |0.017 |0.06 |2.40 |\ +| |且输出长度 (0.2,+∞) | | | | | +|^^|输入长度 (32, 128] |0.60 |0.017 |0.06 |4.00 | +|^^|输入长度 (128, 256] |1.20 |0.017 |0.06 |12.00 | +|doubao\-seed\-1.6\-flash |输入长度 [0, 32] |0.15 |0.017 |0.03 |1.50 | +|^^|输入长度 (32, 128] |0.30 |0.017 |0.03 |3.00 | +|^^|输入长度 (128, 256] |0.60 |0.017 |0.03 |6.00 | +|doubao\-seed\-1.6\-vision |输入长度 [0, 32] |0.80 |0.017 |0.16 |8.00 | +|^^|输入长度 (32, 128] |1.20 |0.017 |0.16 |16.00 | +|^^|输入长度 (128, 256] |2.40 |0.017 |0.16 |24.00 | +|doubao\-seed\-translation |\- |1.20 |不支持 |不支持 |3.60 | +|doubao\-1.5\-pro\-32k |\- |0.80 |0.017 |0.16 |2.00 | +|doubao\-1.5\-lite\-32k |\- |0.30 |0.017 |0.06 |0.60 | +|doubao\-1.5\-vision\-pro |\- |3.00 |不支持 |不支持 |9.00 | +|glm\-4.7 |输入长度 [0, 32]|2.0 |0.017 |0.4 |8.0 |\ +| |且输出长度 [0, 0.2] | | | | | +|^^|输入长度 [0, 32]|3.0 |0.017 |0.6 |14.0 |\ +| |且输出长度 (0.2,+∞) | | | | | +|^^|输入长度 (32, 200] |4.0 |0.017 |0.8 |16.0 | +|deepseek\-v3.2 |输入长度 [0, 32] |2.00 |0.017 |0.4 |3.00 | +|^^|输入长度 (32, 128] |4.00 |0.017 |0.4 |6.00 | +|deepseek\-v3.1 |\- |4.00 |0.017 |0.80 |12.00 | +|deepseek\-v3 |\- |2.00 |0.017 |0.40 |8.00 | +|deepseek\-r1 |\- |4.00 |0.017 |0.80 |16.00 | + + +> * 按 token 后付费,计算公式: +> * `在线推理费用 = 输入单价 × 输入token + 缓存输入单价 × 缓存命中token + 缓存存储单价 × 缓存存储token × 时长 + 输出单价 × 输出token` +> * 分段计费:部分模型适用,不同的输入长度(和输出长度),token单价不同: +> * 举例:请求输入 200k tokens,输出 14k tokens,满足 **输入长度 (128, 256]** 条件,模型输入输出 token 按照:输入 2.4 元/百万 token,输出 24 元/百万 token 单价计费。 +> * 常见问题: [如何查看历史调用的输入输出长度的区间分布?](/docs/82379/1359411#fba666f2) + + +## 在线推理(低延迟) + + +|模型名称 |条件|输入|缓存输入|输出|\ +| |千 token |元/百万token |元/百万token |元/百万token | +|---|---|---|---|---| +|doubao\-seed\-2.0\-pro |输入长度 [0, 32] |9.6 |1.92 |48.0 | +|^^|输入长度 (32, 128] |14.4 |2.88 |72.0 | +|^^|输入长度 (128, 256] |28.8 |5.76 |144.0 | +|doubao\-seed\-2.0\-lite |输入长度 [0, 32] |1.2 |0.24 |7.2 | +|^^|输入长度 (32, 128] |1.8 |0.36 |10.8 | +|^^|输入长度 (128, 256] |3.6 |0.72 |21.6 | +|doubao\-seed\-2.0\-mini |输入长度 [0, 32] |0.4 |0.08 |4.0 | +|^^|输入长度 (32, 128] |0.8 |0.16 |8.0 | +|^^|输入长度 (128, 256] |1.6 |0.32 |16.0 | + + +## 在线推理(TPM 保障包) + + +|模型 |计费方式 |输入|输出|\ +| | |元/每10K TPM |元/每1K TPM | +|---|---|---|---| +|doubao\-seed\-1.8 |按购买时长后付费 |1.920 |0.480 | +|^^|包天预付费 |23.040 |5.760 | +|doubao\-seed\-1.6 |按购买时长后付费 |1.920 |0.480 | +|^^|包天预付费 |23.040 |5.760 | +|doubao\-seed\-1.6\-vision |按购买时长后付费 |1.920 |0.480 | +|^^|包天预付费 |23.040 |5.760 | +|doubao\-seed\-1.6\-flash|按购买时长后付费 |0.360 |0.360 |\ +|> 0615版本不支持 | | | | +|^^|包天预付费 |4.320 |4.320 | +|doubao\-1.5\-vision\-pro |按购买时长后付费 |7.200 |2.160 | +|^^|包天预付费 |86.400 |25.920 | +|doubao\-1.5\-pro\-32k|按购买时长后付费 |1.920 |0.480 |\ +|> 包含 character\-250715 版本 | | | | +|^^|包天预付费 |23.040 |5.760 | +|doubao\-1.5\-lite\-32k |按购买时长后付费 |0.72 |0.144 | +|^^|包天预付费 |8.64 |1.728 | +|doubao\-pro\-32k |按购买时长后付费 |1.920 |0.480 | +|^^|包天预付费 |23.040 |5.760 | +|deepseek\-v3.2 |按购买时长后付费 |7.2 |1.08 | +|^^|包天预付费 |86.4 |12.96 | +|deepseek\-v3.1 |按购买时长后付费 |9.60 |2.88 | +|^^|包天预付费 |115.20 |34.56 | +|deepseek\-v3 |按购买时长后付费 |4.80 |1.92 | +|^^|包天预付费 |57.60 |23.04 | +|deepseek\-r1 |按购买时长后付费 |9.60 |3.84 | +|^^|包天预付费 |115.20 |46.08 | + + +> * 相比普通的按token计费模式,TPM保障包具备更高并发,更低的延迟,更强稳定性。支持的模型,以[接入点创建页](https://console.volcengine.com/ark/region:ark+cn-beijing/endpoint/create)可选的付费方式为准。 +> * 支持「按购买时长后付费」和「包天预付费」两种方式叠加购买,可灵活组合。 +> * **doubao\-seed\-1.6 系列及之后模型,deepseek\-v3.2 模型,不同长度请求抵扣 TPM 速度不同**,可通过 TPM 计算器查看相应的抵扣系数,估算实际需购买的**可抵扣TPM**。 + + +## 批量推理 + + +|模型名称 |条件|输入|缓存命中|输出|\ +| |千 token |元/百万token |元/百万token |元/百万token | +|---|---|---|---|---| +|doubao\-seed\-2.0\-pro |输入长度 [0, 32] |1.6 |0.64 |8.0 | +|^^|输入长度 (32, 128] |2.4 |0.96 |12.0 | +|^^|输入长度 (128, 256] |4.8 |1.92 |24.0 | +|doubao\-seed\-2.0\-lite |输入长度 [0, 32] |0.3 |0.12 |1.8 | +|^^|输入长度 (32, 128] |0.45 |0.18 |2.7 | +|^^|输入长度 (128, 256] |0.9 |0.36 |5.4 | +|doubao\-seed\-2.0\-mini |输入长度 [0, 32] |0.1 |0.04 |1.0 | +|^^|输入长度 (32, 128] |0.2 |0.08 |2.0 | +|^^|输入长度 (128, 256] |0.4 |0.16 |4.0 | +|doubao\-seed\-2.0\-code |输入长度 [0, 32] |1.6 |0.64 |8.0 | +|^^|输入长度 (32, 128] |2.4 |0.96 |12.0 | +|^^|输入长度 (128, 256] |4.8 |1.92 |24.0 | +|doubao\-seed\-1.8 |输入长度 [0, 32]|0.40 |0.16 |1.00 |\ +| |且输出长度 [0, 0.2] | | | | +|^^|输入长度 [0, 32]|0.40 |0.16 |4.00 |\ +| |且输出长度 (0.2,+∞) | | | | +|^^|输入长度 (32, 128] |0.60 |0.16 |8.00 | +|^^|输入长度 (128, 256] |1.20 |0.16 |12.00 | +|doubao\-seed\-1.6\-vision |输入长度 [0, 32] |0.40 |0.16 |4.00 | +|^^|输入长度 (32, 128] |0.60 |0.16 |8.00 | +|^^|输入长度 (128, 256] |1.20 |0.16 |12.00 | +|doubao\-seed\-1.6\-lite |输入长度 [0, 32]|0.15 |0.06 |0.30 |\ +| |且输出长度 [0, 0.2] | | | | +|^^|输入长度 [0, 32]|0.15 |0.06 |1.20 |\ +| |且输出长度 (0.2,+∞) | | | | +|^^|输入长度 (32, 128] |0.30 |0.06 |2.00 | +|^^|输入长度 (128, 256] |0.60 |0.06 |6.00 | +|doubao\-seed\-1.6 |输入长度 [0, 32]|0.40 |0.16 |1.00 |\ +| |且输出长度 [0, 0.2] | | | | +|^^|输入长度 [0, 32]|0.40 |0.16 |4.00 |\ +| |且输出长度 (0.2,+∞) | | | | +|^^|输入长度 (32, 128] |0.60 |0.16 |8.00 | +|^^|输入长度 (128, 256] |1.20 |0.16 |12.00 | +|doubao\-seed\-1.6\-flash |输入长度 [0, 32] |0.075 |0.03 |0.75 | +|^^|输入长度 (32, 128] |0.150 |0.03 |1.50 | +|^^|输入长度 (128, 256] |0.300 |0.03 |3.00 | +|doubao\-seed\-translation |\- |0.60 |0.24 |1.80 | +|doubao\-1.5\-pro\-32k |\- |0.40 |0.16 |1.00 | +|doubao\-1.5\-lite\-32k |\- |0.15 |0.06 |0.30 | +|doubao\-pro\-32k |\- |0.80 |0.16 |2.00 | +|deepseek\-v3.2 |输入长度 [0, 32] |1.00 |0.40 |1.50 | +|^^|输入长度 (32, 128] |2.00 |0.40 |3.00 | +|deepseek\-v3.1 |\- |2.00 |0.80 |6.00 | +|deepseek\-v3 |\- |1.00 |0.40 |4.00 | +|deepseek\-r1 |\- |2.00 |0.80 |8.00 | + + +> * 按 token 后付费,计算公式:`批量推理费用 = 输入单价 × 输入token + 缓存命中单价 × 缓存命中token + 输出单价 × 输出token` +> * 部分模型已支持透明前缀缓存能力,无需任何配置,享受命中缓存后的更低单价。 +> * doubao\-seed\-1.6 系列支持分段计费,即根据每次请求的输入及输出长度,采用不同 token 单价。 +> * 举例:当某次请求的输入长度为 200k,输出长度为 14k 时,满足 **输入长度 (128, 256]** 条件,模型产生的所有 token 按照:输入2.4 元/百万 token,输出 24 元/百万 token 单价计费。 +> * 查看往期调用的输入输出长度分布,请查看常见问题 [如何查看历史调用的输入输出长度的区间分布?](/docs/82379/1359411#fba666f2) + + +# 视频生成模型 + +## 按token单价 + + +|模型 |在线推理|离线推理|\ +| |元/百万token |元/百万token | +|---|---|---| +|doubao\-seedance\-2.0|* 输出视频分辨率为 480p,720p|暂不支持 |\ +|> 按输出视频分辨率和输入是否包含视频区分定价 | * 输入不含视频:46.00| |\ +| | * 输入包含视频:28.00| |\ +| |* 输出视频分辨率为 1080p| |\ +| | * 输入不含视频:51.00| |\ +| | * 输入包含视频:31.00 | | +|doubao\-seedance\-2.0\-fast|* 输入不含视频:37.00|暂不支持 |\ +|> 按输入是否包含视频区分定价|* 输入包含视频:22.00 | |\ +|> 不支持输出 1080p 视频 | | | +|doubao\-seedance\-1.5\-pro|* 有声视频:16.00|* 有声视频:8.00|\ +|> 按输出视频是否包含声音区分定价 |* 无声视频:8.00 |* 无声视频:4.00 | +|doubao\-seedance\-1.0\-pro |15.00 |7.50 | +|doubao\-seedance\-1.0\-pro\-fast |4.20 |2.10 | +|doubao\-seedance\-1.0\-lite |10.00 |5.00 | + + +> * 仅对成功生成的视频计费。因审核等原因导致生成失败的,不收取费用。 +> * 视频价格估算公式:`按 token 单价 × token 用量` +> * 正常视频 token 用量估算:`(输入视频时长+输出视频时长) × 输出视频的宽 × 输出视频的高 × 输出视频的帧率/1024`,注意存在输入视频时, Seedance 2.0 和 Seedance 2.0 fast 模型针对不同的视频输出时长存在最低 Token 用量限制,详见下文表格。 +> * Draft 视频(仅480p)token 用量估算:`正常视频 token 用量公式 × 折算系数`,折算系数与模型相关,Seedance 1.5 pro 的 token 折算系数:无声 0.7;有声 0.6,其他模型暂不支持。 +> * 准确 token 用量:以调用 API 后返回信息中的 usage 字段为准。 + + +## 价格示例 +基于 token 用量公式估算的视频单价,方便您直观了解不同规格的视频成本。更多价格示例请参见[火山方舟视频生成模型价格快查表](https://bytedance.larkoffice.com/wiki/FXaYwxzJ5i5Zdik32ipcWzt7nxd?table=tblns3WjGMNbR8sL&view=vewPa39Do4#CategoryScheduledTask)。 + +### doubao\-seedance\-2.0 & 2.0 fast + +> * 视频价格估算公式:`按 token 单价 × token 用量`=`按 token 单价 × (输入视频时长+输出视频时长) × 输出视频的宽 × 输出视频的高 × 输出视频的帧率/1024` +> * 注意:输入包含视频时, Seedance 2.0 和 Seedance 2.0 fast 模型针对不同的视频输出时长存在最低 token 用量限制,如果 token 估算用量 < 最低 token 用量限制,则按最低 token 用量计算视频价格。 +* **输入不含视频** + + + +|分辨率 |宽高比 |输出视频时长(秒) |doubao\-seedance\-2.0|doubao\-seedance\-2.0\-fast|\ +| | | |视频价格(元/个) |视频价格(元/个) | +|---|---|---|---|---| +|480p |16:9 |5 |2.31 |1.86 | +|720p |16:9 |5 |4.97 |4.00 | +|1080p |16:9 |5 |12.39 |不支持 | + + +* **输入包含视频** + + + +|分辨率 |宽高比 |输入视频时长(秒) |输出视频时长(秒) |doubao\-seedance\-2.0|doubao\-seedance\-2.0\-fast|\ +| | | | |视频价格(元/个) |视频价格(元/个) | +|---|---|---|---|---|---| +|480p |16:9 |2~15 |5 |2.53~5.62|1.99~4.42|\ +| | | | |> 最低价对应输入2~4秒|> 最低价对应输入2~4秒|\ +| | | | |> 最高价对应输入15秒 |> 最高价对应输入15秒 | +|720p |16:9 |2~15 |5 |5.44~12.10|4.28~9.50|\ +| | | | |> 最低价对应输入2~4秒|> 最低价对应输入2~4秒|\ +| | | | |> 最高价对应输入15秒 |> 最高价对应输入15秒 | +|1080p |16:9 |2~15 |5 |13.56~30.13|不支持 |\ +| | | | |> 最低价对应输入2~4秒| |\ +| | | | |> 最高价对应输入15秒 | | + +附:输入包含视频时,Seedance 2.0 & 2.0 fast 的最低 token 用量限制。本表以 16:9 宽高比为例展示各分辨率下的最低 token 用量。不同宽高比的最低 token 用量存在少许差异,详情参见 [火山方舟视频生成模型价格快查表](https://bytedance.larkoffice.com/wiki/FXaYwxzJ5i5Zdik32ipcWzt7nxd?table=tblmNCuMjADrXtDf&view=vewPa39Do4#CategoryScheduledTask)。 + + +|输出视频秒数 |最低tokens\-480P |最低tokens\-720P |最低tokens\-1080P | +|---|---|---|---| +|4 |70308 |151200 |340200 | +|5 |90396 |194400 |437400 | +|6 |100440 |216000 |486000 | +|7 |120528 |259200 |583200 | +|8 |140616 |302400 |680400 | +|9 |150660 |324000 |729000 | +|10 |170748 |367200 |826200 | +|11 |190836 |410400 |923400 | +|12 |200880 |432000 |972000 | +|13 |220968 |475200 |1069200 | +|14 |241056 |518400 |1166400 | +|15 |251100 |540000 |1215000 | + + +### doubao\-seedance\-1.5\-pro + + +|分辨率 |宽高比 |时长(秒) |有声视频|Draft 有声|无声视频|Draft无声|\ +| | | |价格|视频价格|价格|视频价格|\ +| | | |(元/个) |(元/个) |(元/个) |(元/个) | +|---|---|---|---|---|---|---| +|480p |16:9 |5 |0.80 |0.48 |0.40 |0.28 | +|720p |16:9 |5 |1.73 |不支持 |0.86 |不支持 | +|1080p |16:9 |5 |3.89 |不支持 |1.94 |不支持 | + + +# 图片生成模型 + + +|模型名称 |单价|\ +| |元/张 | +|---|---| +|doubao\-seedream\-5.0\-lite |0.22 | +|doubao\-seedream\-4.5 |0.25 | +|doubao\-seedream\-4.0 |0.2 | +|doubao\-seedream\-3.0\-t2i |0.259 | + + +> * 按成功输出图片数量计费: +> * 组图场景按实际生成的图片数量计费。 +> * 因审核等原因未成功输出的图片不计费。 + +  + +# 向量模型 + + +|模型 |文本输入|图片输入|\ +| |元/百万 token |元/百万 token | +|---|---|---| +|doubao\-embedding\-vision |0.70 |1.80 | + +> 按输入的 tokens 计费: +> 费用 = `文本输入 tokens × 文本输入单价 + 图片输入 tokens × 图片输入单价` +> = `文本输入 tokens × 文本输入单价+ min((width × height)/784,1312 ) × 图片输入单价` + + +# 模型精调 + +## 精调\-按 token 后付费 + + +|基础模型 ID |LoRA精调|全量精调|\ +| |元/百万token |元/百万token | +|---|---|---| +|doubao\-seed\-1.6 |40 |80 | +|doubao\-seed\-1.6\-flash |7 |14 | +|doubao\-1\-5\-pro\-32k\-250115 |50 |100 | +|doubao\-1\-5\-lite\-32k\-250115 |30 |60 | + +> 训练费用 = 总 token 数 x 精调单价 =(用户训练集token数+混入token数+验证集token数)x 迭代轮次 x 精调token单价 +> * 若 token 数小于 1000,将会上取整为 1000 tokens 计算。 + + +## 精调\-按算力付费 + + +|算力规格 |计费方式 |定价|\ +| | |元/小时 | +|---|---|---| +|方舟A型模型单元 |按量后付费 |25 | +|方舟B型模型单元 |按量后付费 |15 | +|方舟C型模型单元 |按量后付费 |10 | +|方舟D型模型单元 |按量后付费 |20 | + +> 训练费用=训练计费时长*使用的模版单价=训练计费时长*模型单元数\*模型单元单价。 + + +## 推理\-在线推理 + + +|精调模型对应的基础模型 |条件(千 token) |输入|输出|\ +| | |元/百万token |元/百万token | +|---|---|---|---| +|doubao\-seed\-1.6 |输入长度 [0, 32] |1.60 |16.00 | +|^^|输入长度 (32, 128] |2.40 |32.00 | +|doubao\-seed\-1.6\-flash |输入长度 [0, 32] |0.30 |3.00 | +|^^|输入长度 (32, 128] |0.60 |6.00 | +|doubao\-1.5\-pro\-32k |\- |2.00 |5.00 | +|doubao\-1.5\-lite\-32k |\- |0.75 |1.50 | +|doubao\-pro\-32k |\- |0.80 |2.00 | + +> 按 token 后付费价格,仅部分 doubao 模型在精调后支持按 token 付费,以[接入点创建页](https://console.volcengine.com/ark/region:ark+cn-beijing/endpoint/create)可选的付费方式为准。 + + +## 推理\-批量推理 + + +|精调模型对应的基础模型 |条件(千 token) |输入|缓存命中|输出|\ +| | |元/百万token |元/百万token |元/百万token | +|---|---|---|---|---| +|doubao\-seed\-1.6 |输入长度 [0, 32] |0.40 |0.16 |4.00 | +|^^|输入长度 (32, 128] |0.60 |0.16 |8.00 | +|^^|输入长度 (128, 256] |1.20 |0.16 |12.00 | +|doubao\-seed\-1.6\-flash |输入长度 [0, 32] |0.075 |0.03 |0.75 | +|^^|输入长度 (32, 128] |0.15 |0.03 |1.50 | +|^^|输入长度 (128, 256] |0.30 |0.03 |3.00 | +|doubao\-1.5\-pro\-32k |\- |0.40 |0.16 |1.00 | +|doubao\-1.5\-lite\-32k |\- |0.15 |0.06 |0.30 | +|doubao\-pro\-32k |\- |0.80 |0.16 |2.00 | + +> 按token后付费,相比在线推理,价格低至50%。 + + +# 模型单元 + + +|机型 |计费方式 |定价|\ +| | |元/个 | +|---|---|---| +|方舟A型模型单元 |按购买时长后付费 |25.00 | +|^^|包月预付费 |16700.00 | +|方舟B型模型单元 |按购买时长后付费 |15.00 | +|^^|包月预付费 |10400.00 | +|方舟C型模型单元 |按购买时长后付费 |10.00 | +|^^|包月预付费 |7100.00 | +|方舟D型模型单元 |按购买时长后付费 |20.00 | +|^^|包月预付费 |12800.00 | + +> 支持「按购买时长后付费」和「包月预付费」两种方式叠加购买,可灵活组合。 +> **提供** [单元计算器](https://console.volcengine.com/ark/region:ark+cn-beijing/endpoint/create) 估算需要的机型数量。更推荐通过实际业务流量压测,计算需要的机型和数量。 + + +# 工具及插件 + +## 联网内容插件 + + +|服务项 |价格|说明 |\ +| |元/千次 | | +|---|---|---| +|联网资源 |4 |实时搜索互联网公开域内容,每月提供2万次免费额度。 | +|头条资源 |6 |实时搜索今日头条图文内容,并提供内容详情信息供展示交互卡片。 | +|抖音资源 |6 |实时搜索抖音百科内容,并提供内容详情信息供展示交互卡片。 | +|墨迹天气 |6 |实时搜索墨迹天气内容资源。 | + + +> * 出账及计费:按量后付费 +> * 用量:每次请求产生的调用次数,可返回结构体的 **source_type** 字段计算得到。 +> * 更多说明请参见 [联网内容插件功能说明](/docs/82379/1338552)。 + + +## 豆包助手 + + +|服务项 |价格|说明 |\ +| |元/次 | | +|---|---|---| +|日常沟通 |0.1 |全能助手,自然交流,多轮对话,高情商人格化聊天。 | +|深度沟通 |0.2 |深度理解,精准解析,先思考再回答,复杂问题尽在掌握。 | +|联网搜索 |0.2 |全网搜索,信源丰富,无需费力找资料,一键搜索实时资讯。 | +|边想边搜 |0.5 |逻辑缜密,深度洞察,遇难题问豆包,想得更深,答得更准。 | + + +> * 出账及计费:按量后付费 +> * 用量:每次请求产生的调用次数,可返回结构体的 **source_type** 字段计算得到。 +> * 更多说明请参见 [联网内容插件功能说明](/docs/82379/1338552)。 + + +## 知识库 + + +|服务项 |价格 | +|---|---| +|计算资源\-知识库【旗舰版】 |0.45 元/CU/小时 | +|离线存储资源\-知识库【旗舰版】 |0.0015 元/GB/小时 | +|标准计算资源\-知识库【标准版】 |0.0416 元/知识库/小时 | +|文本向量模型\-知识库【通用】 |0.0005 元/千token | +|文本向量模型(多功能版)\-知识库【通用】 |0.0005 元/千token | +|文本向量模型(Doubao\-embedding)\-知识库【通用】 |0.0005 元/千token | +|文本向量模型(Doubao\- embedding\-large)\-知识库【通用】 |0.0007 元/千token | +|多模态向量模型(Doubao\-embedding\-vision\-text)\-知识库【通用】 |0.0007 元/千token | +|多模态向量模型(Doubao\-embedding\-vision\-image)\-知识库【通用】 |0.0018 元/千token | +|重排模型\-知识库【通用】 |0.0005 元/千token | + +> 更多说明请参见 [知识库计费](/docs/82379/1263336)。 + + +# Coding Plan 个人版 + + +|套餐类型 |订阅时长 |价格 | +|---|---|---| +|Lite 套餐 |1 个月 |40 元/月 | +|^^|3 个月 |120 元/季 | +|Pro 套餐 |1 个月 |200 元/月 | +|^^|3 个月 |600 元/季 | + +> 套餐信息及特惠活动参见[套餐概览](/docs/82379/1925114)。 + + + diff --git a/docs/API文档/创建视频生成任务API.md b/docs/API文档/创建视频生成任务API.md new file mode 100644 index 0000000..a9c7c3c --- /dev/null +++ b/docs/API文档/创建视频生成任务API.md @@ -0,0 +1,648 @@ +`POST https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks` [ ](https://api.volcengine.com/api-explorer/?action=CreateContentsGenerationsTasks&data=%7B%7D&groupName=%E8%A7%86%E9%A2%91%E7%94%9F%E6%88%90API&query=%7B%7D&serviceCode=ark&version=2024-01-01)[运行](https://api.volcengine.com/api-explorer/?action=CreateContentsGenerationsTasks&data=%7B%7D&groupName=%E8%A7%86%E9%A2%91%E7%94%9F%E6%88%90API&query=%7B%7D&serviceCode=ark&version=2024-01-01) +本文介绍创建视频生成任务 API 的输入输出参数,供您使用接口时查阅字段含义。模型会依据传入的图片及文本信息生成视频,待生成完成后,您可以按条件查询任务并获取生成的视频。 +:::tip +请确保您的账户余额大于等于 200 元([前往充值](https://console.volcengine.com/finance/fund/recharge)),或已[购买资源包](https://console.volcengine.com/common-buy/fast/ark_bd%7C%7Cd682ppeeq1mp7kd5q0e0),否则无法开通 seedance 2.0 及 seedance 2.0 fast 模型。 + +::: +**模型能力==^new^==** + +* **seedance 2.0 & 2.0 fast==^new^==** ** (有声视频/无声视频)** + * **多模态参考生视频==^new^==**:输入++参考图片(0~9)+参考视频(0~3)+ 参考音频(0~3)+ 文本提示词(可选)++ 生成 1 个目标视频。注意不可单独输入音频,应至少包含 1 个参考视频或图片。支持生成全新视频、编辑视频、延长视频,[阅读教程](https://www.volcengine.com/docs/82379/2291680) 获取详细代码示例。 + * **图生视频\-首尾帧**:输入++首帧图片+尾帧图片+文本提示词(可选)++ 生成 1 个目标视频。 + * **图生视频\-首帧**:输入++首帧图片+文本提示词(可选)++ 生成 1 个目标视频。 + * **文生视频**:输入++文本提示词++生成 1 个目标视频。 +* **seedance 1.5 pro (有声视频/无声视频)** + 【图生视频\-首尾帧】【图生视频\-首帧】【文生视频】 +* **seedance 1.0 pro** + 【图生视频\-首尾帧】【图生视频\-首帧】【文生视频】 +* **seedance 1.0 pro fast** + 【图生视频\-首帧】【文生视频】 +* **seedance 1.0 lite** + * **doubao\-seedance\-1\-0\-lite\-t2v:** 文生视频 + * **doubao\-seedance\-1\-0\-lite\-i2v:** + * 参考图生视频:根据您输入的**++参考图片(1\-4张)++ ** +++文本提示词(可选)++ 生成 1 个目标视频。 + * 图生视频\-首尾帧 + * 图生视频\-首帧 + + +Tips:一键展开折叠,快速检索内容 +打开页面右上角开关,**ctrl ** + **f** 可检索页面内所有内容。 +![图片](https://portal.volccdn.com/obj/volcfe/cloud-universal-doc/upload_cae7ddb0e1977b68b353f17897b8574c.png) + + +```mixin-react +return ( + +`}> + +![图片](https://portal.volccdn.com/obj/volcfe/cloud-universal-doc/upload_2abecd05ca2779567c6d32f0ddc7874d.png =20x) [模型列表](https://www.volcengine.com/docs/82379/1330310?lang=zh#2705b333) ![图片](https://portal.volccdn.com/obj/volcfe/cloud-universal-doc/upload_a5fdd3028d35cc512a10bd71b982b6eb.png =20x) [模型计费](https://www.volcengine.com/docs/82379/1544106?redirect=1&lang=zh#02affcb8) ![图片](https://portal.volccdn.com/obj/volcfe/cloud-universal-doc/upload_afbcf38bdec05c05089d5de5c3fd8fc8.png =20x) [API Key](https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey?apikey=%7B%7D) + ![图片](https://portal.volccdn.com/obj/volcfe/cloud-universal-doc/upload_57d0bca8e0d122ab1191b40101b5df75.png =20x) [调用教程](https://www.volcengine.com/docs/82379/1366799) ![图片](https://portal.volccdn.com/obj/volcfe/cloud-universal-doc/upload_f45b5cd5863d1eed3bc3c81b9af54407.png =20x) [接口文档](https://www.volcengine.com/docs/82379/1520758) ![图片](https://portal.volccdn.com/obj/volcfe/cloud-universal-doc/upload_1609c71a747f84df24be1e6421ce58f0.png =20x) [常见问题](https://www.volcengine.com/docs/82379/1359411) ![图片](https://portal.volccdn.com/obj/volcfe/cloud-universal-doc/upload_bef4bc3de3535ee19d0c5d6c37b0ffdd.png =20x) [开通模型](https://console.volcengine.com/ark/region:ark+cn-beijing/openManagement?LLM=%7B%7D&OpenTokenDrawer=false) +`}>); +``` + + +--- + + + +## 请求参数 +> 跳转 [响应参数](#y2hhTyHB) + + +### 请求体 + +--- + + +**model** `string` %%require%% +您需要调用的模型的 ID (Model ID),[开通模型服务](https://console.volcengine.com/ark/region:ark+cn-beijing/openManagement?LLM=%7B%7D&OpenTokenDrawer=false),并[查询 Model ID](https://www.volcengine.com/docs/82379/1330310) 。 +您也可通过 Endpoint ID 来调用模型,获得限流、计费类型(前付费/后付费)、运行状态查询、监控、安全等高级能力,可参考[获取 Endpoint ID](https://www.volcengine.com/docs/82379/1099522)。 + +--- + + +**content** `object[]` %%require%% +输入给模型,生成视频的信息,支持文本、图片、音频、视频、样片任务 ID。 +:::warning +seedance 2.0 系列模型不支持直接上传含有真人人脸的参考图/视频。为了便利创作者对肖像的使用,平台推出了以下解决方案,详情参见 [教程](https://www.volcengine.com/docs/82379/2291680?lang=zh#5c67c9a1)。 + +* 支持使用部分模型的含人脸原始产物作为输入素材 +* 支持使用预置虚拟人像作为输入素材 +* 支持使用已授权真人素材作为输入 + +::: +支持以下几种组合: + +* **文本** +* **文本(可选)+ 图片** +* **文本(可选)+ 视频** +* **文本(可选)+ 图片 + 音频** +* **文本(可选)+ 图片 + 视频** +* **文本(可选)+ 视频 + 音频** +* **文本(可选)+ 图片 + 视频 + 音频** +* **样片任务 ID**:样片指使用 seedance 模型成功生成的样片视频,模型可基于样片生成高质量正式视频。 + + +信息类型 + +--- + + +**文本信息** `object` +输入给模型的提示词信息。 + +属性 + +--- + + +content.**type ** `string` %%require%% +输入内容的类型,此处应为 `text`。 + +--- + + +content.**text ** `string` %%require%% +输入给模型的文本提示词,描述期望生成的视频。 +:::tip + +* 提示词语言支持:所有模型均支持中英文提示词;seedance 2.0 及 seedance 2.0 fast 额外支持日语、印尼语、西班牙语、葡萄牙语。 +* 提示词字数建议:中文提示词不超过500字,英文提示词不超过1000词。字数过多易导致信息分散,模型可能忽略细节、仅关注重点,进而造成视频缺失部分元素。 +* 更多使用技巧:提示词的详细使用技巧,请参见 [seedance 提示词指南](https://www.volcengine.com/docs/82379/2222480?lang=zh)。 + + + +::: + +--- + + +**图片信息==^new^==** `object` +输入给模型的图片信息。 + +属性 + +--- + + +content.**type ** `string` %%require%% +输入内容的类型,此处应为 `image_url`。 + +--- + + +content.**image_url ** `object` %%require%% +输入给模型的图片对象。 + +属性 + +--- + + +content.image_url.**url ** `string` %%require%% +图片 URL 、图片 Base64 编码、素材 ID。 + +* 图片 URL:填入图片的公网 URL。 +* Base64 编码:将本地文件转换为 Base64 编码字符串,然后提交给大模型。遵循格式:`data:image/<图片格式>;base64,`,注意 `<图片格式>` 需小写,如 `data:image/png;base64,{base64_image}`。 +* 素材 ID:用于视频生成的预置素材及虚拟人像的 ID,遵循格式:asset://。可从 [素材&虚拟人像库](https://console.volcengine.com/ark/region:ark+cn-beijing/experience/vision?modelId=doubao-seedance-2-0-260128) 获取。 + +:::tip 传入单张图片要求 + +* 格式:jpeg、png、webp、bmp、tiff、gif。其中,seedance 1.5 pro 新增支持 heic 和 heif。 +* 宽高比(宽/高): (0.4, 2.5) +* 宽高长度(px):(300, 6000) +* 大小:单张图片小于 30 MB。请求体大小不超过 64 MB。大文件请勿使用Base64编码。 +* 图片数量: + * 图生视频\-首帧:1 张 + * 图生视频\-首尾帧:2 张 + * seedance 2.0&2.0 fast 多模态参考生视频:1~9 张 + * seedance 1.0 lite 参考图生视频:1~4 张 + +::: + +--- + + +content.**role ** `string` `条件必填` +图片的位置或用途。 +:::warning + +* **图生视频\-首帧**、**图生视频\-首尾帧**、**多模态参考生视频**(包括参考图、视频、音频)为 3 种互斥场景,**不可混用**。 +* **多模态参考生视频**可通过提示词指定参考图片作为首帧/尾帧,间接实现“首尾帧+多模态参考”效果。若需严格保障首尾帧和指定图片一致,**优先使用图生视频\-首尾帧**(配置 role 为 first_frame/last_frame)。 + + +::: +图生视频\-首帧 + +* **支持模型:** 所有图生视频模型 +* **字段role取值:** 需要传入1个 image_url 对象,字段 role 为 first_frame 或不填。 + + +图生视频\-首尾帧 + +* **支持模型:** seedance 2.0 & 2.0 fast,seedance 1.5 pro、seedance 1.0 pro、seedance 1.0 lite i2v +* **字段role取值:** 需要传入2个image_url对象,且字段 role 必填。 + * 首帧图片对应的字段 role 为:first_frame + * 尾帧图片对应的字段 role 为:last_frame + +:::tip +传入的首尾帧图片可相同。首尾帧图片的宽高比不一致时,以首帧图片为主,尾帧图片会自动裁剪适配。 + +::: + +图生视频\-参考图 + +* **支持模型:** seedance 2.0 & 2.0 fast(1~9 张图片),seedance 1.0 lite i2v(1~4 张图片) +* **字段role取值:** 必填,每张参考图对应的字段 role 均为:reference_image + +:::tip +参考图生视频功能的文本提示词,可以用自然语言指定多张图片的组合。但若想有更好的指令遵循效果,**推荐使用“[图1]xxx,[图2]xxx”的方式来指定图片**。 +示例1:戴着眼镜穿着蓝色T恤的男生和柯基小狗,坐在草坪上,3D卡通风格 +示例2:[图1]戴着眼镜穿着蓝色T恤的男生和[图2]的柯基小狗,坐在[图3]的草坪上,3D卡通风格 + +::: + + +--- + + +**视频信息==^new^==** `object` +输入给模型的视频信息。仅 seedance 2.0 & 2.0 fast 支持输入视频。 +方舟平台信任 seedance 2.0 及 2.0 fast 模型生成的含人脸视频,您可使用**本账号下近30天内由上述模型生成的含人脸原始视频**,作为输入素材进行二次创作,详情参见 [教程](https://www.volcengine.com/docs/82379/2291680?lang=zh#86c3831f)。 + +属性 +content.**type ** `string` %%require%% +输入内容的类型,此处应为`video_url`。 + +--- + + +content.**video_url** ** ** `object` %%require%% +输入给模型的视频对象。 + +属性 +content.video_url.**url ** `string` %%require%% +视频URL、素材 ID。 + +* 视频 URL:填入视频的公网 URL。 +* 素材 ID:用于视频生成的预置素材及虚拟人像视频的 ID,遵循格式:asset://。可从[素材&虚拟人像库](https://console.volcengine.com/ark/region:ark+cn-beijing/experience/vision?modelId=doubao-seedance-2-0-260128)获取。 + +:::tip 传入单个视频要求 + +* 视频格式:mp4、mov,支持编码格式见下表。 +* 分辨率:480p,720p,1080p +* 时长:单个视频时长 [2, 15] s,最多传入 3 个参考视频,所有视频总时长不超过 15s。 +* 尺寸: + * 宽高比(宽/高):[0.4, 2.5] + * 宽高长度(px):[300, 6000] + * 总像素数:[640×640=409600, 2206×946=2086876],即宽和高的乘积符合 [409600, 2086876] 的区间要求。 +* 大小:单个视频不超过 50 MB。 +* 帧率 (FPS):[24, 60] + +::: + +--- + + +content.**role ** `string` `条件必填` +视频的位置或用途。当前仅支持 reference_video:参考视频。 + + +--- + + +**音频信息==^new^==** `object` +输入给模型的音频信息。仅 seedance 2.0&2.0 fast 支持输入音频。 +注意不可单独输入音频,应至少包含 1 个参考视频或图片。 + +属性 +content.**type ** `string` %%require%% +输入内容的类型,此处应为`audio_url`。 + +--- + + +content.**audio_url** ** ** `object` %%require%% +输入给模型的音频对象。 + +属性 +content.audio_url.**url ** `string` %%require%% +音频 URL 、音频 Base64 编码、素材 ID。 + +* 音频 URL:填入音频的公网 URL。 +* Base64 编码:将本地文件转换为 Base64 编码字符串,然后提交给大模型。遵循格式:`data:audio/<音频格式>;base64,`,注意 `<音频格式>` 需小写,如 `data:audio/wav;base64,{base64_audio}`。 +* 素材 ID:用于视频生成的虚拟人的音频素材 ID,遵循格式:asset://。可从[素材&虚拟人像库](https://console.volcengine.com/ark/region:ark+cn-beijing/experience/vision?modelId=doubao-seedance-2-0-260128)获取。 + +:::tip 传入单个音频要求 + +* 格式:wav、mp3 +* 时长:单个音频时长 [2, 15] s,最多传入 3 段参考音频,所有音频总时长不超过 15 s。 +* 大小:单个音频不超过 15 MB,请求体大小不超过 64 MB。大文件请勿使用Base64编码。 + + + +::: + +--- + + +content.**role ** `string` `条件必填` +音频的位置或用途。当前仅支持 reference_audio:参考音频。 + + + +--- + + +**样片信息 ** `object` +基于样片任务 ID,生成正式视频。仅 seedance 1.5 pro 支持该功能。[阅读](https://www.volcengine.com/docs/82379/1366799?lang=zh#5acd28c8)[文档](https://www.volcengine.com/docs/82379/1366799?lang=zh#5acd28c8) 获取 draft 功能的使用教程和注意事项。 + +属性 + +--- + + +content.**type ** `string` %%require%% +输入内容的类型,此处应为 `draft_task`。 + +--- + + +content.**draft_task** ** ** `object` %%require%% +输入给模型的样片任务。 + +属性 + +--- + + +content.draft_task.**id ** `string` %%require%% +样片任务 ID。平台将自动复用 Draft 视频使用的用户输入(**model、** content.**text、** content.**image_url、generate_audio、seed、ratio、duration、camera_fixed ** ),生成正式视频。其余参数支持指定,不指定将使用本模型的默认值。 +使用分为两步:Step1: 调用本接口生成 Draft 视频。Step2: 如果确认 Draft 视频符合预期,可基于 Step1 返回的 Draft 视频任务 ID,调用本接口生成最终视频。[阅读文档](https://www.volcengine.com/docs/82379/1366799?lang=zh#5acd28c8) 获取详细教程。 + + + + +--- + + +**callback_url** `string` +填写本次生成任务结果的回调通知地址。当视频生成任务有状态变化时,方舟将向此地址推送 POST 请求。 +回调请求内容结构与[查询任务API](https://www.volcengine.com/docs/82379/1521309)的返回体一致。 +回调返回的 status 包括以下状态: + +* queued:排队中。 +* running:任务运行中。 +* succeeded: 任务成功。(如发送失败,即5秒内没有接收到成功发送的信息,回调三次) +* failed:任务失败。(如发送失败,即5秒内没有接收到成功发送的信息,回调三次) +* expired:任务超时,即任务处于**运行中或排队中**状态超过过期时间。可通过 **execution_expires_after ** 字段设置过期时间。 + + +--- + + +**return_last_frame** `boolean` `默认值 false` + +* true:返回生成视频的尾帧图像。设置为 `true` 后,可通过 [查询视频生成任务接口](https://www.volcengine.com/docs/82379/1521309) 获取视频的尾帧图像。尾帧图像的格式为 png,宽高像素值与生成的视频保持一致,无水印。 + 使用该参数可实现生成多个连续视频:以上一个生成视频的尾帧作为下一个视频任务的首帧,快速生成多个连续视频,调用示例详见 [教程](https://www.volcengine.com/docs/82379/1366799?lang=zh#141cf7fa)。 +* false:不返回生成视频的尾帧图像。 + + +--- + + +**service_tier** `string` `默认值 default` +> 不支持修改已提交任务的服务等级 +> seedance 2.0 & 2.0 fast 不支持离线推理 + +指定处理本次请求的服务等级类型,枚举值: + +* default:在线推理模式,RPM 和并发数配额较低(详见 [模型列表](https://www.volcengine.com/docs/82379/1330310?lang=zh#2705b333)),适合对推理时效性要求较高的场景。 +* flex:离线推理模式,TPD 配额更高(详见 [模型列表](https://www.volcengine.com/docs/82379/1330310?lang=zh#2705b333)),价格为在线推理的 50%, 适合对推理时延要求不高的场景。 + + +--- + + +**execution_expires_after ** `integer` `默认值 172800` +任务超时阈值。指定任务提交后的过期时间(单位:秒),从 **created at** 时间戳开始计算。默认值 172800 秒,即 48 小时。取值范围:[3600,259200]。 +不论使用哪种 **service_tier**,都建议根据业务场景设置合适的超时时间。超过该时间后任务会被自动终止,并标记为`expired`状态。 + +--- + + +**generate_audio ** `boolean` `默认值 true` +> 仅 seedance 2.0 & 2.0 fast、seedance 1.5 pro 支持 + +控制生成的视频是否包含与画面同步的声音。 + +* true:模型输出的视频包含同步音频。模型会基于文本提示词与视觉内容,自动生成与之匹配的人声、音效及背景音乐。建议将对话部分置于双引号内,以优化音频生成效果。例如:男人叫住女人说:“你记住,以后不可以用手指指月亮。” +* false:模型输出的视频为无声视频。 + +:::warning +生成的有声视频均为单声道,和传入的音频声道数无关。 + +::: +--- + + +**draft ** `boolean` `默认值 false` +> 仅 seedance 1.5 pro 支持 + +控制是否开启样片模式。[阅读文档](https://www.volcengine.com/docs/82379/1366799?lang=zh#5acd28c8) 获取使用教程和注意事项。 + +* true:开启样片模式,生成一段预览视频,快速验证场景结构、镜头调度、主体动作与 prompt 意图是否符合预期。消耗 token 数较正常视频更少,使用成本更低。 +* false:关闭样片模式,正常生成一段视频。 + +:::tip +开启样片模式后,将使用 480p 分辨率生成 Draft 视频(使用其他分辨率会报错),不支持返回尾帧功能,不支持离线推理功能。 + +::: +--- + + +**tools==^new^==** ** ** `object[]` +> 仅 seedance 2.0 & 2.0 fast 支持 + +配置模型要调用的工具。 + +属性 +tools.**type ** `string` +指定使用的工具类型。 + +* web_search:联网搜索工具。[阅读教程](https://www.volcengine.com/docs/82379/1366799?lang=zh#c40ed3ef) 获取详细代码示例。 + +:::tip + +* 开启联网搜索后,模型会根据用户的提示词自主判断是否搜索互联网内容(如商品、天气等)。可提升生成视频的时效性,但也会增加一定的时延。 +* 实际搜索次数可通过 [查询视频生成任务 API](https://www.volcengine.com/docs/82379/1521309?lang=zh) 返回的 usage.tool_usage.**web_search** 字段获取,如果为 0 表示未搜索。 + +::: + +--- + + +**safety_identifier==^new^==** `string` +终端用户的唯一标识符,用于协助平台检测您的应用中可能违反火山方舟使用政策的用户。该标识符为英文字符串,需保证对单个用户固定且唯一,长度不超过 64 个字符。推荐传入对用户名、用户 ID 或邮箱进行哈希处理后生成的字符串,避免泄露用户隐私信息。 + +--- + + +  +:::warning 部分参数升级说明 + +* **对于 resolution、ratio、duration、frames、seed、camera_fixed、watermark 参数,平台升级了参数传入方式,示例如下。所有模型依然兼容支持旧方式。** +* 不同模型,可能对应支持不同的参数与取值,详见 [输出视频格式](https://www.volcengine.com/docs/82379/1366799?lang=zh#9fe4cce0)。当输入的参数或取值不符合所选的模型时,该参数将被忽略或触发报错: + * 新方式:在 request body 中直接传入参数。此方式为**强校验,** 若参数填写错误,模型会返回错误提示。 + * 旧方式:在文本提示词后追加 \-\-[parameters]。此方式为**弱校验,** 若参数填写错误,该参数将被忽略或触发报错。 + + +::: +**新方式(推荐):在 request body 中直接传入参数** +```JSON +... + // Specify the aspect ratio of the generated video as 16:9, duration as 5 seconds, resolution as 720p, seed as 11, and include a watermark. The camera is not fixed. + "model": "doubao-seedance-1-5-pro-251215", + "content": [ + { + "type": "text", + "text": "小猫对着镜头打哈欠" + } + ], + // All parameters must be written in full; abbreviations are not supported + "resolution": "720p", + "ratio":"16:9", + "duration": 5, + // "frames": 29, Either duration or frames is required + "seed": 11, + "camera_fixed": false, + "watermark": true +... +``` + + + + +**旧方式:在文本提示词后追加 \-\-[parameters]** +```JSON +... + // Specify the aspect ratio of the generated video as 16:9, duration as 5 seconds, resolution as 720p, seed as 11, and include a watermark. The camera is not fixed. + "model": "doubao-seedance-1-5-pro-251215", + "content": [ + { + "type": "text", + "text": "小猫对着镜头打哈欠 --rs 720p --rt 16:9 --dur 5 --seed 11 --cf false --wm true" + // "text": "小猫对着镜头打哈欠 --resolution 720p --ratio 16:9 --duration 5 --seed 11 --camerafixed false --watermark true" + } + ] +... +``` + + + + +--- + + +**resolution ** `string` +> seedance 2.0 & 2.0 fast、seedance 1.5 pro、seedance 1.0 lite 默认值:`720p` +> seedance 1.0 pro & pro\-fast 默认值:`1080p` + +视频分辨率,枚举值: + +* 480p +* 720p +* 1080p:seedance 1.0 lite 参考图场景、seedance 2.0 & 2.0 fast 不支持 + + +--- + + +**ratio ** `string` +> seedance 2.0 & 2.0 fast、seedance 1.5 pro 默认值为 `adaptive` +> seedance 1.0 lite 参考图场景默认值为 `16:9` +> 其他模型:文生视频默认值 `16:9`,图生视频默认值 `adaptive` + +生成视频的宽高比例。不同宽高比对应的宽高像素值见下方表格。 + +* 16:9 +* 4:3 +* 1:1 +* 3:4 +* 9:16 +* 21:9 +* adaptive:根据输入自动选择最合适的宽高比(详见下文说明) + +:::warning **adaptive ** 适配规则 +当配置 **ratio** 为 `adaptive` 时,模型会根据生成场景自动适配宽高比;实际生成的视频宽高比可通过 [查询视频生成任务 API](https://www.volcengine.com/docs/82379/1521309?lang=zh) 返回的 **ratio** 字段获取。 +**支持模型:** + +* seedance 2.0 & 2.0 fast、seedance 1.5 Pro 支持 +* 其他模型仅图生视频场景支持,注意 seedance 1.0 lite 参考图场景不支持。 + +**取值规则:** + +* 文生视频:根据输入的提示词,智能选择最合适的宽高比。 +* 首帧 / 首尾帧生视频:根据上传的首帧图片比例,自动选择最接近的宽高比。 +* 多模态参考生视频:根据用户提示词意图判断,如果是首帧生视频/编辑视频/延长视频,以该图片/视频为准选择最接近的宽高比;否则,以传入的第一个媒体文件为准(优先级:视频>图片)选择最接近的宽高比。 + +::: +  + +不同宽高比对应的宽高像素值 +Note:图生视频,选择的宽高比与您上传的图片宽高比不一致时,方舟会对您的图片进行裁剪,裁剪时会居中裁剪,详细规则见 [图片裁剪规则](https://www.volcengine.com/docs/82379/1366799?lang=zh#f76aafc8)。 + +|分辨率 |宽高比|宽高像素值|宽高像素值|\ +| | |seedance 1.0 系列 |seedance 1.5 pro|\ +| | | |seedance 2.0 & 2.0 fast | +|---|---|---|---| +|480p |16:9 |864×480 |864×496 | +|^^|4:3 |736×544 |752×560 | +|^^|1:1 |640×640 |640×640 | +|^^|3:4 |544×736 |560×752 | +|^^|9:16 |480×864 |496×864 | +|^^|21:9 |960×416 |992×432 | +|720p |16:9 |1248×704 |1280×720 | +|^^|4:3 |1120×832 |1112×834 | +|^^|1:1 |960×960 |960×960 | +|^^|3:4 |832×1120 |834×1112 | +|^^|9:16 |704×1248 |720×1280 | +|^^|21:9 |1504×640 |1470×630 | +|1080p |16:9 |1920×1088 |1920×1080 |\ +|> 1.0 lite 参考图场景不支持,seedance 2.0 & 2.0 fast不支持 | | | | +|^^|4:3 |1664×1248 |1664×1248 | +|^^|1:1 |1440×1440 |1440×1440 | +|^^|3:4 |1248×1664 |1248×1664 | +|^^|9:16 |1088×1920 |1080×1920 | +|^^|21:9 |2176×928 |2206×946 | + + + + +--- + + +**duration** `integer` `默认值 5` +> duration 和 frames 二选一即可,frames 的优先级高于 duration。如果您希望生成整数秒的视频,建议指定 duration。 + +生成视频时长,仅支持整数,单位:秒。 + +* seedance 1.0 pro、seedance 1.0 pro fast、seedance 1.0 lite: [2, 12] s。 +* seedance 1.5 pro: [4,12] 或设置为`-1` +* seedance 2.0 & 2.0 fast: [4,15] 或设置为`-1` + +:::warning +seedance 2.0 & 2.0 fast、seedance 1.5 pro 支持两种配置方法 + + * 指定具体时长:支持有效范围内的任一整数。 + * 智能指定:设置为 `-1`,表示由模型在有效范围内自主选择合适的视频长度(整数秒)。实际生成视频的时长可通过 [查询视频生成任务 API](https://www.volcengine.com/docs/82379/1521309?lang=zh) 返回的 **duration** 字段获取。注意视频时长与计费相关,请谨慎设置。 + + +::: +--- + + +**frames** `integer` +> seedance 2.0 & 2.0 fast、seedance 1.5 pro 暂不支持 +> duration 和 frames 二选一即可,frames 的优先级高于 duration。如果您希望生成小数秒的视频,建议指定 frames。 + +生成视频的帧数。通过指定帧数,可以灵活控制生成视频的长度,生成小数秒的视频。 +由于 frames 的取值限制,仅能支持有限小数秒,您需要根据公式推算最接近的帧数。 + +* 计算公式:帧数 = 时长 × 帧率(24)。 +* 取值范围:支持 [29, 289] 区间内所有满足 `25 + 4n` 格式的整数值,其中 n 为正整数。 + +例如:假设需要生成 2.4 秒的视频,帧数=2.4×24=57.6。由于 frames 不支持 57.6,此时您只能选择一个最接近的值。根据 25+4n 计算出最接近的帧数为 57,实际生成的视频为 57/24=2.375 秒。 + +--- + + +**seed** `integer` `默认值 -1` +种子整数,用于控制生成内容的随机性。 +取值范围:[\-1, 2^32\-1]之间的整数。 +:::warning + +* 相同的请求下,模型收到不同的seed值,如:不指定seed值或令seed取值为\-1(会使用随机数替代)、或手动变更seed值,将生成不同的结果。 +* 相同的请求下,模型收到相同的seed值,会生成类似的结果,但不保证完全一致。 + + +::: +--- + + +**camera_fixed** `boolean` `默认值 false` +> 参考图场景不支持,seedance 2.0 & 2.0 fast 暂不支持 + +是否固定摄像头。枚举值: + +* true:固定摄像头。平台会在用户提示词中追加固定摄像头,实际效果不保证。 +* false:不固定摄像头。 + + +--- + + +**watermark** `boolean` `默认值 false` +生成视频是否包含水印。枚举值: + +* false:不含水印。 +* true:含有水印。 + + +--- + + + +## 响应参数 +> 跳转 [请求参数](#RxN8G2nH) + +**id ** `string` +视频生成任务 ID 。仅保存 7 天(从 **created at** 时间戳开始计算),超时后将自动清除。 + +* 设置`"draft": true`,为 Draft 视频任务 ID。 +* 设置 `"draft": false`,为正常视频任务 ID。 + +创建视频生成任务为异步接口,获取 ID 后,需要通过 [查询视频生成任务 API](https://www.volcengine.com/docs/82379/1521309) 来查询视频生成任务的状态。任务成功后,会输出生成视频的`video_url`。 + + diff --git a/docs/celery-polling-fix-20260404.md b/docs/celery-polling-fix-20260404.md deleted file mode 100644 index 6f6013a..0000000 --- a/docs/celery-polling-fix-20260404.md +++ /dev/null @@ -1,134 +0,0 @@ -# Celery 轮询机制修复报告 - -> 日期:2026-04-04 -> 版本:v0.16.0 -> 影响范围:backend/apps/generation/tasks.py, backend/config/settings.py - ---- - -## 一、问题现象 - -2026/4/1 下午,大量用户反馈视频生成任务长时间卡在"生成中",前端显示耗时 60~65 分钟。 -火山引擎侧确认视频实际生成仅需约 10 分钟,结果已就绪但未被平台及时同步。 - -**截图数据**(4/1 下午完成的任务): - -| 提交时间 | 显示耗时 | -|---------|---------| -| 2026/4/1 16:57:28 | 63 分 33 秒 | -| 2026/4/1 16:58:41 | 62 分 37 秒 | -| 2026/4/1 16:59:16 | 62 分 7 秒 | -| 2026/4/1 17:00:36 | 64 分 24 秒 | -| 2026/4/1 17:04:53 | 64 分 2 秒 | - -## 二、根因分析 - -### 2.1 状态同步链路 - -``` -用户提交任务 - → 后端调 create_task(火山 API) - → 获得 ark_task_id - → 派发 Celery 任务 poll_video_task - → Celery worker 每 5 秒查一次火山 API - → 火山返回完成 → 写 DB + 上传 TOS + 结算 - → 前端轮询 DB → 展示结果 -``` - -前端只读 DB 状态,**不直接调火山 API**。整个链路完全依赖 Celery worker 轮询。 - -### 2.2 旧实现缺陷 - -`poll_video_task` 使用 `while True` + `time.sleep(5)` 长驻循环: - -```python -# 旧代码 -while True: - time.sleep(POLL_INTERVAL) # 5 秒 - ark_resp = query_task(...) # 查一次 - if terminal: - break -``` - -**三个致命问题:** - -| 问题 | 影响 | -|------|------| -| 每个任务占死一个 worker 进程 | `concurrency=4` 最多同时轮询 4 个任务,第 5 个排队 | -| worker 重启后循环直接丢失 | 内存中的 `while True` 不可持久化,OOM/重启 = 任务丢失 | -| `time.sleep` 浪费进程资源 | worker 99% 时间在 sleep,实际有用工作不到 1% | - -### 2.3 OOM 重启链 - -``` -4 个任务同时轮询 - → 某些任务完成,触发 TOS 上传(下载视频 + 上传对象存储) - → 内存飙升超过 512Mi 限制 - → K8s OOM Kill → worker 重启(共重启 15 次) - → 4 个进程中的 while True 循环全部丢失 - → 等 recover_stuck_tasks(每 10 分钟)重新派发 - → 重新派发后 worker 又被占满 → 又 OOM → 循环 - → 实际恢复耗时 ≈ 50~60 分钟 -``` - -## 三、修复方案 - -### 3.1 核心改动:self.retry 替代 while True - -```python -# 新代码 -@shared_task(bind=True, max_retries=None, ignore_result=True) -def poll_video_task(self, record_id): - record = GenerationRecord.objects.get(pk=record_id) - - ark_resp = query_task(record.ark_task_id) - new_status = map_status(ark_resp.get('status', '')) - - if new_status in ('queued', 'processing'): - record.save(update_fields=['status', 'updated_at']) - raise self.retry(countdown=5) # 5 秒后重新入队 - - # 到达终态 → 处理结果 - ... -``` - -**原理对比:** - -| | 旧方式(while True) | 新方式(self.retry) | -|---|---|---| -| 任务生命周期 | 在 worker 进程内存中 | 在 Redis 队列中 | -| worker 占用 | 持续占用直到完成(分钟级) | 每次查询仅占用毫秒级 | -| worker 重启 | 任务丢失 | Redis 中的任务自动恢复 | -| 并发能力 | 最多 4 个(= concurrency) | 数百个(受 API RPM 限制) | - -### 3.2 recover_stuck_tasks 间隔缩短 - -| | 旧值 | 新值 | -|---|---|---| -| Beat 调度间隔 | 600 秒(10 分钟) | 180 秒(3 分钟) | -| stuck 判定门槛 | 10 分钟 | 3 分钟 | -| 最坏恢复时间 | ~20 分钟 | ~6 分钟 | - -### 3.3 变更文件 - -| 文件 | 改动 | -|------|------| -| `backend/apps/generation/tasks.py` | `poll_video_task`: while True → self.retry;`recover_stuck_tasks`: 门槛 10 → 3 分钟 | -| `backend/config/settings.py` | Beat schedule: 600 → 180 秒 | - -## 四、效果预估 - -| 指标 | 修复前 | 修复后 | -|------|--------|--------| -| 同时轮询任务数上限 | 4 | 数百 | -| worker 重启后任务恢复 | 丢失,等 10 分钟兜底 | 自动恢复,无需兜底 | -| 最坏同步延迟 | 60+ 分钟 | ~15 秒(= 查询间隔 + 网络延迟) | -| 内存占用 | 持续占满(sleep 期间不释放) | 脉冲式占用(查完释放) | -| OOM 风险 | 高(4 进程常驻 + TOS 上传峰值) | 低(进程闲置时内存极小) | - -## 五、部署注意 - -1. **无需数据库迁移** — 仅修改 Python 代码 -2. **部署后旧的 while True 任务会自然消亡** — 不需要手动干预 -3. **Redis 中可能有旧格式的任务** — 兼容无问题,新旧 `poll_video_task` 签名一致(`record_id` 参数不变) -4. **建议同步部署**:先部署代码,再重启 Celery worker(`kubectl rollout restart deployment celery-worker`) diff --git a/docs/changelog.md b/docs/changelog.md index be3cfd8..9b9a160 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -4,6 +4,71 @@ --- +## 2026-04-17 — v0.18.3: 版权报错友好提示 + 图片删除即梦式连续重命名 + +**状态**: ✅ 已完成 | **验收**: 14 个自动化测试全过(11 单元 + 3 E2E) + +### 变更内容 + +#### 后端 +1. **版权限制错误友好提示** — `OutputVideoSensitiveContentDetected.PolicyViolation`(漫威等知名 IP 触发的版权拦截)加中文错误码映射:"生成的视频涉及版权限制内容(如知名IP、名人肖像等),已被系统拦截,请修改提示词后重试"。精确匹配 API 返回的 code,不影响父级 `OutputVideoSensitiveContentDetected`(敏感内容)的现有提示 + +#### 前端 +2. **图片删除即梦式连续重命名** — 现有逻辑:删图片2 后,图片3 保持原名称,再上传新图会出现"两个图片2"。修复后: + - `inputBar.ts::removeReference` 删除后,同类型(图片/视频/音频)剩余引用按顺序连续重命名(图片1/图片2/图片3 连续无空位) + - 用 `DOMParser` 解析 editorHtml,找到对应 `data-ref-id` 的 @mention span,更新 textContent(提示词栏里的 `@图片3` 自动变 `@图片2`) + - 缩略图区和提示词栏视觉同步刷新 + +#### 测试覆盖 +- **Vitest 单元测试 11 个**(test/unit/removeReferenceRelabeling.test.ts):图片三场景、视频/音频独立编号、空 editorHtml、无 @mention、传入无效 id、部分 @、连续快速删除等边界 +- **Playwright E2E 3 个**(test/e2e/bug2-rename.spec.ts):真实浏览器验证上传 3 张图 → 删中间 → 再上传,编号不冲突 + +#### 文档整理 +3. **AirDrama 根目录归档**:8 个过期 MD 文档移至 `archive/`(_settle_payment 双重结算/v0.15.1 部署/公告HTML/迁移到火山/全平台账务审计/火山耗时分析/图片上传blob/迭代需求_20260320) +4. **video-shuoshan/docs 归档**:6 个过期文档移至 `docs/archive/`(celery 轮询修复/design-review/PRD/test-report/两版旧 API 文档) +5. **新增 1080P Plan**:`AirDrama/1080P分辨率支持开发计划.md`,对照官方 API 文档完成 3 轮审查修正(21:9 像素值错误、_settle_payment 遗漏、VideoDetailModal 重新编辑、regenerate、API 响应 6 处、serializer 命名、GenerationRecord.resolution 字段已存在等),标注 5 项已知计费缺陷 + +### 变更文件 +- `backend/utils/airdrama_client.py` — ERROR_MESSAGES 加 PolicyViolation 映射 +- `web/src/store/inputBar.ts` — removeReference 重写(即梦逻辑 + editorHtml 同步) +- `web/test/unit/removeReferenceRelabeling.test.ts` — 11 个单元测试(新增) +- `web/test/e2e/bug2-rename.spec.ts` — 3 个 E2E 测试(新增) +- `AirDrama/1080P分辨率支持开发计划.md` — 1080P 开发 Plan(新增) +- `AirDrama/版本管理.md` — 添加 v0.18.3 记录 +- `AirDrama/项目总览与待办.md` — 完成项 + 1080P P0 待办 +- 16 个 MD 文档归档到两个 archive 目录 + +### 触发原因 +- 用户反馈:漫威素材生成失败时显示英文错误,不友好 +- 用户反馈:删除中间图片后再上传会出现重复编号(参考即梦交互) +- 火山 2026-04-16 1080P 上线,需提前规划开发 + +--- + +## 2026-04-13 — v0.18.2: 资产页修复 + 重新编辑素材泄漏 + 音频校验 + +**状态**: ✅ 已完成 | **验收**: 待测试 + +### 变更内容 + +#### 前端 +1. **资产页素材库引用不可查看** — Admin/Team 资产页的 `assetVideoToTask` 直接用了 `asset://` 协议 URL 作为 `previewUrl`,浏览器无法加载。改为检测 `asset://` 后使用 `thumb_url`(真实 TOS 缩略图地址),并标记 `isAssetRef`。同步修复 `BackendTask` 和 `AssetVideo` 类型定义补 `thumb_url` 字段 +2. **重新编辑素材泄漏** — `reEdit()` 把素材库引用混入 `references` 数组(注释写已过滤但实际没有),用户删除 @标签后旧素材仍通过 `filesToUpload` 路径发出。修复:`reEdit/regenerate` 加 `.filter(!isAssetRef)`;`PromptInput.extractText` 每次 DOM 变化时实时同步 `assetMentions` store +3. **音频不能作为唯一参考素材** — Seedance API 不支持"纯音频"和"文本+音频"。`canSubmit()` 去掉 `!hasText` 条件,同时检查 `references` 和 `assetMentions` 中的图片/视频;Toolbar 点击禁用按钮弹 toast 提示原因 +4. **素材库引用缩略图烂图** — `pollStatus` 跨项目素材保护 +5. **音频 ♫ 符号溢出** — 改用 CSS `::before` 渲染,不再污染 prompt 文本 + +### 变更文件 +- `web/src/pages/AdminAssetsPage.tsx` — isAssetUrl + thumb_url 处理 +- `web/src/pages/TeamAssetsPage.tsx` — 同上 +- `web/src/types/index.ts` — BackendTask/AssetVideo 补 thumb_url +- `web/src/store/generation.ts` — reEdit/regenerate 过滤 isAssetRef +- `web/src/components/PromptInput.tsx` — extractText 同步 assetMentions +- `web/src/store/inputBar.ts` — canSubmit 音频校验增强 +- `web/src/components/Toolbar.tsx` — 音频受限 toast 提示 + +--- + ## 2026-03-19 — v0.9.7: 登录风控第二期 — IP归属地解析 + 异常检测 + 飞书告警 + 自动封禁 **状态**: ✅ 已完成 | **验收**: ✅ 通过(本地验证,IP138 在线 API 需部署至阿里云后验证) diff --git a/docs/design-review.md b/docs/design-review.md deleted file mode 100644 index 259e0b0..0000000 --- a/docs/design-review.md +++ /dev/null @@ -1,134 +0,0 @@ -# 设计评审报告 - -## 评审结论: APPROVED - -**评审版本**: PRD v3.0 — Phase 3 (计量单位变更 + 管理后台重做 + 用户个人中心) -**评审日期**: 2026-03-12 -**评审范围**: Phase 3 新增/修改的原型页面(6 个新文件 + 1 个更新) - ---- - -## 功能覆盖检查 - -### Phase 3 P0 核心功能 - -| PRD 功能点 | 是否实现 | 备注 | -|-----------|---------|------| -| 管理后台布局 — 左侧 Sidebar 240px + 4 导航项 | ✅ | 所有 4 个管理页面共享一致的 Sidebar,active 高亮正确 | -| 管理后台路由 — dashboard/users/records/settings | ✅ | 4 个独立页面,导航链接互通 | -| 用户个人中心页面 `/profile` | ✅ | 消费概览 + 消费趋势 + 消费记录 + 配额警告 | -| 消费概览卡片 — 环形进度条 + 日/月配额 | ✅ | SVG 环形图 345s/600s,日额度 82.0%,月额度 39.1% | - -**P0 覆盖率: 4/4 (100%)** - -### Phase 3 P1 重要功能 - -| PRD 功能点 | 是否实现 | 备注 | -|-----------|---------|------| -| 仪表盘 — 核心指标卡片 (4 个) | ✅ | 总用户数 1,234 / 今日新增 +23 / 今日消费 4,560s / 本月消费 89,010s,含环比变化箭头 | -| 仪表盘 — 消费趋势折线图 | ✅ | SVG 折线图 + 面积填充,30 天数据,tooltip 显示 "3/28 188s" | -| 仪表盘 — 用户消费排行柱状图 | ✅ | Top 10 水平柱状图,数据递减 2,340s → 350s,前 3 名高亮 | -| 仪表盘 — 时间范围选择器 | ✅ | 今日/近7天/近30天/自定义,按钮可交互切换 | -| 仪表盘 — 图表 Mock 数据 | ✅ | 30 天数据有自然波动和上升趋势,排行榜数据合理 | -| 用户管理 — 用户列表表格 (分页) | ✅ | 9 列数据 + 7 条记录,分页 "共 56 条,第 1/3 页" | -| 用户管理 — 搜索和筛选 | ✅ | 关键字搜索 + 状态下拉 (全部/已启用/已禁用) + 刷新按钮 | -| 用户管理 — 配额编辑模态框 | ✅ | 点击"编辑配额"弹出 Modal,含日/月限额输入框 + 取消/保存按钮 | -| 用户管理 — 用户状态管理 | ✅ | 启用用户显示"禁用"(红色),禁用用户显示"启用"(绿色) | -| 用户管理 — 用户详情抽屉 | ✅ | 点击用户名打开 420px 右侧抽屉,含完整用户信息 + 近期 3 条消费记录 | -| 消费记录 — 消费明细表格 | ✅ | 6 列 (时间/用户名/消费秒数/视频描述/生成模式/状态),10 条记录,分页 "共 1,234 条,第 1/62 页" | -| 消费记录 — 时间范围筛选 | ✅ | 日期选择器 2026-03-01 ~ 2026-03-12 + 查询按钮 | -| 消费记录 — 用户筛选 | ✅ | "搜索用户名..." 搜索框 | -| 消费记录 — 导出 CSV | ✅ | 顶栏"导出 CSV"按钮 + 下载图标,主题色边框 | -| 系统设置 — 全局默认配额 | ✅ | 日限额 600s / 月限额 6000s 数字输入框 + 提示文字 + 保存按钮 | -| 系统设置 — 系统公告管理 | ✅ | 开关切换 (ON 状态) + 文本域含示例公告 + 保存按钮 + Toast 反馈 | -| 个人中心 — 消费记录列表 | ✅ | 6 条记录 (时间/秒数/prompt/模式/状态) + "加载更多"按钮 | -| 个人中心 — 消费趋势迷你图 | ✅ | Sparkline 折线图 7 天数据 (3/6-3/12),近7天/近30天切换按钮 | -| 个人中心 — 配额提示 | ✅ | 黄色警告横幅 "今日额度已消费 82%,请合理安排使用" + 日额度卡片 warning 样式 | - -**P1 覆盖率: 19/19 (100%)** - -### Phase 3 P2 锦上添花 - -| PRD 功能点 | 是否实现 | 备注 | -|-----------|---------|------| -| 页面切换过渡动画 | ✅ | fadeUp 入场动画 + 延迟序列 | -| 数据加载骨架屏 | ❌ | 未实现 (P2,不影响评审) | -| Sidebar 折叠模式 | ❌ | 未实现 (P2,不影响评审) | - -**P2 覆盖率: 1/3 (33%)** - -### 导航页更新 - -| PRD 功能点 | 是否实现 | 备注 | -|-----------|---------|------| -| index.html 更新 — Phase 3 导航卡片 | ✅ | 3 个分区:Phase 1 核心功能 + Phase 3 管理后台 (4 卡片) + Phase 3 用户端 (个人中心) | - ---- - -## 后台管理系统专项检查 - -| 检查项 | 结果 | 说明 | -|--------|------|------| -| 按功能模块拆分多个页面 + 侧边导航 | ✅ | 4 个独立页面 + 240px Sidebar 导航,active 状态正确 | -| 仪表盘图表有真实 Mock 数据 | ✅ | 折线图 30 天波动数据 + 排行榜 10 用户递减数据 + tooltip | -| 独立的用户管理页面 | ✅ | 完整表格 + 搜索/筛选 + 编辑配额模态框 + 用户详情抽屉 | -| 数据表格有搜索、分页、操作列 | ✅ | 搜索框 + 状态筛选 + 分页控件 + 编辑/禁用操作按钮 | - -**专项检查: 4/4 全部通过** - ---- - -## 素材使用质量 - -| 检查项 | 结果 | 问题描述 | -|--------|------|---------| -| 图片方向 | N/A | 原型为纯 HTML/CSS/SVG,无外部图片素材 | -| 精灵图集裁切 | N/A | 不涉及精灵图 | -| 尺寸比例 | ✅ | SVG 图表自适应宽度,卡片网格响应式 | -| 真实素材引用 | ✅ | 使用 SVG 内联图标(非 emoji 占位符) | -| 素材加载 | ✅ | 所有页面资源正常加载,无 broken image | -| 视觉层次 | ✅ | Sidebar → Content → Modal/Drawer 层叠正确 | - ---- - -## 设计质量 - -- **视觉一致性**: 5/5 — 所有 6 个 Phase 3 页面共享统一的深色主题 (Linear/Vercel 风格),CSS 变量一致 (#0a0a0f, #111118, #16161e, #2a2a38, #00b8e6),字体统一 (Noto Sans SC + Space Grotesk + JetBrains Mono) -- **交互合理性**: 5/5 — Drawer/Modal/Toggle/Toast 交互完整,时间选择器可切换,分页/搜索/筛选 UI 齐全 -- **响应式设计**: 4/5 — 仪表盘卡片使用 grid-cols-4 max-lg:grid-cols-2 响应式,个人中心 max-width 900px 居中。Sidebar 无折叠模式 (P2) -- **素材使用正确性**: 5/5 — 纯 SVG 图表和图标,无外部依赖,渲染准确 - -**综合评分: 4.8/5** - ---- - -## Playwright 验证截图 - -| 页面 | 截图文件 | 验证结果 | -|------|---------|---------| -| 仪表盘 | prototype-admin-dashboard.png | ✅ 4 统计卡片 + 折线图 + 排行榜 + 时间选择器 | -| 用户管理 | prototype-admin-users.png | ✅ 搜索/筛选栏 + 7 行用户表格 + 分页 | -| 用户详情抽屉 | prototype-admin-users-drawer.png | ✅ 右侧 420px 抽屉 + 用户信息 + 近期消费 | -| 消费记录 | prototype-admin-records.png | ✅ 筛选栏 + 10 行记录表格 + 导出 CSV + 分页 | -| 系统设置 | prototype-admin-settings.png | ✅ 配额表单 + 公告管理 + Toggle 开关 | -| 个人中心 | prototype-user-profile.png | ✅ 环形图 + 日/月额度 + Sparkline + 消费记录 + 配额警告 | -| 导航页 | prototype-index.png | ✅ Phase 1 + Phase 3 管理后台 + Phase 3 用户端分区 | - ---- - -## 评审总结 - -Phase 3 原型质量**极高**,完整覆盖了 PRD 中所有 P0 (4/4) 和 P1 (19/19) 功能需求。 - -**亮点**: -1. 管理后台 4 个子页面布局一致,Sidebar 导航交互正确 -2. 仪表盘图表使用真实感 Mock 数据(折线图有自然波动,排行榜递减合理) -3. 用户管理交互完整:表格 + 搜索 + 筛选 + 编辑模态框 + 详情抽屉 -4. 个人中心环形进度条 + Sparkline 趋势图 + 配额警告横幅,信息层次清晰 -5. 整体深色主题统一,Linear/Vercel 风格专业感强 -6. 所有页面计量单位正确使用「秒数」(非「次数」),与 Phase 3 需求一致 - -**可改进项** (不影响通过): -- P2: Sidebar 折叠模式未实现 -- P2: 骨架屏加载态未实现 -- 用户表格缺少头像列(可在开发阶段补充) diff --git a/docs/prd.md b/docs/prd.md deleted file mode 100644 index a598312..0000000 --- a/docs/prd.md +++ /dev/null @@ -1,1611 +0,0 @@ -# 产品需求文档 (PRD) - -## 1. 项目概述 - -- **项目名称**: Jimeng Clone — AI 视频生成平台 -- **一句话描述**: 1:1 还原即梦平台 (jimeng.jianying.com) 的 AI 视频生成页面,包含完整的用户认证体系、视频生成输入界面、后台管理系统和用户个人中心 -- **目标用户**: 前端开发学习者、AI 视频产品原型验证团队、平台管理员 -- **项目范围**: 视频生成输入栏(InputBar)及其交互逻辑 + Django 后端 API + 用户登录注册 + 后台管理(生成秒数统计与限制) + 用户个人中心(消费概览与记录) - -### 开发阶段划分 - -| 阶段 | 范围 | 状态 | -|------|------|------| -| **Phase 1** | 纯前端视频生成输入界面(InputBar、工具栏、上传、模式切换) | ✅ 已完成 | -| **Phase 2** | Django 后端 + 用户认证 + 前端路由 + 管理后台(基于调用次数) | ✅ 已完成 | -| **Phase 3** | 计量单位变更(次数→秒数)+ 管理后台重做(多页面 Sidebar)+ 用户个人中心 | 🔲 待开发 | - -> **当前迭代范围**: Phase 3。Phase 1 和 Phase 2 功能已完成。Phase 3 在 Phase 2 基础上进行重大重构和新增功能。文档中 `[Phase 3]` 标记用于区分本次迭代的新增/修改内容。 - -### Phase 3 核心变更摘要 - -1. **计量单位变更**: 所有「调用次数」改为「生成秒数」,用户每次生成视频消耗的是秒数(= 视频时长),不是次数 -2. **后台管理系统重做**: 从单页面改为多页面 + 左侧 Sidebar 导航(仪表盘/用户管理/消费记录/系统设置) -3. **新增用户个人中心** `/profile`: 消费概览 + 消费记录 + 趋势迷你图 -4. **图表库引入**: 使用 ECharts(echarts + echarts-for-react)展示趋势图、排行榜、环形进度条 -5. **设计升级**: 管理后台深色主题(Linear/Vercel 风格)、骨架屏加载、页面过渡动画 - -## 2. 功能需求 - -### 2.1 核心功能(P0) - -#### 已有前端功能 - -- [x] **深色主题全屏页面** — 背景色 `#0a0a0f`,页面无滚动,输入栏固定在底部居中,最大宽度 ~900px -- [x] **InputBar 容器** — 背景 `#16161e`,边框 `1px solid #2a2a38`,圆角 `20px`,内部分为上半区(上传+输入)和下半区(工具栏) -- [x] **提示词多行文本输入框** — 自适应高度(min 1行,max ~6行),支持换行输入,placeholder 根据当前模式动态切换 -- [x] **全能参考模式(默认模式)** — 左侧 [+ 参考内容] 上传按钮,支持上传 1-5 张图片/视频文件;上传后显示缩略图网格,每张标注「图片1」「图片2」等序号,每个缩略图右上角有 × 关闭按钮;上传区与文本输入框左右排列 -- [x] **首尾帧模式** — 上传区变为 [首帧缩略图] ↔ [+ 尾帧] 双框布局,中间双向箭头图标连接;首帧和尾帧各上传一张图片 -- [x] **模式切换下拉** — 工具栏中「全能参考/首尾帧」下拉菜单,点击切换模式,切换时联动:上传区 UI、比例选项、时长默认值 -- [x] **工具栏按钮行** — 一行横排按钮,透明背景,灰色文字 `#8a8a9a`,hover 时微亮背景 -- [x] **发送按钮** — 圆形按钮,内含上箭头图标;无内容时灰色不可点击,有内容(文字或上传文件)时变为蓝色 `#00b8e6` 可点击 - -#### [Phase 2] 用户认证系统 - -- [x] **用户注册页面** — 前端注册页 `/register`,包含用户名、邮箱、密码、确认密码字段,提交后调用后端注册 API -- [x] **用户登录页面** — 前端登录页 `/login`,包含用户名/邮箱、密码字段,登录成功后获取 JWT Token 并存储到 localStorage -- [x] **JWT 认证机制** — 后端签发 Access Token(有效期 2 小时)+ Refresh Token(有效期 7 天),前端请求自动附加 Authorization Bearer Token -- [x] **登录状态保持** — 前端全局 Auth 状态管理(Zustand),未登录用户自动跳转到登录页,已登录用户显示用户信息和退出按钮 -- [x] **Token 自动刷新** — Access Token 过期时自动使用 Refresh Token 刷新,刷新失败则跳转到登录页 - -#### [Phase 2] Django 后端服务 - -- [x] **Django 项目初始化** — 在 `backend/` 子目录创建 Django 项目,连接 MySQL 云数据库 -- [x] **RESTful API** — 使用 Django REST Framework (DRF) 提供用户认证、视频生成记录等 API -- [x] **CORS 配置** — 允许前端开发服务器(localhost:5173)跨域访问后端 API - -#### [Phase 3] 计量单位变更(次数 → 秒数) - -- [ ] **用户配额字段变更** — User 模型的 `daily_limit` / `monthly_limit`(次数)改为 `daily_seconds_limit` / `monthly_seconds_limit`(秒数),默认值分别为 600秒/日、6000秒/月 -- [ ] **消费记录增加秒数字段** — GenerationRecord 模型新增 `seconds_consumed` 字段(FloatField),记录每次生成消耗的秒数(= 视频时长 duration) -- [ ] **配额检查逻辑变更** — 后端配额检查从「今日调用次数 < daily_limit」改为「今日消费秒数 < daily_seconds_limit」 -- [ ] **前端展示变更** — 所有显示「剩余次数」的地方改为「剩余秒数」,UserInfoBar 组件配额显示改为秒数 - -#### [Phase 3] 后台管理系统重做 - -- [ ] **管理后台布局** — 采用左侧 Sidebar + 右侧内容区的经典管理后台布局,Sidebar 固定宽度 240px,支持折叠 -- [ ] **Sidebar 导航菜单** — 包含 4 个导航项:仪表盘、用户管理、消费记录、系统设置,当前项高亮,使用 react-router 嵌套路由 -- [ ] **管理后台路由** — `/admin` 为管理后台根路由(重定向到 `/admin/dashboard`),子路由:`/admin/dashboard`、`/admin/users`、`/admin/records`、`/admin/settings` - -#### [Phase 3] 用户个人中心 - -- [ ] **个人中心页面** — 新增 `/profile` 路由,已登录用户可访问,展示个人消费概览和历史记录 -- [ ] **消费概览卡片** — 显示已用秒数/总额度(环形进度条,使用 ECharts gauge)、今日已用/日限额、本月已用/月限额 - -### 2.2 重要功能(P1) - -#### 已有前端功能 - -- [x] **视频生成下拉按钮** — 蓝色文字 `#00b8e6` + 视频图标 + 下拉箭头,点击展开下拉菜单(菜单项仅 UI 展示,如"视频生成"/"图片生成"等) -- [x] **模型选择按钮** — 显示「Seedance 2.0」+ 钻石图标,点击展开模型选择下拉(仅 UI 展示,如 Seedance 2.0 / Seedance 2.0 Fast) -- [x] **比例选择按钮** — 全能参考模式下显示屏幕图标 + 当前比例值,点击弹出选项:`16:9` / `9:16` / `1:1` / `21:9` / `4:3` / `3:4`,默认 `21:9`;首尾帧模式下显示「自动匹配」不可选择 -- [x] **时长选择按钮** — 时钟图标 + 当前时长值,点击弹出选项:`5s` / `10s` / `15s`;全能参考模式默认 `15s`,首尾帧模式默认 `5s` -- [x] **@ 按钮** — 仅在全能参考模式下显示,点击插入 `@` 符号到文本输入框光标位置 -- [x] **文件上传交互** — 点击上传区触发文件选择器,accept 为 `image/*,video/*`;上传后生成本地预览缩略图;支持拖拽上传 -- [x] **上传数量限制** — 全能参考模式最多 5 张,超出时 toast 提示;首尾帧模式首帧/尾帧各 1 张 - -#### [Phase 2] 后台管理与生成接入 - -- [x] **Django Admin 集成** — 启用 Django Admin 面板(`/admin/`),管理员可查看和管理所有用户、视频生成记录 -- [x] **发送按钮接入后端** — 点击发送按钮时,调用后端 `/api/v1/video/generate` 接口(需登录),后端记录调用并检查配额 - -#### [Phase 3] 仪表盘页面(`/admin/dashboard`) - -- [ ] **核心指标卡片** — 4 个统计卡片:总用户数、今日新增用户、今日消费秒数、本月消费秒数。每个卡片显示数值 + 环比变化百分比 + 趋势箭头(↑绿色/↓红色) -- [ ] **消费趋势折线图** — 使用 ECharts 折线图展示近 30 天每日消费秒数趋势,支持 tooltip 悬浮显示具体数值,X轴为日期,Y轴为秒数 -- [ ] **用户消费排行柱状图** — 使用 ECharts 水平柱状图展示消费 Top 10 用户(按本月消费秒数降序),柱状图标签显示用户名和秒数 -- [ ] **时间范围选择器** — 支持「今日 / 近7天 / 近30天 / 自定义时间范围」切换,图表数据联动更新 -- [ ] **图表 Mock 数据** — 开发阶段使用 30 天的真实结构 Mock 数据(随机波动、周末低谷),确保图表有真实感 - -#### [Phase 3] 用户管理页面(`/admin/users`) - -- [ ] **用户列表表格** — 分页展示所有用户(每页 20 条),列:头像、用户名、邮箱、注册时间、状态(启用/禁用)、日限额(秒)、月限额(秒)、今日消费(秒)、本月消费(秒)、操作 -- [ ] **搜索和筛选** — 支持按用户名/邮箱关键字搜索 + 按状态筛选(全部/启用/禁用) -- [ ] **配额编辑** — 每个用户行的操作列有「编辑配额」按钮,点击弹出模态框,可修改日限额秒数和月限额秒数 -- [ ] **用户状态管理** — 操作列有「启用/禁用」开关按钮,点击后调用 API 切换用户 `is_active` 状态 -- [ ] **用户详情抽屉** — 点击用户名展开右侧抽屉面板,显示用户详情 + 该用户近期消费记录列表 - -#### [Phase 3] 消费记录页面(`/admin/records`) - -- [ ] **消费明细表格** — 分页展示所有用户的消费记录,列:时间、用户名、消费秒数、视频描述(prompt 截断)、生成模式、状态 -- [ ] **时间范围筛选** — 日期选择器,支持选择起止日期筛选记录 -- [ ] **用户筛选** — 支持按用户名搜索筛选特定用户的消费记录 -- [ ] **导出功能** — 「导出 CSV」按钮,将当前筛选条件下的消费记录导出为 CSV 文件 - -#### [Phase 3] 系统设置页面(`/admin/settings`) - -- [ ] **全局默认配额设置** — 表单修改全局默认日限额秒数和月限额秒数(新注册用户自动获得此配额) -- [ ] **系统公告管理** — 公告文本编辑框 + 启用/禁用开关,启用后公告内容展示在用户端页面顶部 - -#### [Phase 3] 用户个人中心详细功能 - -- [ ] **消费记录列表** — 分页展示当前用户的消费记录,每条记录显示:时间、消费秒数、生成的视频描述(prompt)、生成模式、状态 -- [ ] **消费趋势迷你图** — 使用 ECharts Sparkline 样式展示近 7 天 / 近 30 天每日消费秒数趋势,可切换时间范围 -- [ ] **配额提示** — 当日额度消费超过 80% 时显示黄色警告提示,超过 100% 时显示红色禁用提示 - -### 2.3 锦上添花(P2) - -- [x] **下拉菜单动画** — 下拉展开/收起有 fade + slide 动画过渡 -- [x] **文本输入框自动聚焦** — 页面加载后自动 focus 到文本输入框 -- [x] **键盘快捷键** — `Ctrl/Cmd + Enter` 触发发送(等同点击发送按钮) -- [ ] **上传进度条** — 文件上传时缩略图上显示加载进度 -- [ ] **拖拽排序** — 全能参考模式下已上传的缩略图支持拖拽调整顺序 -- [x] **响应式适配** — 移动端窄屏下工具栏按钮文字隐藏只显示图标,输入栏宽度自适应 -- [ ] **Tooltip 提示** — 工具栏按钮 hover 显示功能说明 tooltip -- [ ] **[Phase 2] 忘记密码** — 邮箱验证码找回密码流程 -- [ ] **[Phase 2] 用户个人资料编辑** — 查看和修改个人信息(头像、昵称) -- [ ] **[Phase 3] 页面切换过渡动画** — 路由切换时使用 fade/slide 过渡动画,提升体验流畅度 -- [ ] **[Phase 3] 数据加载骨架屏** — 管理后台和个人中心的数据加载使用骨架屏(Skeleton)替代 loading spinner -- [ ] **[Phase 3] Sidebar 折叠模式** — 管理后台 Sidebar 支持折叠为图标模式,增大内容区宽度 - -## 3. 技术栈建议 - -### 3.1 现有技术栈(保留) - -| 层级 | 技术选型 | 说明 | -|------|---------|------| -| 前端框架 | React 18 + TypeScript | 函数组件 + Hooks | -| 构建工具 | Vite 5 | 极速 HMR,原生 ESM | -| UI 组件库 | @arco-design/web-react | 字节跳动设计系统,即梦同款 | -| 状态管理 | Zustand | 轻量、TypeScript 友好 | -| 样式方案 | CSS Modules + Arco Design Token | 深色主题定制 | -| 图标 | @arco-design/web-react/icon + 自定义 SVG | 工具栏图标 | -| 文件处理 | 浏览器原生 File API | 本地预览、缩略图生成 | - -### 3.2 [Phase 2] 已有前端依赖(保留) - -| 依赖 | 说明 | -|------|------| -| react-router-dom v7 | 前端路由(登录页、注册页、管理页) | -| axios | HTTP 请求库,支持拦截器实现 Token 自动附加和刷新 | - -### 3.3 [Phase 3] 新增前端依赖 - -| 依赖 | 说明 | -|------|------| -| echarts | 图表库核心,用于折线图、柱状图、环形图等数据可视化 | -| echarts-for-react | ECharts 的 React 封装组件,声明式使用图表 | - -> **组件优先级**: 如果 Arco Design 内置了对应组件(如 Table、Modal、Skeleton、DatePicker),优先使用 Arco 组件,ECharts 仅用于复杂图表。 - -### 3.4 [Phase 2] 后端技术栈(保留) - -| 层级 | 技术选型 | 说明 | -|------|---------|------| -| 后端框架 | Django 4.2+ (LTS) | Python Web 框架 | -| API 框架 | Django REST Framework (DRF) | RESTful API 开发 | -| 认证方案 | djangorestframework-simplejwt | JWT Token 签发与验证 | -| 数据库 | MySQL 8.0(阿里云 RDS) | 云数据库,已提供连接信息 | -| 数据库驱动 | mysqlclient | Django 官方推荐的 MySQL 驱动 | -| CORS | django-cors-headers | 跨域请求支持 | -| 后端管理 | Django Admin | 内置管理后台 | -| 部署 | Gunicorn + Nginx | 生产环境部署方案 | - -> **后端代码目录**: 所有后端代码放在项目根目录下的 `backend/` 子目录中。 - -### 3.5 数据库连接配置(不变) - -```python -# backend/config/settings.py -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': 'video_auto', - 'USER': 'ai_video', - 'PASSWORD': 'JogNQdtrd3WY8CBCAiYfYEGx', - 'HOST': 'rm-7xv1uaw910558p1788o.mysql.rds.aliyuncs.com', - 'PORT': '3306', - 'OPTIONS': { - 'charset': 'utf8mb4', - 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", - }, - } -} -``` - -## 4. 页面列表 - -### 4.1 [已有] 视频生成页 (`/`) - -**整体布局**: -``` -┌─────────────────────────────────────────────┐ -│ [Phase 3 修改] 顶部用户信息: │ -│ 用户名 | 剩余: 345s/600s(日) | [个人中心] [退出]│ -│ │ -│ 深色背景空白区域 │ -│ #0a0a0f │ -│ │ -│ ┌─────────────────────────────────────┐ │ -│ │ InputBar (底部固定) │ │ -│ │ max-width: 900px, 居中 │ │ -│ │ 背景: #16161e │ │ -│ │ 边框: #2a2a38, 圆角: 20px │ │ -│ │ │ │ -│ │ ┌──────┐ ┌──────────────────────┐ │ │ -│ │ │上传区 │ │ 提示词文本输入框 │ │ │ -│ │ │ │ │ │ │ │ -│ │ └──────┘ └──────────────────────┘ │ │ -│ │ │ │ -│ │ ─────────── 工具栏按钮行 ────────── │ │ -│ │ [视频生成▼][模型][模式▼][比例][时长] │ │ -│ │ [@] flex空白 [发送⬆] │ │ -│ └─────────────────────────────────────┘ │ -└─────────────────────────────────────────────┘ -``` - -- [Phase 3 修改] 顶部用户信息区的配额显示从「剩余 N 次」改为「剩余 N 秒」,增加「个人中心」链接 -- [Phase 2] 需要登录才能访问,未登录重定向到 `/login` - -**全能参考模式 — 上传区细节**: -``` -┌──────────┐ -│ + │ ← 初始状态: [+ 参考内容] 按钮 -│ 参考内容 │ 虚线边框,点击触发上传 -└──────────┘ - -┌───┐┌───┐┌──────┐ -│图1││图2││ + │ ← 已上传状态: 缩略图网格 + 添加按钮 -│ × ││ × ││ │ 每张有序号标签和关闭按钮 -└───┘└───┘└──────┘ -``` - -**首尾帧模式 — 上传区细节**: -``` -┌──────┐ ┌──────┐ -│ 首帧 │ ↔ │+ 尾帧 │ ← 两个独立上传框 -│ │ │ │ 中间双向箭头 -└──────┘ └──────┘ -``` - -**工具栏按钮排布**: -``` -全能参考模式: -[🎬 视频生成 ▼] [💎 Seedance 2.0] [✨ 全能参考 ▼] [🖥 21:9] [🕐 15s] [@] ——flex空白—— [⬆ 发送] - -首尾帧模式: -[🎬 视频生成 ▼] [💎 Seedance 2.0] [🔀 首尾帧 ▼] [自动匹配] [🕐 5s] ——flex空白—— [⬆ 发送] -``` - -### 4.2 [已有] 登录页 (`/login`) - -``` -┌─────────────────────────────────────────────┐ -│ │ -│ 深色背景 #0a0a0f │ -│ │ -│ ┌──────────────────────┐ │ -│ │ Jimeng Clone │ │ -│ │ │ │ -│ │ 用户名/邮箱: [____] │ │ -│ │ 密码: [____] │ │ -│ │ │ │ -│ │ [ 登录 ] │ │ -│ │ │ │ -│ │ 没有账号?去注册 → │ │ -│ └──────────────────────┘ │ -│ │ -└─────────────────────────────────────────────┘ -``` - -- 表单验证:用户名/邮箱必填,密码最少 6 位 -- 登录成功后跳转到 `/`(视频生成页) -- 风格与主应用一致:深色主题,卡片式表单 - -### 4.3 [已有] 注册页 (`/register`) - -``` -┌─────────────────────────────────────────────┐ -│ │ -│ 深色背景 #0a0a0f │ -│ │ -│ ┌──────────────────────┐ │ -│ │ 创建账号 │ │ -│ │ │ │ -│ │ 用户名: [____] │ │ -│ │ 邮箱: [____] │ │ -│ │ 密码: [____] │ │ -│ │ 确认密码: [____] │ │ -│ │ │ │ -│ │ [ 注册 ] │ │ -│ │ │ │ -│ │ 已有账号?去登录 → │ │ -│ └──────────────────────┘ │ -│ │ -└─────────────────────────────────────────────┘ -``` - -- 表单验证:用户名 3-20 位、邮箱格式校验、密码最少 6 位、两次密码一致 -- 注册成功后自动登录并跳转到 `/` - -### 4.4 [Phase 3] 管理后台布局(`/admin/*`) - -``` -┌──────────────────────────────────────────────────────────────┐ -│ Jimeng Admin [管理员名] [退出] │ -├────────────┬─────────────────────────────────────────────────┤ -│ │ │ -│ SIDEBAR │ CONTENT AREA │ -│ 240px │ (根据子路由渲染不同页面) │ -│ │ │ -│ ┌──────┐ │ │ -│ │ 📊 │ │ │ -│ │仪表盘 │ │ │ -│ ├──────┤ │ │ -│ │ 👥 │ │ │ -│ │用户 │ │ │ -│ │管理 │ │ │ -│ ├──────┤ │ │ -│ │ 📋 │ │ │ -│ │消费 │ │ │ -│ │记录 │ │ │ -│ ├──────┤ │ │ -│ │ ⚙️ │ │ │ -│ │系统 │ │ │ -│ │设置 │ │ │ -│ └──────┘ │ │ -│ │ │ -│ ─────── │ │ -│ [返回首页] │ │ -│ │ │ -├────────────┴─────────────────────────────────────────────────┤ -│ Jimeng Clone Admin v3.0 │ -└──────────────────────────────────────────────────────────────┘ -``` - -**设计规范(管理后台专用)**: -- 整体风格参考 Linear / Vercel Dashboard,深色主题 -- 背景色 `#0a0a0f`,Sidebar 背景 `#111118`,内容区背景 `#0a0a0f` -- Sidebar 当前项背景 `rgba(255, 255, 255, 0.08)`,文字 `#ffffff` -- 非当前项文字 `#8a8a9a`,hover 背景 `rgba(255, 255, 255, 0.04)` -- 卡片背景 `#16161e`,边框 `1px solid #2a2a38`,圆角 `12px` -- 数据加载时显示 Arco Skeleton 骨架屏 - -### 4.5 [Phase 3] 仪表盘页面(`/admin/dashboard`) - -``` -┌─────────────────────────────────────────────────────────────┐ -│ │ -│ 仪表盘 [今日] [近7天] [近30天] [自定义]│ -│ │ -│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ -│ │ 总用户数 │ │今日新增 │ │今日消费 │ │本月消费 │ │ -│ │ 1,234 │ │ +23 │ │ 4,560s │ │ 89,010s │ │ -│ │ ↑12% │ │ ↑15% │ │ ↓5% │ │ ↑8% │ │ -│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ -│ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ 消费趋势 (ECharts 折线图) │ │ -│ │ │ │ -│ │ Y轴: 秒数 ___/\___ │ │ -│ │ / \___/\ │ │ -│ │ ___/\___/ \___ │ │ -│ │ │ │ -│ │ X轴: 日期 (3/1 3/5 3/10 3/15 3/20 3/25 3/30) │ │ -│ └──────────────────────────────────────────────────────┘ │ -│ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ 用户消费排行 Top 10 (ECharts 水平柱状图) │ │ -│ │ │ │ -│ │ user_a ████████████████████████ 2,340s │ │ -│ │ user_b ██████████████████ 1,890s │ │ -│ │ user_c ████████████████ 1,560s │ │ -│ │ ... │ │ -│ └──────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────┘ -``` - -- 仅 `is_staff=True` 的用户可访问 -- 统计卡片使用 Arco Card 组件 + 自定义样式 -- 折线图使用 ECharts `line` 类型,开启 `tooltip`、`dataZoom` 交互 -- 柱状图使用 ECharts `bar` 类型,水平方向,标签显示用户名和秒数 -- 时间范围选择器使用 Arco DatePicker.RangePicker -- 数据来源:`GET /api/v1/admin/stats` - -### 4.6 [Phase 3] 用户管理页面(`/admin/users`) - -``` -┌─────────────────────────────────────────────────────────────┐ -│ │ -│ 用户管理 │ -│ │ -│ [🔍 搜索用户名/邮箱___________] [状态: 全部 ▼] [刷新] │ -│ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ 用户名 │ 邮箱 │ 注册时间 │ 状态 │ 日限额│ │ -│ │ │ │ │ │ (秒) │ │ -│ │ 月限额 │ 今日消费(秒) │ 本月消费(秒)│ 操作 │ │ -│ ├──────────┼──────────────┼──────────┼──────┼──────┤ │ -│ │ user_a │ a@test.com │ 3/1 │ ✅ │ 600 │ │ -│ │ 6000 │ 123 │ 2345 │[编辑][禁用] │ │ -│ ├──────────┼──────────────┼──────────┼──────┼──────┤ │ -│ │ user_b │ b@test.com │ 3/5 │ ❌ │ 300 │ │ -│ │ 3000 │ 0 │ 0 │[编辑][启用] │ │ -│ └──────────┴──────────────┴──────────┴──────┴──────┘ │ -│ │ -│ 共 56 条 [< 1 2 3 >] │ -│ │ -└─────────────────────────────────────────────────────────────┘ -``` - -- 使用 Arco Table 组件(分页、排序) -- 搜索使用 Arco Input.Search -- 状态筛选使用 Arco Select -- 编辑配额使用 Arco Modal 弹窗 -- 用户详情使用 Arco Drawer 右侧抽屉 -- 数据来源:`GET /api/v1/admin/users` - -### 4.7 [Phase 3] 消费记录页面(`/admin/records`) - -``` -┌─────────────────────────────────────────────────────────────┐ -│ │ -│ 消费记录 [导出 CSV] │ -│ │ -│ [用户名搜索____] [时间: 2026-03-01 ~ 2026-03-12] [查询] │ -│ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ 时间 │ 用户名 │ 消费秒数│ 视频描述 │ │ -│ │ │ │ │ (prompt截断) │ │ -│ │ 模式 │ 状态 │ │ -│ ├───────────────────┼────────┼────────┼─────────────┤ │ -│ │ 3/12 14:30:00 │ user_a │ 15s │ 一只猫在... │ │ -│ │ 全能参考 │ 已完成 │ │ -│ ├───────────────────┼────────┼────────┼─────────────┤ │ -│ │ 3/12 14:25:00 │ user_b │ 5s │ 日落海边... │ │ -│ │ 首尾帧 │ 生成中 │ │ -│ └──────────────────────────────────────────────────────┘ │ -│ │ -│ 共 1,234 条 [< 1 2 3 ... 62 >] │ -│ │ -└─────────────────────────────────────────────────────────────┘ -``` - -- 使用 Arco Table 组件(分页) -- 时间范围筛选使用 Arco DatePicker.RangePicker -- 导出 CSV:前端调用 API 获取全部数据并生成 CSV 文件下载 -- 数据来源:`GET /api/v1/admin/records` - -### 4.8 [Phase 3] 系统设置页面(`/admin/settings`) - -``` -┌─────────────────────────────────────────────────────────────┐ -│ │ -│ 系统设置 │ -│ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ 全局默认配额 │ │ -│ │ │ │ -│ │ 默认每日限额 (秒): [____600____] │ │ -│ │ 默认每月限额 (秒): [____6000___] │ │ -│ │ │ │ -│ │ [保存配额设置] │ │ -│ └──────────────────────────────────────────────────────┘ │ -│ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ 系统公告 [启用公告: ON] │ │ -│ │ │ │ -│ │ ┌──────────────────────────────────────────────┐ │ │ -│ │ │ │ │ │ -│ │ │ 公告内容 (支持纯文本) │ │ │ -│ │ │ │ │ │ -│ │ └──────────────────────────────────────────────┘ │ │ -│ │ │ │ -│ │ [保存公告] │ │ -│ └──────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────┘ -``` - -- 使用 Arco Form、InputNumber、Switch、Input.TextArea 组件 -- 保存后 showToast 提示「设置已保存」 -- 数据来源:`GET/PUT /api/v1/admin/settings` - -### 4.9 [Phase 3] 用户个人中心(`/profile`) - -``` -┌─────────────────────────────────────────────────────────────┐ -│ │ -│ [← 返回首页] 个人中心 [用户名] [退出] │ -│ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ 消费概览 │ │ -│ │ │ │ -│ │ ┌────────┐ ┌──────────────┐ ┌──────────────┐ │ │ -│ │ │ (环形图)│ │ 今日额度 │ │ 本月额度 │ │ │ -│ │ │ │ │ │ │ │ │ │ -│ │ │ 已用 │ │ 已用: 123s │ │ 已用: 2345s │ │ │ -│ │ │ 345s │ │ 限额: 600s │ │ 限额: 6000s │ │ │ -│ │ │ /600s │ │ ████████░░░ │ │ ████░░░░░░░ │ │ │ -│ │ │ │ │ 20.5% │ │ 39.1% │ │ │ -│ │ └────────┘ └──────────────┘ └──────────────┘ │ │ -│ └──────────────────────────────────────────────────────┘ │ -│ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ 消费趋势 [近7天] [近30天] │ │ -│ │ ___/\___/\___ (Sparkline 迷你折线图) │ │ -│ └──────────────────────────────────────────────────────┘ │ -│ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ 消费记录 │ │ -│ │ │ │ -│ │ 3/12 14:30 │ 15s │ 一只猫在花园... │ 全能参考 │ 完成│ │ -│ │ 3/12 14:25 │ 5s │ 日落海边散步... │ 首尾帧 │ 完成│ │ -│ │ 3/12 13:00 │ 10s │ 城市夜景延时... │ 全能参考 │ 失败│ │ -│ │ ... │ │ -│ │ │ │ -│ │ [加载更多] │ │ -│ └──────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────┘ -``` - -- 环形进度条使用 ECharts `gauge` 类型(半环或全环) -- 进度条使用 Arco Progress 组件 -- 消费记录列表使用 Arco List 或 Table 组件,支持「加载更多」分页 -- Sparkline 迷你图使用 ECharts `line` 类型(无坐标轴,仅曲线) -- 数据来源:`GET /api/v1/profile/overview` + `GET /api/v1/profile/records` -- 深色主题风格与主应用一致 - -## 5. API 设计 - -### 5.1 [已有] 视频生成(Phase 3 修改配额返回字段) - -``` -POST /api/v1/video/generate -Content-Type: multipart/form-data -Authorization: Bearer - -Request: -{ - "prompt": string, - "mode": "universal" | "keyframe", - "model": "seedance_2.0" | "seedance_2.0_fast", - "aspect_ratio": "16:9" | "9:16" | "1:1" | "21:9" | "4:3" | "3:4" | "auto", - "duration": 5 | 10 | 15, - "references": File[], - "first_frame": File | null, - "last_frame": File | null -} - -Response: 202 Accepted -{ - "task_id": "uuid", - "status": "queued", - "estimated_time": 120, - "seconds_consumed": 15, ← [Phase 3] 本次消耗秒数 - "remaining_seconds_today": 345 ← [Phase 3] 今日剩余秒数 -} - -Error Response: 429 Too Many Requests -{ - "error": "quota_exceeded", - "message": "您今日的生成额度已用完", ← [Phase 3] 改为秒数描述 - "daily_seconds_limit": 600, - "daily_seconds_used": 600, - "reset_at": "2026-03-13T00:00:00+08:00" -} -``` - -### 5.2 [已有] 文件上传(不变) - -``` -POST /api/v1/upload -Content-Type: multipart/form-data -Authorization: Bearer - -Request: -{ - "file": File, - "type": "image" | "video" -} - -Response: 200 OK -{ - "file_id": "uuid", - "url": "https://cdn.example.com/...", - "thumbnail_url": "https://cdn.example.com/.../thumb.jpg", - "width": 1920, - "height": 1080, - "duration": 10.5 -} -``` - -### 5.3 [已有] 用户注册(不变) - -``` -POST /api/v1/auth/register -Content-Type: application/json - -Request: -{ - "username": "string (3-20字符)", - "email": "string (合法邮箱)", - "password": "string (最少6位)" -} - -Response: 201 Created -{ - "user": { - "id": 1, - "username": "johndoe", - "email": "john@example.com" - }, - "tokens": { - "access": "eyJ...", - "refresh": "eyJ..." - } -} - -Error Response: 400 Bad Request -{ - "username": ["该用户名已被注册"], - "email": ["该邮箱已被注册"] -} -``` - -### 5.4 [已有] 用户登录(不变) - -``` -POST /api/v1/auth/login -Content-Type: application/json - -Request: -{ - "username": "string (用户名或邮箱)", - "password": "string" -} - -Response: 200 OK -{ - "user": { - "id": 1, - "username": "johndoe", - "email": "john@example.com", - "is_staff": false - }, - "tokens": { - "access": "eyJ...", - "refresh": "eyJ..." - } -} - -Error Response: 401 Unauthorized -{ - "error": "invalid_credentials", - "message": "用户名或密码错误" -} -``` - -### 5.5 [已有] Token 刷新(不变) - -``` -POST /api/v1/auth/token/refresh -Content-Type: application/json - -Request: -{ - "refresh": "eyJ..." -} - -Response: 200 OK -{ - "access": "eyJ..." -} -``` - -### 5.6 [已有] 获取当前用户信息(Phase 3 修改配额字段) - -``` -GET /api/v1/auth/me -Authorization: Bearer - -Response: 200 OK -{ - "id": 1, - "username": "johndoe", - "email": "john@example.com", - "is_staff": false, - "quota": { - "daily_seconds_limit": 600, ← [Phase 3] 改为秒数 - "daily_seconds_used": 123, - "monthly_seconds_limit": 6000, - "monthly_seconds_used": 2345 - } -} -``` - -### 5.7 [Phase 3] 管理后台 — 仪表盘统计 - -``` -GET /api/v1/admin/stats?period=30d -Authorization: Bearer -(requires is_staff=True) - -Query Parameters: - period: "today" | "7d" | "30d" | "custom" - start_date: "2026-03-01" (当 period=custom 时必填) - end_date: "2026-03-12" (当 period=custom 时必填) - -Response: 200 OK -{ - "total_users": 1234, - "new_users_today": 23, - "seconds_consumed_today": 4560, - "seconds_consumed_this_month": 89010, - "today_change_percent": -5.0, - "month_change_percent": 8.0, - "daily_trend": [ - {"date": "2026-02-11", "seconds": 3200}, - {"date": "2026-02-12", "seconds": 4100}, - ... - ], - "top_users": [ - { - "user_id": 1, - "username": "user_a", - "seconds_consumed": 2340 - }, - ... - ] -} -``` - -### 5.8 [Phase 3] 管理后台 — 用户列表 - -``` -GET /api/v1/admin/users?page=1&page_size=20&search=&status=&sort_by=created_at&order=desc -Authorization: Bearer -(requires is_staff=True) - -Query Parameters: - page: int (默认 1) - page_size: int (默认 20,最大 100) - search: string (按用户名或邮箱模糊搜索) - status: "active" | "disabled" | "" (空表示全部) - sort_by: "created_at" | "seconds_today" | "seconds_month" (排序字段) - order: "asc" | "desc" - -Response: 200 OK -{ - "total": 56, - "page": 1, - "page_size": 20, - "results": [ - { - "id": 1, - "username": "user_a", - "email": "a@test.com", - "is_active": true, - "date_joined": "2026-03-01T10:00:00+08:00", - "daily_seconds_limit": 600, - "monthly_seconds_limit": 6000, - "seconds_today": 123, - "seconds_this_month": 2345 - }, - ... - ] -} -``` - -### 5.9 [Phase 3] 管理后台 — 用户详情 + 消费记录 - -``` -GET /api/v1/admin/users/:id -Authorization: Bearer -(requires is_staff=True) - -Response: 200 OK -{ - "id": 1, - "username": "user_a", - "email": "a@test.com", - "is_active": true, - "is_staff": false, - "date_joined": "2026-03-01T10:00:00+08:00", - "daily_seconds_limit": 600, - "monthly_seconds_limit": 6000, - "seconds_today": 123, - "seconds_this_month": 2345, - "seconds_total": 5678, - "recent_records": [ - { - "id": 101, - "created_at": "2026-03-12T14:30:00+08:00", - "seconds_consumed": 15, - "prompt": "一只猫在花园里追蝴蝶", - "mode": "universal", - "model": "seedance_2.0", - "status": "completed" - }, - ... - ] -} -``` - -### 5.10 [Phase 3] 管理后台 — 修改用户配额 - -``` -PUT /api/v1/admin/users/:id/quota -Authorization: Bearer -(requires is_staff=True) -Content-Type: application/json - -Request: -{ - "daily_seconds_limit": 900, - "monthly_seconds_limit": 9000 -} - -Response: 200 OK -{ - "user_id": 1, - "username": "user_a", - "daily_seconds_limit": 900, - "monthly_seconds_limit": 9000, - "updated_at": "2026-03-12T14:30:00+08:00" -} -``` - -### 5.11 [Phase 3] 管理后台 — 启用/禁用用户 - -``` -PATCH /api/v1/admin/users/:id/status -Authorization: Bearer -(requires is_staff=True) -Content-Type: application/json - -Request: -{ - "is_active": false -} - -Response: 200 OK -{ - "user_id": 1, - "username": "user_a", - "is_active": false, - "updated_at": "2026-03-12T14:30:00+08:00" -} -``` - -### 5.12 [Phase 3] 管理后台 — 消费记录列表 - -``` -GET /api/v1/admin/records?page=1&page_size=20&search=&start_date=&end_date= -Authorization: Bearer -(requires is_staff=True) - -Query Parameters: - page: int (默认 1) - page_size: int (默认 20,最大 100) - search: string (按用户名搜索) - start_date: "2026-03-01" (起始日期) - end_date: "2026-03-12" (结束日期) - -Response: 200 OK -{ - "total": 1234, - "page": 1, - "page_size": 20, - "results": [ - { - "id": 101, - "created_at": "2026-03-12T14:30:00+08:00", - "user_id": 1, - "username": "user_a", - "seconds_consumed": 15, - "prompt": "一只猫在花园里追蝴蝶", - "mode": "universal", - "model": "seedance_2.0", - "aspect_ratio": "16:9", - "status": "completed" - }, - ... - ] -} -``` - -### 5.13 [Phase 3] 管理后台 — 系统设置 - -``` -GET /api/v1/admin/settings -Authorization: Bearer -(requires is_staff=True) - -Response: 200 OK -{ - "default_daily_seconds_limit": 600, - "default_monthly_seconds_limit": 6000, - "announcement": "系统将于今晚 22:00 进行维护", - "announcement_enabled": true -} - -PUT /api/v1/admin/settings -Authorization: Bearer -(requires is_staff=True) -Content-Type: application/json - -Request: -{ - "default_daily_seconds_limit": 600, - "default_monthly_seconds_limit": 6000, - "announcement": "系统将于今晚 22:00 进行维护", - "announcement_enabled": true -} - -Response: 200 OK -{ - "default_daily_seconds_limit": 600, - "default_monthly_seconds_limit": 6000, - "announcement": "系统将于今晚 22:00 进行维护", - "announcement_enabled": true, - "updated_at": "2026-03-12T14:30:00+08:00" -} -``` - -### 5.14 [Phase 3] 用户个人中心 — 消费概览 - -``` -GET /api/v1/profile/overview?period=7d -Authorization: Bearer - -Query Parameters: - period: "7d" | "30d" (趋势数据的时间范围) - -Response: 200 OK -{ - "daily_seconds_limit": 600, - "daily_seconds_used": 123, - "monthly_seconds_limit": 6000, - "monthly_seconds_used": 2345, - "total_seconds_used": 5678, - "daily_trend": [ - {"date": "2026-03-06", "seconds": 45}, - {"date": "2026-03-07", "seconds": 120}, - {"date": "2026-03-08", "seconds": 0}, - {"date": "2026-03-09", "seconds": 88}, - {"date": "2026-03-10", "seconds": 200}, - {"date": "2026-03-11", "seconds": 156}, - {"date": "2026-03-12", "seconds": 123} - ] -} -``` - -### 5.15 [Phase 3] 用户个人中心 — 消费记录 - -``` -GET /api/v1/profile/records?page=1&page_size=20 -Authorization: Bearer - -Query Parameters: - page: int (默认 1) - page_size: int (默认 20) - -Response: 200 OK -{ - "total": 45, - "page": 1, - "page_size": 20, - "results": [ - { - "id": 101, - "created_at": "2026-03-12T14:30:00+08:00", - "seconds_consumed": 15, - "prompt": "一只猫在花园里追蝴蝶", - "mode": "universal", - "model": "seedance_2.0", - "aspect_ratio": "16:9", - "status": "completed" - }, - ... - ] -} -``` - -## 6. 数据模型 - -### 6.1 已有前端 Store 类型(保留) - -```typescript -// 创作模式 -type CreationMode = 'universal' | 'keyframe'; - -// 模型选项 -type ModelOption = 'seedance_2.0' | 'seedance_2.0_fast'; - -// 宽高比 -type AspectRatio = '16:9' | '9:16' | '1:1' | '21:9' | '4:3' | '3:4'; - -// 时长 -type Duration = 5 | 10 | 15; - -// 上传文件 -interface UploadedFile { - id: string; - file: File; - type: 'image' | 'video'; - previewUrl: string; - label: string; -} - -// 输入栏状态 Store -interface InputBarStore { - mode: CreationMode; - setMode: (mode: CreationMode) => void; - model: ModelOption; - setModel: (model: ModelOption) => void; - aspectRatio: AspectRatio; - setAspectRatio: (ratio: AspectRatio) => void; - duration: Duration; - setDuration: (duration: Duration) => void; - prompt: string; - setPrompt: (prompt: string) => void; - references: UploadedFile[]; - addReference: (file: File) => void; - removeReference: (id: string) => void; - clearReferences: () => void; - firstFrame: UploadedFile | null; - lastFrame: UploadedFile | null; - setFirstFrame: (file: File | null) => void; - setLastFrame: (file: File | null) => void; - canSubmit: () => boolean; - switchMode: (mode: CreationMode) => void; - submit: () => void; - reset: () => void; -} -``` - -### 6.2 已有下拉菜单配置(保留) - -```typescript -interface DropdownOption { - label: string; - value: string; - icon?: string; - disabled?: boolean; -} - -const generationTypes: DropdownOption[] = [ - { label: '视频生成', value: 'video', icon: 'video' }, - { label: '图片生成', value: 'image', icon: 'image' }, -]; - -const modelOptions: DropdownOption[] = [ - { label: 'Seedance 2.0', value: 'seedance_2.0', icon: 'diamond' }, - { label: 'Seedance 2.0 Fast', value: 'seedance_2.0_fast', icon: 'diamond' }, -]; - -const modeOptions: DropdownOption[] = [ - { label: '全能参考', value: 'universal', icon: 'sparkle' }, - { label: '首尾帧', value: 'keyframe', icon: 'swap' }, -]; - -const aspectRatioOptions: DropdownOption[] = [ - { label: '16:9', value: '16:9' }, - { label: '9:16', value: '9:16' }, - { label: '1:1', value: '1:1' }, - { label: '21:9', value: '21:9' }, - { label: '4:3', value: '4:3' }, - { label: '3:4', value: '3:4' }, -]; - -const durationOptions: DropdownOption[] = [ - { label: '5s', value: '5' }, - { label: '10s', value: '10' }, - { label: '15s', value: '15' }, -]; -``` - -### 6.3 [Phase 2] 前端 Auth Store 类型(Phase 3 修改配额字段) - -```typescript -interface User { - id: number; - username: string; - email: string; - is_staff: boolean; -} - -// [Phase 3] 配额字段改为秒数 -interface Quota { - daily_seconds_limit: number; // 原 daily_limit - daily_seconds_used: number; // 原 daily_used - monthly_seconds_limit: number; // 原 monthly_limit - monthly_seconds_used: number; // 原 monthly_used -} - -interface AuthStore { - // 状态 - user: User | null; - accessToken: string | null; - refreshToken: string | null; - isAuthenticated: boolean; - isLoading: boolean; - - // 操作 - login: (username: string, password: string) => Promise; - register: (username: string, email: string, password: string) => Promise; - logout: () => void; - refreshAccessToken: () => Promise; - fetchUserInfo: () => Promise; - - // 配额 - quota: Quota | null; - fetchQuota: () => Promise; -} -``` - -### 6.4 [Phase 3] 前端新增类型 - -```typescript -// 管理后台统计数据 -interface AdminStats { - total_users: number; - new_users_today: number; - seconds_consumed_today: number; // 原 calls_today - seconds_consumed_this_month: number; // 原 calls_this_month - today_change_percent: number; - month_change_percent: number; - daily_trend: { date: string; seconds: number }[]; - top_users: { user_id: number; username: string; seconds_consumed: number }[]; -} - -// 管理后台用户列表项 -interface AdminUser { - id: number; - username: string; - email: string; - is_active: boolean; - date_joined: string; - daily_seconds_limit: number; - monthly_seconds_limit: number; - seconds_today: number; - seconds_this_month: number; -} - -// 管理后台消费记录 -interface AdminRecord { - id: number; - created_at: string; - user_id: number; - username: string; - seconds_consumed: number; - prompt: string; - mode: CreationMode; - model: ModelOption; - aspect_ratio: string; - status: 'queued' | 'processing' | 'completed' | 'failed'; -} - -// 系统设置 -interface SystemSettings { - default_daily_seconds_limit: number; - default_monthly_seconds_limit: number; - announcement: string; - announcement_enabled: boolean; -} - -// 用户个人中心概览 -interface ProfileOverview { - daily_seconds_limit: number; - daily_seconds_used: number; - monthly_seconds_limit: number; - monthly_seconds_used: number; - total_seconds_used: number; - daily_trend: { date: string; seconds: number }[]; -} - -// 用户消费记录 -interface ProfileRecord { - id: number; - created_at: string; - seconds_consumed: number; - prompt: string; - mode: CreationMode; - model: ModelOption; - aspect_ratio: string; - status: 'queued' | 'processing' | 'completed' | 'failed'; -} - -// 分页响应 -interface PaginatedResponse { - total: number; - page: number; - page_size: number; - results: T[]; -} -``` - -### 6.5 后端数据模型(Django Models) - -#### [Phase 2 → Phase 3 修改] 用户模型 - -```python -# backend/apps/accounts/models.py - -from django.contrib.auth.models import AbstractUser -from django.db import models - -class User(AbstractUser): - """扩展用户模型 — Phase 3: 配额单位改为秒数""" - email = models.EmailField(unique=True, verbose_name='邮箱') - # [Phase 3] 改为秒数限制 - daily_seconds_limit = models.IntegerField(default=600, verbose_name='每日秒数上限') - monthly_seconds_limit = models.IntegerField(default=6000, verbose_name='每月秒数上限') - created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') - updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间') - - class Meta: - verbose_name = '用户' - verbose_name_plural = '用户' -``` - -> **迁移说明**: 需要创建 Django migration 将 `daily_limit` → `daily_seconds_limit`,`monthly_limit` → `monthly_seconds_limit`,并将现有数据按「原次数 × 15」换算为秒数(假设平均每次生成 15 秒)。 - -#### [Phase 2 → Phase 3 修改] 生成记录模型 - -```python -# backend/apps/generation/models.py - -import uuid -from django.db import models -from django.conf import settings - -class GenerationRecord(models.Model): - """视频生成记录 — Phase 3: 新增消费秒数字段""" - MODE_CHOICES = [ - ('universal', '全能参考'), - ('keyframe', '首尾帧'), - ] - MODEL_CHOICES = [ - ('seedance_2.0', 'Seedance 2.0'), - ('seedance_2.0_fast', 'Seedance 2.0 Fast'), - ] - STATUS_CHOICES = [ - ('queued', '排队中'), - ('processing', '生成中'), - ('completed', '已完成'), - ('failed', '失败'), - ] - - user = models.ForeignKey( - settings.AUTH_USER_MODEL, - on_delete=models.CASCADE, - related_name='generation_records', - verbose_name='用户' - ) - task_id = models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='任务ID') - prompt = models.TextField(blank=True, verbose_name='提示词') - mode = models.CharField(max_length=20, choices=MODE_CHOICES, verbose_name='创作模式') - model = models.CharField(max_length=30, choices=MODEL_CHOICES, verbose_name='模型') - aspect_ratio = models.CharField(max_length=10, verbose_name='宽高比') - duration = models.IntegerField(verbose_name='视频时长(秒)') - seconds_consumed = models.FloatField(default=0, verbose_name='消费秒数') # [Phase 3] 新增 - status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='queued', verbose_name='状态') - created_at = models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='创建时间') - - class Meta: - verbose_name = '生成记录' - verbose_name_plural = '生成记录' - ordering = ['-created_at'] - indexes = [ - models.Index(fields=['user', 'created_at']), - ] -``` - -> **消费秒数逻辑**: `seconds_consumed` = 视频 `duration`(5/10/15秒),在调用生成 API 时自动设置。 - -#### [Phase 2 → Phase 3 修改] 配额配置模型 - -```python -# backend/apps/generation/models.py (续) - -class QuotaConfig(models.Model): - """全局配额配置 — Phase 3: 改为秒数""" - default_daily_seconds_limit = models.IntegerField(default=600, verbose_name='默认每日秒数上限') - default_monthly_seconds_limit = models.IntegerField(default=6000, verbose_name='默认每月秒数上限') - announcement = models.TextField(blank=True, default='', verbose_name='系统公告') # [Phase 3] 新增 - announcement_enabled = models.BooleanField(default=False, verbose_name='启用公告') # [Phase 3] 新增 - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - verbose_name = '系统配置' - verbose_name_plural = '系统配置' - - def save(self, *args, **kwargs): - # 单例模式,确保只有一条记录 - self.pk = 1 - super().save(*args, **kwargs) -``` - -## 7. 非功能需求 - -### 性能要求 -- 首屏加载 < 2s(Vite 构建,代码分割) -- 文件上传后缩略图预览 < 200ms(使用 URL.createObjectURL 本地生成) -- 下拉菜单展开/收起动画 < 150ms -- 文本输入无感知延迟(非受控组件或 debounce) -- [Phase 2] 后端 API 响应时间 < 500ms(除文件上传外) -- [Phase 2] JWT Token 验证 < 50ms -- [Phase 3] ECharts 图表渲染 < 300ms(含数据加载) -- [Phase 3] 管理后台页面切换 < 200ms(路由级代码分割) -- [Phase 3] 分页列表请求 < 300ms - -### 安全要求 -- 文件上传仅限 image/* 和 video/* MIME 类型 -- 文件大小限制:图片 < 20MB,视频 < 100MB -- 使用 URL.createObjectURL 生成预览,组件卸载时调用 URL.revokeObjectURL 释放内存 -- [Phase 2] 密码使用 Django 默认的 PBKDF2 算法加密存储 -- [Phase 2] JWT Access Token 有效期 2 小时,Refresh Token 有效期 7 天 -- [Phase 2] 数据库密码等敏感配置通过环境变量管理(生产环境),开发环境可硬编码在 settings 中 -- [Phase 2] API 接口对未认证请求返回 401,对权限不足返回 403 -- [Phase 2] 管理接口仅 `is_staff=True` 用户可访问 -- [Phase 3] 管理后台操作(修改配额、禁用用户)需记录操作日志 -- [Phase 3] CSV 导出需要防止 CSV 注入攻击(prompt 字段可能包含特殊字符) - -### 响应式设计要求 -- 桌面端(≥1024px):InputBar 最大宽度 900px 居中;管理后台 Sidebar 240px + 内容区自适应 -- 平板端(768px-1023px):InputBar 宽度 90% 居中;管理后台 Sidebar 折叠为图标模式 -- 移动端(<768px):InputBar 宽度 95%,工具栏按钮文字隐藏仅显示图标;管理后台 Sidebar 隐藏,使用汉堡菜单 - -### 浏览器兼容 -- Chrome 90+、Firefox 90+、Safari 15+、Edge 90+ - -## 8. 验收标准 - -> **重要**: Phase 1 和 Phase 2 功能已完成。当前验收范围为 **Phase 3 全部功能**。Phase 1/2 功能保持不变,不重复验收。 - -### Phase 1 验收标准(已通过) - -#### P0(已全部通过) -1. 页面打开后显示深色全屏背景 `#0a0a0f`,底部居中显示 InputBar -2. InputBar 样式与参考截图视觉一致:背景 `#16161e`、边框 `#2a2a38`、圆角 `20px` -3. 默认处于「全能参考」模式,显示 [+ 参考内容] 上传按钮 + 提示词输入框 -4. 点击 [+ 参考内容] 可选择图片/视频文件,上传后显示带序号的缩略图 -5. 上传 1-5 张文件后缩略图正确显示,每个有 × 关闭按钮可删除 -6. 切换到「首尾帧」模式后,上传区变为首帧 ↔ 尾帧双框布局 -7. 工具栏所有按钮正确显示,布局与参考截图一致 -8. 发送按钮状态正确:无内容时灰色,有内容时蓝色 `#00b8e6` - -#### P1(已全部通过) -9. 「视频生成」下拉、「模型选择」下拉、「模式切换」下拉均可正常展开和选择 -10. 比例选择按钮点击弹出 6 个选项,选中后按钮文字更新 -11. 时长选择按钮点击弹出 3 个选项,选中后按钮文字更新 -12. 切换模式时联动正确:全能参考→首尾帧时比例变为「自动匹配」、时长变为 5s、隐藏 @ 按钮 -13. 文件上传支持拖拽 - -#### P2(已全部通过) -14. 下拉菜单有动画过渡效果 -15. `Ctrl/Cmd + Enter` 可触发发送 -16. 页面加载后文本输入框自动聚焦 -17. 移动端下工具栏按钮自适应 - -### Phase 2 验收标准(已通过) - -#### P0(已全部通过) -18. 未登录用户访问 `/` 自动跳转到 `/login` -19. 注册页表单验证正确,注册成功后自动登录跳转到首页 -20. 登录页输入正确凭据后成功登录,获取 JWT Token -21. 后端 Django 服务正常启动,能连接 MySQL 数据库 -22. 发送按钮点击后调用后端 API,后端记录调用并返回剩余配额 - -#### P1(已全部通过) -23. 管理员登录后可访问管理后台,普通用户无法访问 -24. 管理后台正确显示用户总数、调用统计等指标 -25. 管理员可修改用户的每日/每月调用限额 -26. 超出限额时前端显示友好提示,后端返回 429 状态码 -27. Django Admin 后台(`/admin/`)可管理用户和生成记录 - -### Phase 3 验收标准(当前迭代) - -#### P0(必须全部通过) -28. 所有「调用次数」展示改为「生成秒数」—— UserInfoBar 显示「剩余 Ns/Ns(日)」而非「剩余 N 次」 -29. 后端 User 模型字段 `daily_limit`/`monthly_limit` 迁移为 `daily_seconds_limit`/`monthly_seconds_limit` -30. GenerationRecord 模型新增 `seconds_consumed` 字段,生成 API 返回 `seconds_consumed` 和 `remaining_seconds_today` -31. 管理后台使用左侧 Sidebar + 右侧内容区布局,Sidebar 包含 4 个导航项(仪表盘/用户管理/消费记录/系统设置) -32. `/admin/dashboard` 仪表盘页面显示 4 个统计卡片(总用户、今日新增、今日消费秒数、本月消费秒数)+ ECharts 消费趋势折线图 + 用户消费排行柱状图 -33. `/admin/users` 用户管理页面支持分页列表、搜索筛选、编辑配额、启用/禁用用户 -34. `/profile` 用户个人中心显示消费概览(环形进度条)+ 消费记录列表 - -#### P1 -35. `/admin/records` 消费记录页面显示所有用户消费明细,支持时间范围筛选和导出 CSV -36. `/admin/settings` 系统设置页面支持修改全局默认配额和管理系统公告 -37. 用户个人中心显示消费趋势 Sparkline 迷你图(近 7天/30天 切换) -38. 仪表盘统计卡片显示环比变化百分比 + 趋势箭头 -39. 用户管理页面点击用户名展开详情抽屉,显示用户详情 + 近期消费记录 -40. 管理后台深色主题与 Linear/Vercel Dashboard 风格一致 -41. 数据加载使用骨架屏(Skeleton) - -#### P2 -42. 管理后台 Sidebar 支持折叠为图标模式 -43. 页面切换有 fade/slide 过渡动画 -44. 当日额度消费超过 80% 时用户端显示黄色警告提示 - -## 9. 模式切换联动逻辑 - -| 切换动作 | 上传区 | 比例 | 时长 | @ 按钮 | Placeholder | -|---------|--------|------|------|--------|-------------| -| → 全能参考 | [+ 参考内容] 多文件上传 | 恢复用户之前选择(默认 21:9) | 恢复用户之前选择(默认 15s) | 显示 | "上传1-5张参考图或视频,输入文字,自由组合图、文、音、视频多元素,定义精彩互动。" | -| → 首尾帧 | [首帧] ↔ [+ 尾帧] | 自动匹配(灰色不可选) | 5s(可切换) | 隐藏 | "输入描述,定义首帧到尾帧的运动过程" | - -> **注意**: 切换模式时不清空已输入的提示词文本,但上传的文件会被清空(因为两种模式的上传逻辑不同)。 - -## 10. 设计规范(Design Token) - -### 颜色 - -| Token | 值 | 用途 | -|-------|-----|------| -| `--color-bg-page` | `#0a0a0f` | 页面背景 | -| `--color-bg-input-bar` | `#16161e` | InputBar 背景 | -| `--color-border-input-bar` | `#2a2a38` | InputBar 边框 | -| `--color-primary` | `#00b8e6` | 主强调色(发送按钮、视频生成文字) | -| `--color-text-primary` | `#ffffff` | 主文字 | -| `--color-text-secondary` | `#8a8a9a` | 次文字(工具栏按钮、placeholder) | -| `--color-text-disabled` | `#4a4a5a` | 禁用文字 | -| `--color-bg-hover` | `rgba(255, 255, 255, 0.06)` | 按钮 hover 背景 | -| `--color-bg-dropdown` | `#1e1e2a` | 下拉菜单背景 | -| `--color-bg-upload` | `rgba(255, 255, 255, 0.04)` | 上传区背景 | -| `--color-border-upload` | `#2a2a38` | 上传区虚线边框 | -| `--color-btn-send-disabled` | `#3a3a4a` | 发送按钮禁用状态 | -| `--color-btn-send-active` | `#00b8e6` | 发送按钮激活状态 | - -### [Phase 3] 管理后台专用颜色 - -| Token | 值 | 用途 | -|-------|-----|------| -| `--color-bg-sidebar` | `#111118` | Sidebar 背景 | -| `--color-sidebar-active` | `rgba(255, 255, 255, 0.08)` | Sidebar 当前项背景 | -| `--color-sidebar-hover` | `rgba(255, 255, 255, 0.04)` | Sidebar hover 背景 | -| `--color-bg-card` | `#16161e` | 卡片/面板背景 | -| `--color-border-card` | `#2a2a38` | 卡片边框 | -| `--color-success` | `#00b894` | 正向指标(↑绿色) | -| `--color-danger` | `#e74c3c` | 负向指标(↓红色) / 禁用状态 | -| `--color-warning` | `#f39c12` | 警告提示(额度 80%+) | - -### 圆角 - -| Token | 值 | 用途 | -|-------|-----|------| -| `--radius-input-bar` | `20px` | InputBar 容器 | -| `--radius-btn` | `8px` | 工具栏按钮 | -| `--radius-send-btn` | `50%` | 发送按钮(圆形) | -| `--radius-thumbnail` | `8px` | 缩略图 | -| `--radius-dropdown` | `12px` | 下拉菜单 | -| `--radius-card` | `12px` | [Phase 3] 管理后台卡片 | - -### 尺寸 - -| Token | 值 | 用途 | -|-------|-----|------| -| `--input-bar-max-width` | `900px` | InputBar 最大宽度 | -| `--send-btn-size` | `36px` | 发送按钮直径 | -| `--thumbnail-size` | `80px` | 上传缩略图尺寸 | -| `--toolbar-height` | `44px` | 工具栏行高 | -| `--toolbar-btn-height` | `32px` | 工具栏按钮高度 | -| `--sidebar-width` | `240px` | [Phase 3] Sidebar 宽度 | -| `--sidebar-collapsed-width` | `64px` | [Phase 3] Sidebar 折叠宽度 | - -## 11. 组件树结构 - -``` -App -├── AuthProvider // [Phase 2] 认证上下文 -├── Router // [Phase 2] 路由 -│ ├── /login → LoginPage // [Phase 2] 登录页 -│ ├── /register → RegisterPage // [Phase 2] 注册页 -│ ├── / → ProtectedRoute // [Phase 2] 需要登录 -│ │ └── VideoGenerationPage -│ │ ├── UserInfoBar // [Phase 2] 顶部用户信息 + [Phase 3] 秒数配额 + 个人中心链接 -│ │ ├── PageBackground -│ │ └── InputBar -│ │ ├── InputArea -│ │ │ ├── UploadSection -│ │ │ │ ├── UniversalUpload -│ │ │ │ │ ├── UploadButton -│ │ │ │ │ └── ThumbnailGrid -│ │ │ │ │ └── ThumbnailItem -│ │ │ │ └── KeyframeUpload -│ │ │ │ ├── FrameUpload -│ │ │ │ ├── ArrowIcon -│ │ │ │ └── FrameUpload -│ │ │ └── PromptInput -│ │ └── Toolbar -│ │ ├── GenerationTypeDropdown -│ │ ├── ModelSelector -│ │ ├── ModeDropdown -│ │ ├── AspectRatioSelector -│ │ ├── DurationSelector -│ │ ├── AtButton -│ │ ├── FlexSpacer -│ │ └── SendButton -│ ├── /profile → ProtectedRoute // [Phase 3] 用户个人中心 -│ │ └── ProfilePage -│ │ ├── ProfileHeader // 返回首页 + 用户信息 -│ │ ├── ConsumptionOverview // 消费概览卡片 -│ │ │ ├── EChartsGauge // 环形进度条 -│ │ │ ├── DailyQuotaCard // 今日额度进度条 -│ │ │ └── MonthlyQuotaCard // 本月额度进度条 -│ │ ├── ConsumptionTrend // Sparkline 迷你趋势图 -│ │ └── ConsumptionRecordList // 消费记录列表 -│ ├── /admin → ProtectedRoute (requireAdmin) // [Phase 3] 管理后台 -│ │ └── AdminLayout // Sidebar + Content 布局 -│ │ ├── AdminSidebar // 左侧导航栏 -│ │ │ ├── SidebarLogo // Logo -│ │ │ ├── SidebarNav // 导航菜单 -│ │ │ │ ├── NavItem (仪表盘) -│ │ │ │ ├── NavItem (用户管理) -│ │ │ │ ├── NavItem (消费记录) -│ │ │ │ └── NavItem (系统设置) -│ │ │ └── SidebarFooter // 返回首页链接 -│ │ └── AdminContent // 右侧内容区 (Outlet) -│ │ ├── /admin/dashboard → DashboardPage -│ │ │ ├── StatsCards // 4 个指标卡片 -│ │ │ ├── TrendLineChart // ECharts 折线图 -│ │ │ └── TopUsersBarChart // ECharts 柱状图 -│ │ ├── /admin/users → UsersPage -│ │ │ ├── UserSearchBar // 搜索 + 筛选 -│ │ │ ├── UserTable // Arco Table -│ │ │ ├── QuotaEditModal // 配额编辑弹窗 -│ │ │ └── UserDetailDrawer // 用户详情抽屉 -│ │ ├── /admin/records → RecordsPage -│ │ │ ├── RecordFilters // 筛选条件 -│ │ │ ├── RecordTable // Arco Table -│ │ │ └── ExportButton // 导出 CSV -│ │ └── /admin/settings → SettingsPage -│ │ ├── QuotaSettingsCard // 全局配额表单 -│ │ └── AnnouncementCard // 公告管理 -│ └── * → Navigate to / -``` - -## 12. 后端项目结构 - -``` -backend/ -├── manage.py -├── requirements.txt -├── config/ # Django 项目配置 -│ ├── __init__.py -│ ├── settings.py -│ ├── urls.py -│ ├── wsgi.py -│ └── asgi.py -├── apps/ -│ ├── accounts/ # 用户认证模块 -│ │ ├── __init__.py -│ │ ├── models.py # User 扩展模型 (Phase 3: 秒数字段) -│ │ ├── serializers.py # 注册/登录序列化器 -│ │ ├── views.py # 注册/登录/Token刷新 API -│ │ ├── urls.py -│ │ └── admin.py # 用户管理 Admin -│ └── generation/ # 视频生成模块 -│ ├── __init__.py -│ ├── models.py # GenerationRecord (Phase 3: +seconds_consumed) + QuotaConfig (Phase 3: +announcement) -│ ├── serializers.py # [Phase 3] 新增管理后台 + 个人中心序列化器 -│ ├── views.py # [Phase 3] 新增管理后台 API (stats/users/records/settings) + 个人中心 API (overview/records) -│ ├── urls.py # [Phase 3] 新增路由 -│ ├── admin.py # 生成记录 Admin -│ └── middleware.py # 配额检查中间件 (Phase 3: 改为秒数检查) -``` - -## 13. 参考截图说明 - -参考截图存放于 `/Users/maidong/Desktop/zyc/研究openclaw/视频生成平台/` 目录: - -| 文件 | 内容描述 | -|------|---------| -| `20260311-154443.jpeg` | **空状态全貌** — 完整展示了 InputBar 在无输入时的样式 | -| `20260311-154432.jpeg` | **已上传状态** — 展示了上传 1 张图片后的 InputBar | -| `20260311-154407.jpeg` | **有内容状态** — 展示了输入完整提示词 + 多张图片引用后的 InputBar | - -## 14. 修订历史 - -| 日期 | 版本 | 变更内容 | -|------|------|---------| -| 2026-03-11 | v1.0 | 初始版本 — 纯前端视频生成输入界面 | -| 2026-03-12 | v2.0 | 增量迭代 — 新增 Django 后端、用户认证系统、后台管理系统 | -| 2026-03-12 | v2.1 | **需求修订(BUG-002)** — 引入开发阶段划分(Phase 1 / Phase 2),验收标准按阶段分组 | -| 2026-03-12 | v2.2 | **需求修订(BUG-002 后续)** — Phase 2 功能已完成开发,更新阶段状态和验收范围 | -| 2026-03-12 | v3.0 | **重大迭代 — Phase 3** — 计量单位从「调用次数」改为「生成秒数」;管理后台从单页面重做为多页面 Sidebar 布局(仪表盘/用户管理/消费记录/系统设置);新增用户个人中心(/profile)含消费概览、环形进度条、消费趋势 Sparkline、消费记录列表;引入 ECharts 图表库;管理后台深色主题升级(参考 Linear/Vercel 风格);新增骨架屏加载和页面过渡动画;新增 8 个 API 端点、修改 3 个已有 API 端点 | diff --git a/docs/todo/提示词AI优化功能.md b/docs/todo/提示词AI优化功能.md new file mode 100644 index 0000000..8274c4b --- /dev/null +++ b/docs/todo/提示词AI优化功能.md @@ -0,0 +1,65 @@ +# 提示词 AI 优化功能 + +**状态**:待开发 +**创建日期**:2026-04-17 + +## 需求背景 + +用户写提示词时,经常写得过于简单或不符合 Seedance 2.0 的提示词规范(如没用「图片n」引用素材、缺少核心要素、镜头语言模糊等),导致生成效果不理想。 + +引入火山官方的 SKILL.md(Seedance 2.0 Prompt Optimizer)能力,让用户在写完提示词后一键优化。 + +## 功能设计 + +### 用户视角 +1. 用户在提示词输入框输入原始提示词(带 @素材引用) +2. 点击输入框旁的「AI 优化」按钮 +3. 弹出预览弹窗,显示优化后的提示词 +4. 用户点「采纳」→ 替换原提示词;点「取消」→ 保留原文 +5. 消耗一定 token 数(计入团队 token 池) + +### 技术方案 + +**后端** +- 新接口:`POST /api/v1/prompt/optimize` +- 入参:`prompt`(原始提示词,含 `@素材` 标记)、`asset_refs`(素材引用列表:label + type + url) +- 调用豆包模型(推荐 `doubao-seed-2.0` 最新版本,具体 model id 需确认) +- System prompt:基于 SKILL.md 改造成**一次性输出**模式(不做多轮交互) +- 返回:`optimized_prompt`(优化后的文本)+ `token_used`(消耗 token 数) +- 同时扣减团队 token 池 + +**前端** +- `PromptInput` 组件右侧加「AI 优化」按钮(带 ✨ 图标) +- 点击后:loading 状态 → 调用后端接口 → 弹出 `PromptOptimizeModal` 预览弹窗 +- 弹窗显示:原始 vs 优化对比、token 消耗提示、采纳/取消按钮 +- 采纳后:把优化结果写回 editor(保持 @mention 标签正确渲染) + +**SKILL.md 改造要点** +- 去掉 Step 0(主动引导提问)→ 一次输入一次输出 +- 去掉 Step 3 的「多选模板交互」→ 如遇歧义/冲突,在输出里以备注形式标注(如 `【注:检测到 X 冲突,已按 Y 处理】`) +- 保留 Step 2(素材自动映射 `@图N`)、Step 4(结构化输出:优化后提示词 / 优化问题 / 相关原则) + +## 计费设计 +- 提示词优化和视频生成共用**同一个 token 池**(用户已熟悉的计费机制) +- 不单独限额,按实际 token 消耗扣减 +- 前端展示:"本次优化消耗约 X token" + +## 模型选择 +- **首选**:豆包 2.0 系列最强模型(需查火山文档确认最新 model id) +- 备选:`doubao-1-5-pro-32k`(成本更低,任务够用) + +## 待确认事项 +- [ ] 豆包 2.0 系列当前最强模型的具体 model id +- [ ] Token 池扣减逻辑是否需要团队/个人双重配额 +- [ ] 优化失败时(LLM 报错、token 超限)的前端兜底提示 + +## 验收标准 +1. 用户输入粗糙提示词(如「美女跳舞」)→ 优化后符合 SKILL.md 的三段式结构(全局设定 / 时间线脚本 / 质感风格与约束) +2. 带 `@素材` 的提示词 → 优化后正确使用 `@图1/@图2/@视频1` 等标记 +3. 冲突/缺失场景 → 在输出中以备注标明,不擅自填充 +4. Token 消耗正确扣减到团队池 +5. 用户可在弹窗中选择采纳或取消 + +## 参考文件 +- SKILL.md(火山提供的原始技能文件) +- `docs/API文档/seedance 2.0 系列教程.MD` 第 2152 行起的「提示词技巧」部分 diff --git a/test-report.md b/test-report.md deleted file mode 100644 index cab323d..0000000 --- a/test-report.md +++ /dev/null @@ -1,175 +0,0 @@ -# 测试报告 - -## 测试结论: ALL_PASSED - -## Bug 路由摘要 -- CODE_BUG: 0 个(路由到开发 Agent) -- DESIGN_BUG: 0 个(路由到设计 Agent) -- REQUIREMENT_BUG: 0 个(路由到产品 Agent) - -## 测试概要 -- 单元测试: 224 通过 / 0 失败(9 个测试文件) -- E2E 测试: 49 通过 / 0 失败(3 个测试文件) -- 视觉质量检查: 7 通过 / 0 失败 -- 后端 API 验证: 12 端点全部通过 -- Django 系统检查: 0 问题 -- 数据库迁移: 完整 - -## 通过的测试 - -### 单元测试(224 个) - -#### 既有测试文件(已更新适配 Phase 3) -- ✅ test/unit/apiClient.test.ts — API 客户端测试(authApi、videoApi、adminApi、profileApi) -- ✅ test/unit/phase2Components.test.tsx — 组件类型测试(已更新为秒数配额格式) -- ✅ test/unit/auth.test.ts — 认证流程测试 -- ✅ test/unit/videoGeneration.test.ts — 视频生成测试 -- ✅ test/unit/adminPanel.test.ts — 管理面板测试 -- ✅ test/unit/uiComponents.test.tsx — UI 组件测试 -- ✅ test/unit/routerSetup.test.tsx — 路由配置测试 -- ✅ test/unit/phase2Features.test.ts — Phase 2 功能测试 - -#### Phase 3 新增测试(62 个,test/unit/phase3Features.test.ts) -- ✅ 秒数配额系统验证(7 个)— Quota 类型字段、默认值 600s/6000s、使用量追踪 -- ✅ 管理后台多页面布局验证(7 个)— AdminLayout 侧边栏、4 个导航链接、折叠功能 -- ✅ 仪表盘页面验证(8 个)— ECharts 图表、统计卡片、趋势数据、骨架屏加载 -- ✅ 用户管理页面验证(6 个)— 用户表格、搜索过滤、配额编辑、状态切换 -- ✅ 消费记录页面验证(5 个)— 记录表格、日期范围过滤、CSV 导出、分页 -- ✅ 系统设置页面验证(4 个)— 全局配额默认值、公告管理、开关切换 -- ✅ 个人中心页面验证(8 个)— 仪表盘图表、进度条、趋势图、消费记录列表 -- ✅ 后端 API 路由验证(4 个)— profile 和 admin URL 配置完整 -- ✅ QuotaConfig 模型验证(3 个)— 单例模式、默认值 -- ✅ ProtectedRoute 管理员守卫(1 个)— requireAdmin 属性 -- ✅ UserInfoBar 导航(2 个)— 秒数显示、个人中心链接 -- ✅ ECharts 集成(3 个)— echarts-for-react 依赖、图表组件配置 -- ✅ 路由配置(4 个)— 嵌套路由、重定向、通配符 - -### E2E 测试(49 个) - -#### 既有 E2E 测试(26 个) -- ✅ test/e2e/video-generation.spec.ts — 视频生成页 P0/P1/P2 验收 + Sidebar(14 个) -- ✅ test/e2e/auth-flow.spec.ts — 认证流程(注册、登录、登出、路由保护)(12 个) - -#### Phase 3 新增 E2E 测试(23 个,test/e2e/phase3-admin-profile.spec.ts) - -**个人中心页面(7 个)** -- ✅ 已认证用户可访问个人中心 -- ✅ 显示消费概览(今日额度、本月额度) -- ✅ 显示消费趋势(近 7 天 / 近 30 天切换) -- ✅ 显示消费记录(新用户显示"暂无记录") -- ✅ 返回首页导航 -- ✅ 退出按钮可见 -- ✅ 未认证用户重定向到登录页 - -**UserInfoBar 配额与导航(2 个)** -- ✅ 显示秒数格式配额(剩余: Xs/Xs(日)) -- ✅ 个人中心链接导航到 /profile - -**管理后台权限控制(6 个)** -- ✅ 非管理员用户无法访问 /admin/dashboard -- ✅ 非管理员用户无法访问 /admin/users -- ✅ 非管理员用户无法访问 /admin/records -- ✅ 非管理员用户无法访问 /admin/settings -- ✅ /admin 重定向到 /admin/dashboard -- ✅ 未认证访问 /admin 重定向到 /login - -**后端 API 集成(7 个)** -- ✅ GET /api/v1/auth/me 返回秒数配额(daily_seconds_limit=600, monthly_seconds_limit=6000) -- ✅ GET /api/v1/profile/overview 返回消费数据(7 天趋势) -- ✅ GET /api/v1/profile/overview 支持 30 天周期 -- ✅ GET /api/v1/profile/records 返回分页记录 -- ✅ POST /api/v1/video/generate 消耗秒数(seconds_consumed=10, remaining=590) -- ✅ 管理端点对非管理员返回 403 -- ✅ 未认证请求返回 401 - -**趋势切换(1 个)** -- ✅ 点击 30 天标签更新趋势周期 - -### 后端 API 验证(curl 直接测试) -- ✅ POST /api/v1/auth/register — 201 Created -- ✅ POST /api/v1/auth/login — 200 OK -- ✅ GET /api/v1/auth/me — 返回秒数配额 -- ✅ GET /api/v1/profile/overview?period=7d — 7 天趋势 -- ✅ GET /api/v1/profile/overview?period=30d — 30 天趋势 -- ✅ GET /api/v1/profile/records — 分页记录 -- ✅ GET /api/v1/admin/stats — 管理统计数据 -- ✅ GET /api/v1/admin/users — 用户列表(分页、搜索) -- ✅ GET /api/v1/admin/records — 消费记录(日期过滤) -- ✅ GET /api/v1/admin/settings — 系统设置 -- ✅ POST /api/v1/video/generate — 202 Accepted,seconds_consumed=10 -- ✅ Django system check: 0 issues, migrations up-to-date - -## 失败的测试(Bug 列表) - -无 - -## 视觉质量检查 - -| 检查项 | 状态 | 说明 | -|-------|------|------| -| 登录页面 | ✅ | 暗色主题,表单完整,注册链接可见 | -| 主页面(已登录) | ✅ | 显示"剩余: 600s/600s(日)"秒数配额,个人中心和管理后台入口可见 | -| 管理后台 — 仪表盘 | ✅ | 侧边栏 4 个导航项,统计卡片(用户数、今日消费、本月消费、活跃用户),ECharts 折线图和柱状图 | -| 管理后台 — 用户管理 | ✅ | 用户表格含秒数配额列,搜索过滤,分页功能 | -| 管理后台 — 消费记录 | ✅ | 记录表格含时间/用户/秒数/描述/模式/状态列,日期范围过滤,导出 CSV 按钮 | -| 管理后台 — 系统设置 | ✅ | 全局默认配额(600s/6000s),系统公告开关和文本输入 | -| 个人中心 | ✅ | 仪表盘图表(0s/600s),今日/本月额度卡片含进度条,消费趋势(近7天/近30天),消费记录(暂无记录) | - -### 视觉截图文件 -- screenshot-login-phase3.png — 登录页 -- screenshot-main-page-phase3.png — 主页面 -- screenshot-admin-dashboard-phase3.png — 管理仪表盘 -- screenshot-admin-users-phase3.png — 用户管理 -- screenshot-admin-records-phase3.png — 消费记录 -- screenshot-admin-settings-phase3.png — 系统设置 -- screenshot-profile-phase3.png — 个人中心 - -## 上一轮 Bug 修复验证 — 全部 ✅ - -| 原 Bug | 状态 | 验证方式 | -|--------|------|---------| -| API 拦截器在登录端点 401 重定向 | ✅ 已修复 | `api.ts:24-25` 排除 `/auth/login`、`/auth/register`、`/auth/token/refresh` 端点 | -| 音频类型死代码(types/store/components) | ✅ 已修复 | 源码审查确认 `UploadedFile.type` 为 `'image' \| 'video'`,音频分支已全部移除 | -| GenerationCard 硬编码模型名 | ✅ 已修复 | `GenerationCard.tsx:54` 使用 `task.model` 动态渲染 | -| 无文件大小验证 | ✅ 已修复 | UniversalUpload、InputBar、KeyframeUpload 均有 20MB/100MB 限制 | - -## Phase 3 功能覆盖总结 - -| 功能模块 | 前端 | 后端 API | 单元测试 | E2E 测试 | 视觉检查 | -|---------|------|---------|---------|---------|---------| -| 秒数配额系统 | ✅ | ✅ | ✅ | ✅ | ✅ | -| 管理后台侧边栏 | ✅ | — | ✅ | ✅ | ✅ | -| 仪表盘(ECharts) | ✅ | ✅ | ✅ | — | ✅ | -| 用户管理 | ✅ | ✅ | ✅ | — | ✅ | -| 消费记录 | ✅ | ✅ | ✅ | — | ✅ | -| 系统设置 | ✅ | ✅ | ✅ | — | ✅ | -| 个人中心 | ✅ | ✅ | ✅ | ✅ | ✅ | -| 权限控制 | ✅ | ✅ | ✅ | ✅ | — | -| CSV 导出 | ✅ | — | ✅ | — | ✅ | - -## 测试环境 -- 前端: Vite 5 + React 18 + TypeScript -- 后端: Django 4.2 + DRF + SimpleJWT -- 单元测试: Vitest 3.x (jsdom) -- E2E 测试: Playwright 1.50 -- 数据库: SQLite (开发环境) -- Node.js: v22+ -- Python: 3.12+ - -## 测试文件清单 - -| 文件 | 类型 | 测试数 | -|------|------|--------| -| `test/unit/inputBarStore.test.ts` | Store 单元测试 | 31 | -| `test/unit/generationStore.test.ts` | Store 单元测试 | 15 | -| `test/unit/authStore.test.ts` | Store 单元测试 | 15 | -| `test/unit/apiClient.test.ts` | API 客户端测试 | 20 | -| `test/unit/phase2Components.test.tsx` | Phase 2 组件测试 | 17 | -| `test/unit/designTokens.test.ts` | CSS/设计规范测试 | 30 | -| `test/unit/components.test.tsx` | 组件渲染测试 | 16 | -| `test/unit/bugfixVerification.test.ts` | Bug 修复验证 | 15 | -| `test/unit/phase3Features.test.ts` | Phase 3 功能测试 | 62 | -| `test/e2e/video-generation.spec.ts` | E2E 视频生成 | 14 | -| `test/e2e/auth-flow.spec.ts` | E2E 认证流程 | 12 | -| `test/e2e/phase3-admin-profile.spec.ts` | E2E Phase 3 | 23 | -| **总计** | | **270** |