Doubao Seedance 2.0 系列(下文简称 Seedance 2.0 系列)模型支持图像、视频、音频、文本等多种模态内容输入,具备视频生成、视频编辑、视频延长等能力,可高精度还原物品细节、音色、效果、风格、运镜等,保持稳定角色特征,赋予使用者如同导演般的掌控权。本文介绍 Seedance 2.0 系列模型的专属能力,帮助您快速实现 Video Generation API 调用。
新手入门#
本入门教程专为 API 新手用户 设计,帮助您一键搭建 Python 开发环境、完成虚拟环境创建和方舟 SDK 安装,并提供直接可运行的 Seedance 2.0 系列调用代码,您只需修改对应的输入素材,即可开始您的视频生成创作。
1. 准备工作
在开始之前,请确保您已经完成以下准备:
-
注册账号:确保您拥有火山引擎账号并已 登录。
-
获取 API Key:访问 API Key 管理页面,点击 创建 API Key,并复制保存您的 API Key。注意请妥善保管您的 API Key,不要泄露给他人。
-
下载并解压文件:点击下载下方附件,将其解压到您的本地目录(如桌面或“下载”文件夹)。
2.操作步骤
-
进入
scripts/init_dev_env目录。 -
双击运行
setup_windows.bat。 -
脚本会自动执行以下操作:
-
下载 uv 工具。
-
自动下载 Python 3.12(如果不干扰您的系统 Python)。
-
创建虚拟环境 .
venv。 -
安装方舟 SDK。
-
-
完成后,在项目根目录会生成一个
run_demo.bat。 -
双击
run_demo.bat,即可运行 Python SDK 示例代码(python/demo_standard.py)。
-
打开终端,进入
scripts/init_dev_env目录。 -
运行构建脚本:
./setup_mac.sh -
脚本会自动配置好所有环境。
-
完成后,在项目根目录会生成一个
run_demo.sh。 -
运行
./run_demo.sh即可运行 Python SDK 示例代码(python/demo_standard.py)。
3.运行说明
运行脚本后,您将看到如下流程:
- API Key 校验:脚本会自动检测您本地是否配置了
ARK_API_KEY环境变量。如果没有,会提示您手动输入。 - 素材预览:脚本会自动在您的默认浏览器中弹出一个本地生成的 HTML 页面,直观地展示本次任务的文本提示词、待替换的参考图片以及原始参考视频。
- 任务创建与轮询:脚本向火山方舟服务器发起异步请求。由于视频生成需要一定时间,控制台会每隔 30 秒打印一次任务状态(如
running等)。 - 获取结果:任务成功后,控制台会输出一段最终生成的视频 URL。您可以复制该链接到浏览器下载或在线播放。
4.下一步
在成功跑通本示例后,您可以尝试修改 python/``demo_standard.py,来打造您专属的视频生成任务:
- 修改文本提示词
找到代码中的 user_content 变量,更改为您想要的画面描述。
2. 替换输入素材 (图片、视频、音频)
您可以将 reference_image_url、reference_video_url 和 reference_audio_url 替换为您自己的素材链接。
注意:请确保 URL 是公网可公开访问的链接(建议存放在 TOS 对象存储服务中,并配置为公共读)。
3. 继续学习下文中丰富的使用示例。
模型能力#
Seedance 2.0 系列模型目前包括 Doubao Seedance 2.0(下文简称 Seedance 2.0)、Doubao Seedance 2.0 Fast(下文简称 Seedance 2.0 Fast)和 Doubao Seedance 2.0 Mini(下文简称 Seedance 2.0 Mini)。三者支持的功能基本一致,主要区别在于生成品质与成本的取舍:
- 追求最高生成品质,推荐使用 Seedance 2.0;
- 兼顾成本与生成速度,不要求极致品质,推荐使用 Seedance 2.0 Fast;
- 追求更低成本,推荐使用 Seedance 2.0 Mini。
| 模型名称 | Seedance 2.0 | Seedance 2.0 Fast | Seedance 2.0 Mini | |
|---|---|---|---|---|
| Model ID | doubao-seedance-2-0-260128 | doubao-seedance-2-0-fast-260128 | doubao-seedance-2-0-mini-260615 | |
| 文生视频 | ✓ | ✓ | ✓ | |
| 图生视频-首帧 | ✓ | ✓ | ✓ | |
| 图生视频-首尾帧 | ✓ | ✓ | ✓ | |
| 全模态参考【New】 | 图片参考 | ✓ | ✓ | ✓ |
| 视频参考 | ✓ | ✓ | ✓ | |
组合参考
|
✓ | ✓ | ✓ | |
| 编辑视频【New】 | ✓ | ✓ | ✓ | |
| 延长视频【New】 | ✓ | ✓ | ✓ | |
| 生成有声视频 "generate_audio": "true" |
✓ | ✓ | ✓ | |
| 联网搜索工具【New】 | ✓ | ✓ | ✓ | |
| 样片模式 | ✗ | ✗ | ✗ | |
| 返回视频产物对应的尾帧图 "return_last_frame": "true" |
✓ | ✓ | ✓ | |
| 输出视频规格 | 输出分辨率 "resolution": "720p" |
|
|
|
| 输出宽高比 "ratio":"16:9" |
21:9, 16:9, 4:3, 1:1, 3:4, 9:16 |
21:9, 16:9, 4:3, 1:1, 3:4, 9:16 |
21:9, 16:9, 4:3, 1:1, 3:4, 9:16 |
|
| 输出时长 "duration": 5 |
4~15 秒 | 4~15 秒 | 4~15 秒 | |
| 输出视频格式 | mp4 | mp4 | mp4 | |
| 离线推理 "service_tier": "flex" |
✗ | ✗ | ✗ | |
| 在线推理限流 | 最大 RPM | 非 4k 分辨率:
4k 分辨率:
|
|
|
| 最大并发数 | 非 4k 分辨率:
4k 分辨率:
|
|
|
|
| 离线推理限流 | TPD | - | - | - |
基础使用#
全模态参考#
输入文本、参考图、视频(可带音轨)和音频等内容,来生成一段新视频。可继承参考图片的角色形象、视觉风格、画面构图;参考视频的主体内容、运镜方式、动作表现、整体风格;以及参考音频的音色、音乐旋律、对话内容等核心信息。
效果预览如下(访问 模型卡片 查看更多示例):
| 输入:文本 | 输入:图片、视频、音频 | 输出 |
|---|---|---|
| 全程使用视频1的第一视角构图,全程使用音频1作为背景音乐。第一人称视角果茶宣传广告,seedance牌「苹苹安安」苹果果茶限定款;首帧为图片1,你的手摘下一颗带晨露的阿克苏红苹果,清脆的苹果碰撞声;2-4 秒:快速切镜,你的手将苹果块投入雪克杯,加入冰块与茶底,用力摇晃,冰块碰撞声与摇晃声卡点轻快鼓点,背景音:「鲜切现摇」;4-6 秒:第一人称成品特写,分层果茶倒入透明杯,你的手轻挤奶盖在顶部铺展,在杯身贴上粉红包标,镜头拉近看奶盖与果茶的分层纹理;6-8 秒:第一人称手持举杯,你将图片2中的果茶举到镜头前(模拟递到观众面前的视角),杯身标签清晰可见,背景音「来一口鲜爽」,尾帧定格为图片2。背景声音统一为女生音色。 |
import os
import time
# Install SDK: python -m pip install --upgrade arkruntime
from arkruntime import Ark
client = Ark(
# The base URL for model invocation
base_url='https://ark.cn-beijing.volces.com/api/v3',
# Get API Key:https://ark.volcengine.com/region:cn-beijing/apikey
api_key=os.environ.get("ARK_API_KEY"),
)
if __name__ == "__main__":
print("----- create request -----")
create_result = client.content_generation.tasks.create(
model="doubao-seedance-2-0-260128", # Replace with Model ID
content=[
{
"type": "text",
"text": "全程使用视频1的第一视角构图,全程使用音频1作为背景音乐。第一人称视角果茶宣传广告,seedance牌「苹苹安安」苹果果茶限定款;首帧为图片1,你的手摘下一颗带晨露的阿克苏红苹果,轻脆的苹果碰撞声;2-4 秒:快速切镜,你的手将苹果块投入雪克杯,加入冰块与茶底,用力摇晃,冰块碰撞声与摇晃声卡点轻快鼓点,背景音:「鲜切现摇」;4-6 秒:第一人称成品特写,分层果茶倒入透明杯,你的手轻挤奶盖在顶部铺展,在杯身贴上粉红包标,镜头拉近看奶盖与果茶的分层纹理;6-8 秒:第一人称手持举杯,你将图片2中的果茶举到镜头前(模拟递到观众面前的视角),杯身标签清晰可见,背景音「来一口鲜爽」,尾帧定格为图片2。背景声音统一为女生音色。",
},
{
"type": "image_url",
"image_url": {
"url": "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/r2v_tea_pic1-zh.jpg"
},
"role": "reference_image",
},
{
"type": "image_url",
"image_url": {
"url": "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/r2v_tea_pic2-zh.jpg"
},
"role": "reference_image",
},
{
"type": "video_url",
"video_url": {
"url": "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_tea_video1.mp4"
},
"role": "reference_video",
},
{
"type": "audio_url",
"audio_url": {
"url": "https://arkdocs.tos-cn-beijing.volces.com/files/video-generation/r2v_tea_audio1.mp3"
},
"role": "reference_audio",
},
],
generate_audio=True,
ratio="16:9",
duration=11,
watermark=True,
)
print(create_result)
# Polling query section
print("----- polling task status -----")
task_id = create_result.id
while True:
get_result = client.content_generation.tasks.get(task_id=task_id)
status = get_result.status
if status == "succeeded":
print("----- task succeeded -----")
print(get_result)
break
elif status == "failed":
print("----- task failed -----")
print(f"Error: {get_result.error}")
break
else:
print(f"Current status: {status}, Retrying after 30 seconds...")
time.sleep(30)
package com.ark.sample;
import com.volcengine.ark.runtime.models.content_generation.*;
import com.volcengine.ark.runtime.service.ArkService;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class ContentGenerationTaskExample {
// Client initialization
static String apiKey = System.getenv("ARK_API_KEY");
static ConnectionPool connectionPool = new ConnectionPool(5, 1, TimeUnit.SECONDS);
static Dispatcher dispatcher = new Dispatcher();
static ArkService service = ArkService.builder()
.baseUrl("https://ark.cn-beijing.volces.com/api/v3") // The base URL for model invocation
.dispatcher(dispatcher)
.connectionPool(connectionPool)
.apiKey(apiKey)
.build();
public static void main(String[] args) {
// Model ID
final String modelId = "doubao-seedance-2-0-260128";
// Text prompt
final String prompt = "全程使用视频1的第一视角构图,全程使用音频1作为背景音乐。第一人称视角果茶宣传广告,seedance牌「苹苹安安」苹果果茶限定款;" +
"首帧为图片1,你的手摘下一颗带晨露的阿克苏红苹果,轻脆的苹果碰撞声;" +
"2-4 秒:快速切镜,你的手将苹果块投入雪克杯,加入冰块与茶底,用力摇晃,冰块碰撞声与摇晃声卡点轻快鼓点,背景音:「鲜切现摇」;" +
"4-6 秒:第一人称成品特写,分层果茶倒入透明杯,你的手轻挤奶盖在顶部铺展,在杯身贴上粉红包标,镜头拉近看奶盖与果茶的分层纹理;" +
"6-8 秒:第一人称手持举杯,你将图片2中的果茶举到镜头前(模拟递到观众面前的视角),杯身标签清晰可见,背景音「来一口鲜爽」,尾帧定格为图片2。" +
"背景声音统一为女生音色。";
// Example resource URLs
final String refImage1 = "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/r2v_tea_pic1-zh.jpg";
final String refImage2 = "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/r2v_tea_pic2-zh.jpg";
final String refVideo = "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_tea_video1.mp4";
final String refAudio = "https://arkdocs.tos-cn-beijing.volces.com/files/video-generation/r2v_tea_audio1.mp3";
// Output video parameters
final boolean generateAudio = true;
final String videoRatio = "16:9";
final long videoDuration = 11L;
final boolean showWatermark = true;
System.out.println("----- create request -----");
// Build request content
List<ContentItem> contents = new ArrayList<>();
// 1. Text prompt
contents.add(ContentItem.builder()
.type(ContentType.TEXT)
.text(prompt)
.build());
// 2. Reference image 1
contents.add(ContentItem.builder()
.type(ContentType.IMAGE_URL)
.imageUrl(ImageURL.builder()
.url(refImage1)
.build())
.role("reference_image")
.build());
// 3. Reference image 2
contents.add(ContentItem.builder()
.type(ContentType.IMAGE_URL)
.imageUrl(ImageURL.builder()
.url(refImage2)
.build())
.role("reference_image")
.build());
// 4. Reference video
contents.add(ContentItem.builder()
.type(ContentType.VIDEO_URL)
.videoUrl(VideoURL.builder()
.url(refVideo)
.build())
.role("reference_video")
.build());
// 5. Reference audio
contents.add(ContentItem.builder()
.type(ContentType.AUDIO_URL)
.audioUrl(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();
CreateContentGenerationTaskResponse 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) {
String getRequest = taskId;
System.out.println("----- polling task status -----");
try {
while (true) {
ContentGenerationTask getResponse = service.getContentGenerationTask(getRequest);
String status = getResponse.getStatus().toString();
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();
}
}
}
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/volcengine/ark-runtime-go/arkruntime"
model "github.com/volcengine/ark-runtime-go/arkruntime/model/contentgeneration"
)
func main() {
// Initialize Ark client
client := arkruntime.NewClientWithApiKey(
os.Getenv("ARK_API_KEY"),
// The base URL for model invocation
arkruntime.WithBaseUrl("https://ark.cn-beijing.volces.com/api/v3"),
)
ctx := context.Background()
// Model ID
modelID := "doubao-seedance-2-0-260128"
// Text prompt
prompt := "全程使用视频1的第一视角构图,全程使用音频1作为背景音乐。第一人称视角果茶宣传广告,seedance牌「苹苹安安」苹果果茶限定款;" +
"首帧为图片1,你的手摘下一颗带晨露的阿克苏红苹果,轻脆的苹果碰撞声;" +
"2-4 秒:快速切镜,你的手将苹果块投入雪克杯,加入冰块与茶底,用力摇晃,冰块碰撞声与摇晃声卡点轻快鼓点,背景音:「鲜切现摇」;" +
"4-6 秒:第一人称成品特写,分层果茶倒入透明杯,你的手轻挤奶盖在顶部铺展,在杯身贴上粉红包标,镜头拉近看奶盖与果茶的分层纹理;" +
"6-8 秒:第一人称手持举杯,你将图片2中的果茶举到镜头前(模拟递到观众面前的视角),杯身标签清晰可见,背景音「来一口鲜爽」,尾帧定格为图片2。" +
"背景声音统一为女生音色。"
// Example resource URLs
refImage1 := "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/r2v_tea_pic1-zh.jpg"
refImage2 := "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/r2v_tea_pic2-zh.jpg"
refVideo := "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_tea_video1.mp4"
refAudio := "https://arkdocs.tos-cn-beijing.volces.com/files/video-generation/r2v_tea_audio1.mp3"
// Output video parameters
generateAudio := true
videoRatio := "16:9"
videoDuration := int64(11)
showWatermark := true
// 1. Create video generation task
fmt.Println("----- create request -----")
createReq := &model.CreateContentGenerationTaskRequest{
Model: modelID,
GenerateAudio: model.NewOptBool(generateAudio),
Ratio: model.NewOptString(videoRatio),
Duration: model.NewOptInt64(videoDuration),
Watermark: model.NewOptBool(showWatermark),
Content: []model.ContentItem{
{
Type: model.ContentTypeText,
Text: model.NewOptString(prompt),
},
{
Type: model.ContentTypeImageURL,
ImageURL: model.NewOptImageURL(model.ImageURL{
URL: refImage1,
}),
Role: model.NewOptString("reference_image"),
},
{
Type: model.ContentTypeImageURL,
ImageURL: model.NewOptImageURL(model.ImageURL{
URL: refImage2,
}),
Role: model.NewOptString("reference_image"),
},
{
Type: model.ContentTypeVideoURL,
VideoURL: model.NewOptVideoURL(model.VideoURL{
URL: refVideo,
}),
Role: model.NewOptString("reference_video"),
},
{
Type: model.ContentTypeAudioURL,
AudioURL: model.NewOptAudioURL(model.AudioURL{
URL: refAudio,
}),
Role: model.NewOptString("reference_audio"),
},
},
}
createResp, err := client.CreateContentGenerationTask(ctx, createReq)
if err != nil {
fmt.Printf("create content generation error: %v\n", err)
return
}
taskID := createResp.ID
fmt.Printf("Task Created with ID: %s\n", taskID)
// 2. Poll task status
pollTaskStatus(ctx, client, taskID)
}
// poll task status
func pollTaskStatus(ctx context.Context, client *arkruntime.Client, taskID string) {
fmt.Println("----- polling task status -----")
for {
getReq := taskID
getResp, err := client.GetContentGenerationTask(ctx, getReq)
if err != nil {
fmt.Printf("get content generation task error: %v\n", err)
return
}
status := getResp.Status
if status == "succeeded" {
fmt.Println("----- task succeeded -----")
fmt.Printf("Task ID: %s \n", getResp.ID)
fmt.Printf("Model: %s \n", getResp.Model)
fmt.Printf("Video URL: %s \n", getResp.Content.Or(model.TaskContent{}).VideoURL.Or(""))
fmt.Printf("Completion Tokens: %d \n", getResp.Usage.Or(model.TaskUsage{}).CompletionTokens)
fmt.Printf("Created At: %d, Updated At: %d\n", getResp.CreatedAt.Or(0), getResp.UpdatedAt.Or(0))
return
} else if status == "failed" {
fmt.Println("----- task failed -----")
if getResp.Error.IsSet() {
fmt.Printf("Error Code: %s, Message: %s\n", getResp.Error.Value.Code, getResp.Error.Value.Message)
}
return
} else {
fmt.Printf("Current status: %s, Retrying in 10 seconds... \n", status)
time.Sleep(10 * time.Second)
}
}
}
编辑视频#
您可以提供待编辑的视频、参考图片或音频,并结合使用提示词,完成多种视频编辑任务,例如:替换视频主体、视频中对象增删改、局部画面重绘/修复等。
效果预览如下(访问 模型卡片 查看更多示例):
| 输入:文本 | 输入:视频&图片 | 输出 |
|---|---|---|
| 将视频1礼盒中的香水替换成图像1中的面霜,运镜不变 |
import os
import time
# Install SDK: python -m pip install --upgrade arkruntime
from arkruntime import Ark
client = Ark(
# The base URL for model invocation
base_url='https://ark.cn-beijing.volces.com/api/v3',
# Get API Key:https://ark.volcengine.com/region:cn-beijing/apikey
api_key=os.environ.get("ARK_API_KEY"),
)
if __name__ == "__main__":
print("----- create request -----")
create_result = client.content_generation.tasks.create(
model="doubao-seedance-2-0-260128", # Replace with Model ID
content=[
{
"type": "text",
"text": "将视频1礼盒中的香水替换成图片1中的面霜,运镜不变",
},
{
"type": "image_url",
"image_url": {
"url": "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/r2v_edit_pic1.jpg"
},
"role": "reference_image",
},
{
"type": "video_url",
"video_url": {
"url": "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_edit_video1.mp4"
},
"role": "reference_video",
},
],
generate_audio=True,
ratio="16:9",
duration=5,
watermark=True,
)
print(create_result)
# Polling query section
print("----- polling task status -----")
task_id = create_result.id
while True:
get_result = client.content_generation.tasks.get(task_id=task_id)
status = get_result.status
if status == "succeeded":
print("----- task succeeded -----")
print(get_result)
break
elif status == "failed":
print("----- task failed -----")
print(f"Error: {get_result.error}")
break
else:
print(f"Current status: {status}, Retrying after 30 seconds...")
time.sleep(30)
package com.ark.sample;
import com.volcengine.ark.runtime.models.content_generation.*;
import com.volcengine.ark.runtime.service.ArkService;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class ContentGenerationTaskExample {
// Client initialization
static String apiKey = System.getenv("ARK_API_KEY");
static ConnectionPool connectionPool = new ConnectionPool(5, 1, TimeUnit.SECONDS);
static Dispatcher dispatcher = new Dispatcher();
static ArkService service = ArkService.builder()
.baseUrl("https://ark.cn-beijing.volces.com/api/v3") // The base URL for model invocation
.dispatcher(dispatcher)
.connectionPool(connectionPool)
.apiKey(apiKey)
.build();
public static void main(String[] args) {
// Model ID
final String modelId = "doubao-seedance-2-0-260128";
// Text prompt
final String prompt = "将视频1礼盒中的香水替换成图片1中的面霜,运镜不变";
// Example resource URLs
final String refImage1 = "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/r2v_edit_pic1.jpg";
final String refVideo = "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_edit_video1.mp4";
// Output video parameters
final boolean generateAudio = true;
final String videoRatio = "16:9";
final long videoDuration = 5L;
final boolean showWatermark = true;
System.out.println("----- create request -----");
// Build request content
List<ContentItem> contents = new ArrayList<>();
// 1. Text prompt
contents.add(ContentItem.builder()
.type(ContentType.TEXT)
.text(prompt)
.build());
// 2. Reference image 1
contents.add(ContentItem.builder()
.type(ContentType.IMAGE_URL)
.imageUrl(ImageURL.builder()
.url(refImage1)
.build())
.role("reference_image")
.build());
// 3. Reference video
contents.add(ContentItem.builder()
.type(ContentType.VIDEO_URL)
.videoUrl(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();
CreateContentGenerationTaskResponse 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) {
String getRequest = taskId;
System.out.println("----- polling task status -----");
try {
while (true) {
ContentGenerationTask getResponse = service.getContentGenerationTask(getRequest);
String status = getResponse.getStatus().toString();
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();
}
}
}
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/volcengine/ark-runtime-go/arkruntime"
model "github.com/volcengine/ark-runtime-go/arkruntime/model/contentgeneration"
)
func main() {
// Initialize Ark client
client := arkruntime.NewClientWithApiKey(
os.Getenv("ARK_API_KEY"),
// The base URL for model invocation
arkruntime.WithBaseUrl("https://ark.cn-beijing.volces.com/api/v3"),
)
ctx := context.Background()
// Model ID
modelID := "doubao-seedance-2-0-260128"
// Text prompt
prompt := "将视频1礼盒中的香水替换成图片1中的面霜,运镜不变"
// Example resource URLs
refImage1 := "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/r2v_edit_pic1.jpg"
refVideo1 := "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_edit_video1.mp4"
// Output video parameters
generateAudio := true
videoRatio := "16:9"
videoDuration := int64(5)
showWatermark := true
// 1. Create video generation task
fmt.Println("----- create request -----")
createReq := &model.CreateContentGenerationTaskRequest{
Model: modelID,
GenerateAudio: model.NewOptBool(generateAudio),
Ratio: model.NewOptString(videoRatio),
Duration: model.NewOptInt64(videoDuration),
Watermark: model.NewOptBool(showWatermark),
Content: []model.ContentItem{
{
Type: model.ContentTypeText,
Text: model.NewOptString(prompt),
},
{
Type: model.ContentTypeImageURL,
ImageURL: model.NewOptImageURL(model.ImageURL{
URL: refImage1,
}),
Role: model.NewOptString("reference_image"),
},
{
Type: model.ContentTypeVideoURL,
VideoURL: model.NewOptVideoURL(model.VideoURL{
URL: refVideo1,
}),
Role: model.NewOptString("reference_video"),
},
},
}
createResp, err := client.CreateContentGenerationTask(ctx, createReq)
if err != nil {
fmt.Printf("create content generation error: %v\n", err)
return
}
taskID := createResp.ID
fmt.Printf("Task Created with ID: %s\n", taskID)
// 2. Poll task status
pollTaskStatus(ctx, client, taskID)
}
// poll task status
func pollTaskStatus(ctx context.Context, client *arkruntime.Client, taskID string) {
fmt.Println("----- polling task status -----")
for {
getReq := taskID
getResp, err := client.GetContentGenerationTask(ctx, getReq)
if err != nil {
fmt.Printf("get content generation task error: %v\n", err)
return
}
status := getResp.Status
if status == "succeeded" {
fmt.Println("----- task succeeded -----")
fmt.Printf("Task ID: %s \n", getResp.ID)
fmt.Printf("Model: %s \n", getResp.Model)
fmt.Printf("Video URL: %s \n", getResp.Content.Or(model.TaskContent{}).VideoURL.Or(""))
fmt.Printf("Completion Tokens: %d \n", getResp.Usage.Or(model.TaskUsage{}).CompletionTokens)
fmt.Printf("Created At: %d, Updated At: %d\n", getResp.CreatedAt.Or(0), getResp.UpdatedAt.Or(0))
return
} else if status == "failed" {
fmt.Println("----- task failed -----")
if getResp.Error.IsSet() {
fmt.Printf("Error Code: %s, Message: %s\n", getResp.Error.Value.Code, getResp.Error.Value.Message)
}
return
} else {
fmt.Printf("Current status: %s, Retrying in 10 seconds... \n", status)
time.Sleep(10 * time.Second)
}
}
}
延长视频#
在原有视频基础上,向前或者向后延长视频,或多个视频片段(最多 3 个视频片段)串联成一个连贯视频。
效果预览如下(访问 模型卡片 查看更多示例):
| 输入:文本 | 输入:待延长视频 | 输出 |
|---|---|---|
| 视频1中的拱形窗户打开,进入美术馆室内,接视频2,之后镜头进入画内,接视频3 |
import os
import time
# Install SDK: python -m pip install --upgrade arkruntime
from arkruntime import Ark
client = Ark(
# The base URL for model invocation
base_url='https://ark.cn-beijing.volces.com/api/v3',
# Get API Key:https://ark.volcengine.com/region:cn-beijing/apikey
api_key=os.environ.get("ARK_API_KEY"),
)
if __name__ == "__main__":
print("----- create request -----")
create_result = client.content_generation.tasks.create(
model="doubao-seedance-2-0-260128", # Replace with Model ID
content=[
{
"type": "text",
"text": "视频1中的拱形窗户打开,进入美术馆室内,接视频2,之后镜头进入画内,接视频3",
},
{
"type": "video_url",
"video_url": {
"url": "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_extend_video1.mp4"
},
"role": "reference_video",
},
{
"type": "video_url",
"video_url": {
"url": "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_extend_video2.mp4"
},
"role": "reference_video",
},
{
"type": "video_url",
"video_url": {
"url": "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_extend_video3.mp4"
},
"role": "reference_video",
},
],
generate_audio=True,
ratio="16:9",
duration=8,
watermark=True,
)
print(create_result)
# Polling query section
print("----- polling task status -----")
task_id = create_result.id
while True:
get_result = client.content_generation.tasks.get(task_id=task_id)
status = get_result.status
if status == "succeeded":
print("----- task succeeded -----")
print(get_result)
break
elif status == "failed":
print("----- task failed -----")
print(f"Error: {get_result.error}")
break
else:
print(f"Current status: {status}, Retrying after 30 seconds...")
time.sleep(30)
package com.ark.sample;
import com.volcengine.ark.runtime.models.content_generation.*;
import com.volcengine.ark.runtime.service.ArkService;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class ContentGenerationTaskExample {
// Client initialization
static String apiKey = System.getenv("ARK_API_KEY");
static ConnectionPool connectionPool = new ConnectionPool(5, 1, TimeUnit.SECONDS);
static Dispatcher dispatcher = new Dispatcher();
static ArkService service = ArkService.builder()
.baseUrl("https://ark.cn-beijing.volces.com/api/v3") // The base URL for model invocation
.dispatcher(dispatcher)
.connectionPool(connectionPool)
.apiKey(apiKey)
.build();
public static void main(String[] args) {
// Model ID
final String modelId = "doubao-seedance-2-0-260128";
// Text prompt
final String prompt = "视频1中的拱形窗户打开,进入美术馆室内,接视频2,之后镜头进入画内,接视频3";
// Example resource URLs
final String refVideo1 = "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_extend_video1.mp4";
final String refVideo2 = "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_extend_video2.mp4";
final String refVideo3 = "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_extend_video3.mp4";
// Output video parameters
final boolean generateAudio = true;
final String videoRatio = "16:9";
final long videoDuration = 8L;
final boolean showWatermark = true;
System.out.println("----- create request -----");
// Build request content
List<ContentItem> contents = new ArrayList<>();
// 1. Text prompt
contents.add(ContentItem.builder()
.type(ContentType.TEXT)
.text(prompt)
.build());
// 2. Reference video 1
contents.add(ContentItem.builder()
.type(ContentType.VIDEO_URL)
.videoUrl(VideoURL.builder()
.url(refVideo1)
.build())
.role("reference_video")
.build());
// 3. Reference video 2
contents.add(ContentItem.builder()
.type(ContentType.VIDEO_URL)
.videoUrl(VideoURL.builder()
.url(refVideo2)
.build())
.role("reference_video")
.build());
// 4. Reference video 3
contents.add(ContentItem.builder()
.type(ContentType.VIDEO_URL)
.videoUrl(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();
CreateContentGenerationTaskResponse 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) {
String getRequest = taskId;
System.out.println("----- polling task status -----");
try {
while (true) {
ContentGenerationTask getResponse = service.getContentGenerationTask(getRequest);
String status = getResponse.getStatus().toString();
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();
}
}
}
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/volcengine/ark-runtime-go/arkruntime"
model "github.com/volcengine/ark-runtime-go/arkruntime/model/contentgeneration"
)
func main() {
// Initialize Ark client
client := arkruntime.NewClientWithApiKey(
os.Getenv("ARK_API_KEY"),
// The base URL for model invocation
arkruntime.WithBaseUrl("https://ark.cn-beijing.volces.com/api/v3"),
)
ctx := context.Background()
// Model ID
modelID := "doubao-seedance-2-0-260128"
// Text prompt
prompt := "视频1中的拱形窗户打开,进入美术馆室内,接视频2,之后镜头进入画内,接视频3"
// Example resource URLs
refVideo1 := "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_extend_video1.mp4"
refVideo2 := "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_extend_video2.mp4"
refVideo3 := "https://arkdocs.tos-cn-beijing.volces.com/videos/video-generation/r2v_extend_video3.mp4"
// Output video parameters
generateAudio := true
videoRatio := "16:9"
videoDuration := int64(8)
showWatermark := true
// 1. Create video generation task
fmt.Println("----- create request -----")
createReq := &model.CreateContentGenerationTaskRequest{
Model: modelID,
GenerateAudio: model.NewOptBool(generateAudio),
Ratio: model.NewOptString(videoRatio),
Duration: model.NewOptInt64(videoDuration),
Watermark: model.NewOptBool(showWatermark),
Content: []model.ContentItem{
{
Type: model.ContentTypeText,
Text: model.NewOptString(prompt),
},
{
Type: model.ContentTypeVideoURL,
VideoURL: model.NewOptVideoURL(model.VideoURL{
URL: refVideo1,
}),
Role: model.NewOptString("reference_video"),
},
{
Type: model.ContentTypeVideoURL,
VideoURL: model.NewOptVideoURL(model.VideoURL{
URL: refVideo2,
}),
Role: model.NewOptString("reference_video"),
},
{
Type: model.ContentTypeVideoURL,
VideoURL: model.NewOptVideoURL(model.VideoURL{
URL: refVideo3,
}),
Role: model.NewOptString("reference_video"),
},
},
}
createResp, err := client.CreateContentGenerationTask(ctx, createReq)
if err != nil {
fmt.Printf("create content generation error: %v\n", err)
return
}
taskID := createResp.ID
fmt.Printf("Task Created with ID: %s\n", taskID)
// 2. Poll task status
pollTaskStatus(ctx, client, taskID)
}
// poll task status
func pollTaskStatus(ctx context.Context, client *arkruntime.Client, taskID string) {
fmt.Println("----- polling task status -----")
for {
getReq := taskID
getResp, err := client.GetContentGenerationTask(ctx, getReq)
if err != nil {
fmt.Printf("get content generation task error: %v\n", err)
return
}
status := getResp.Status
if status == "succeeded" {
fmt.Println("----- task succeeded -----")
fmt.Printf("Task ID: %s \n", getResp.ID)
fmt.Printf("Model: %s \n", getResp.Model)
fmt.Printf("Video URL: %s \n", getResp.Content.Or(model.TaskContent{}).VideoURL.Or(""))
fmt.Printf("Completion Tokens: %d \n", getResp.Usage.Or(model.TaskUsage{}).CompletionTokens)
fmt.Printf("Created At: %d, Updated At: %d\n", getResp.CreatedAt.Or(0), getResp.UpdatedAt.Or(0))
return
} else if status == "failed" {
fmt.Println("----- task failed -----")
if getResp.Error.IsSet() {
fmt.Printf("Error Code: %s, Message: %s\n", getResp.Error.Value.Code, getResp.Error.Value.Message)
}
return
} else {
fmt.Printf("Current status: %s, Retrying in 10 seconds... \n", status)
time.Sleep(10 * time.Second)
}
}
}
输出 4k 视频#
仅 Seedance 2.0 支持
Seedance 2.0 支持输出 4k 视频,并采用 10bit 位深编码,能够完整保留丰富的色彩层次与平滑的渐变过渡,满足专业影视制作与 HDR 视频内容的要求。
| 效果预览1 | 效果预览2 |
|---|---|
注:效果展示视频由 Seedance 2.0 生成的多个分镜拼接而成,非下述示例代码直接生成。
import os
import time
# Install SDK: python -m pip install --upgrade arkruntime
from arkruntime import Ark
client = Ark(
# The base URL for model invocation
base_url='https://ark.cn-beijing.volces.com/api/v3',
# Get API Key:https://ark.volcengine.com/region:cn-beijing/apikey
api_key=os.environ.get("ARK_API_KEY"),
)
if __name__ == "__main__":
print("----- create request -----")
create_result = client.content_generation.tasks.create(
model="doubao-seedance-2-0-260128",
content=[
{
"type": "text",
"text": "生成一段15秒的越野摩托竞技广告感短片。参考图片作为中段飞跃高潮的参考。镜头逻辑依次为:1)中景跟拍,车手从远处沿土坡高速逼近跳台;2)超近低机位后轮飞砂特写,轮胎抓地甩出大量泥土和砂石;3)中近景展示骑手控车、手部发力、悬挂压缩与机械震动;4)侧向英雄中景拍车手冲坡腾空飞跃,画面状态接近图一,泥土在逆光中大面积飞散;5)腾空近景帅气细节,突出头盔护目镜、手部控把、轮胎悬空或车身侧面局部;6)中景跟拍落地,悬挂压缩回弹,随后继续沿土坡赛道高速冲刺收尾。全片同一名骑手、同一辆车、同一条赛道,镜头景别和角度区分清楚,不重复,动作连贯,画面有真实越野跟拍抖动感、速度感、扬土感和夕阳逆光竞技氛围。",
},
{
"type": "image_url",
"image_url": {
"url": "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/i2v_4k.png"
},
"role": "reference_image",
},
],
generate_audio=True,
resolution="4k",
ratio="adaptive",
duration=15,
watermark=True,
)
print(create_result)
# Polling query section
print("----- polling task status -----")
task_id = create_result.id
while True:
get_result = client.content_generation.tasks.get(task_id=task_id)
status = get_result.status
if status == "succeeded":
print("----- task succeeded -----")
print(get_result)
break
elif status == "failed":
print("----- task failed -----")
print(f"Error: {get_result.error}")
break
else:
print(f"Current status: {status}, Retrying after 30 seconds...")
time.sleep(30)
package com.ark.sample;
import com.volcengine.ark.runtime.models.content_generation.*;
import com.volcengine.ark.runtime.service.ArkService;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class ContentGenerationTaskExample {
// Client initialization
static String apiKey = System.getenv("ARK_API_KEY");
static ConnectionPool connectionPool = new ConnectionPool(5, 1, TimeUnit.SECONDS);
static Dispatcher dispatcher = new Dispatcher();
static ArkService service = ArkService.builder()
.baseUrl("https://ark.cn-beijing.volces.com/api/v3")
// The base URL for model invocation
.dispatcher(dispatcher)
.connectionPool(connectionPool)
.apiKey(apiKey)
.build();
public static void main(String[] args) {
// Model ID
final String modelId = "doubao-seedance-2-0-260128";
// Text prompt
final String prompt = "生成一段15秒的越野摩托竞技广告感短片。参考图片作为中段飞跃高潮的参考。" +
"镜头逻辑依次为:1)中景跟拍,车手从远处沿土坡高速逼近跳台;" +
"2)超近低机位后轮飞砂特写,轮胎抓地甩出大量泥土和砂石;" +
"3)中近景展示骑手控车、手部发力、悬挂压缩与机械震动;" +
"4)侧向英雄中景拍车手冲坡腾空飞跃,画面状态接近图一,泥土在逆光中大面积飞散;" +
"5)腾空近景帅气细节,突出头盔护目镜、手部控把、轮胎悬空或车身侧面局部;" +
"6)中景跟拍落地,悬挂压缩回弹,随后继续沿土坡赛道高速冲刺收尾。" +
"全片同一名骑手、同一辆车、同一条赛道,镜头景别和角度区分清楚,不重复,动作连贯,画面有真实越野跟拍抖动感、速度感、扬土感和夕阳逆光竞技氛围。";
// Example resource URLs
final String refImage = "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/i2v_4k.png";
// Output video parameters
final boolean generateAudio = true;
final String videoResolution = "4k";
final String videoRatio = "adaptive";
final long videoDuration = 15L;
final boolean showWatermark = true;
System.out.println("----- create request -----");
// Build request content
List<ContentItem> contents = new ArrayList<>();
// 1. Text prompt
contents.add(ContentItem.builder()
.type(ContentType.TEXT)
.text(prompt)
.build());
// 2. Reference image
contents.add(ContentItem.builder()
.type(ContentType.IMAGE_URL)
.imageUrl(ImageURL.builder()
.url(refImage)
.build())
.role("reference_image")
.build());
// Create video generation task
CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder()
.generateAudio(generateAudio)
.model(modelId)
.content(contents)
.resolution(videoResolution)
.ratio(videoRatio)
.duration(videoDuration)
.watermark(showWatermark)
.build();
CreateContentGenerationTaskResponse 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) {
String getRequest = taskId;
System.out.println("----- polling task status -----");
try {
while (true) {
ContentGenerationTask getResponse = service.getContentGenerationTask(getRequest);
String status = getResponse.getStatus().toString();
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();
}
}
}
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/volcengine/ark-runtime-go/arkruntime"
model "github.com/volcengine/ark-runtime-go/arkruntime/model/contentgeneration"
)
func main() {
// Initialize Ark client
client := arkruntime.NewClientWithApiKey(
os.Getenv("ARK_API_KEY"),
// The base URL for model invocation
arkruntime.WithBaseUrl("https://ark.cn-beijing.volces.com/api/v3"),
)
ctx := context.Background()
// Model ID
modelID := "doubao-seedance-2-0-260128"
// Text prompt
prompt := "生成一段15秒的越野摩托竞技广告感短片。参考图片作为中段飞跃高潮的参考。" +
"镜头逻辑依次为:1)中景跟拍,车手从远处沿土坡高速逼近跳台;" +
"2)超近低机位后轮飞砂特写,轮胎抓地甩出大量泥土和砂石;" +
"3)中近景展示骑手控车、手部发力、悬挂压缩与机械震动;" +
"4)侧向英雄中景拍车手冲坡腾空飞跃,画面状态接近图一,泥土在逆光中大面积飞散;" +
"5)腾空近景帅气细节,突出头盔护目镜、手部控把、轮胎悬空或车身侧面局部;" +
"6)中景跟拍落地,悬挂压缩回弹,随后继续沿土坡赛道高速冲刺收尾。" +
"全片同一名骑手、同一辆车、同一条赛道,镜头景别和角度区分清楚,不重复,动作连贯,画面有真实越野跟拍抖动感、速度感、扬土感和夕阳逆光竞技氛围。"
// Example resource URLs
refImage := "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/i2v_4k.png"
// Output video parameters
generateAudio := true
videoResolution := "4k"
videoRatio := "adaptive"
videoDuration := int64(15)
showWatermark := true
// 1. Create video generation task
fmt.Println("----- create request -----")
createReq := &model.CreateContentGenerationTaskRequest{
Model: modelID,
GenerateAudio: model.NewOptBool(generateAudio),
Resolution: model.NewOptString(videoResolution),
Ratio: model.NewOptString(videoRatio),
Duration: model.NewOptInt64(videoDuration),
Watermark: model.NewOptBool(showWatermark),
Content: []model.ContentItem{
{
Type: model.ContentTypeText,
Text: model.NewOptString(prompt),
},
{
Type: model.ContentTypeImageURL,
ImageURL: model.NewOptImageURL(model.ImageURL{
URL: refImage,
}),
Role: model.NewOptString("reference_image"),
},
},
}
createResp, err := client.CreateContentGenerationTask(ctx, createReq)
if err != nil {
fmt.Printf("create content generation error: %v\n", err)
return
}
taskID := createResp.ID
fmt.Printf("Task Created with ID: %s\n", taskID)
// 2. Poll task status
pollTaskStatus(ctx, client, taskID)
}
// poll task status
func pollTaskStatus(ctx context.Context, client *arkruntime.Client, taskID string) {
fmt.Println("----- polling task status -----")
for {
getReq := taskID
getResp, err := client.GetContentGenerationTask(ctx, getReq)
if err != nil {
fmt.Printf("get content generation task error: %v\n", err)
return
}
status := getResp.Status
if status == "succeeded" {
fmt.Println("----- task succeeded -----")
fmt.Printf("Task ID: %s \n", getResp.ID)
fmt.Printf("Model: %s \n", getResp.Model)
fmt.Printf("Video URL: %s \n", getResp.Content.Or(model.TaskContent{}).VideoURL.Or(""))
fmt.Printf("Completion Tokens: %d \n", getResp.Usage.Or(model.TaskUsage{}).CompletionTokens)
fmt.Printf("Created At: %d, Updated At: %d\n", getResp.CreatedAt.Or(0), getResp.UpdatedAt.Or(0))
return
} else if status == "failed" {
fmt.Println("----- task failed -----")
if getResp.Error.IsSet() {
fmt.Printf("Error Code: %s, Message: %s\n", getResp.Error.Value.Code, getResp.Error.Value.Message)
}
return
} else {
fmt.Printf("Current status: %s, Retrying in 10 seconds... \n", status)
time.Sleep(10 * time.Second)
}
}
}
使用联网搜索#
联网搜索能力仅适用于纯文本输入
通过配置 tools.type 参数为web_search即可使用联网搜索工具。
- 开启联网搜索后,模型会根据用户的提示词自主判断是否搜索互联网内容(如商品、天气等)。可提升生成视频的时效性,但也会增加一定的时延。
- 实际搜索次数可通过 查询视频生成任务 API 返回的 usage.tool_usage.web_search 字段获取,如果为 0 表示未搜索。
| 输入:文本 | 输出 |
|---|---|
| 微距镜头对准叶片上翠绿的玻璃蛙。焦点逐渐从它光滑的皮肤,转移到它完全透明的腹部,一颗鲜红的心脏正在有力地、规律地收缩扩张。 说明联网搜索玻璃蛙的容貌特征。 |
import os
import time
# Install SDK: python -m pip install --upgrade arkruntime
from arkruntime import Ark
# Make sure that you have stored the API Key in the environment variable ARK_API_KEY
# Initialize the Ark client to read your API Key from an environment variable
client = Ark(
# This is the default path. You can configure it based on the service location
base_url="https://ark.cn-beijing.volces.com/api/v3",
# Get API Key:https://ark.volcengine.com/region:cn-beijing/apikey
api_key=os.environ.get("ARK_API_KEY"),
)
if __name__ == "__main__":
print("----- create request -----")
create_result = client.content_generation.tasks.create(
model="doubao-seedance-2-0-260128", # Replace with Model ID
content=[
{
# text prompt
"type": "text",
"text": "微距镜头对准叶片上翠绿的玻璃蛙。焦点逐渐从它光滑的皮肤,转移到它完全透明的腹部,一颗鲜红的心脏正在有力地、规律地收缩扩张。"
}
],
generate_audio=True,
ratio="16:9",
duration=11,
watermark=True,
tools=[{"type": "web_search"}],
)
print(create_result)
# Polling query section
print("----- polling task status -----")
task_id = create_result.id
while True:
get_result = client.content_generation.tasks.get(task_id=task_id)
status = get_result.status
if status == "succeeded":
print("----- task succeeded -----")
print(get_result)
break
elif status == "failed":
print("----- task failed -----")
print(f"Error: {get_result.error}")
break
else:
print(f"Current status: {status}, Retrying after 10 seconds...")
time.sleep(10)
package com.ark.sample;
import com.volcengine.ark.runtime.models.content_generation.*;
import com.volcengine.ark.runtime.service.ArkService;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.Collections;
public class ContentGenerationTaskExample {
// Make sure that you have stored the API Key in the environment variable ARK_API_KEY
// Initialize the Ark client to read your API Key from an environment variable
static String apiKey = System.getenv("ARK_API_KEY");
static ConnectionPool connectionPool = new ConnectionPool(5, 1, TimeUnit.SECONDS);
static Dispatcher dispatcher = new Dispatcher();
static ArkService service = ArkService.builder()
.baseUrl("https://ark.cn-beijing.volces.com/api/v3")
// The base URL for model invocation
.dispatcher(dispatcher)
.connectionPool(connectionPool)
.apiKey(apiKey)
.build();
public static void main(String[] args) {
String model = "doubao-seedance-2-0-260128"; // Replace with Model ID
String prompt = "微距镜头对准叶片上翠绿的玻璃蛙。焦点逐渐从它光滑的皮肤,转移到它完全透明的腹部,一颗鲜红的心脏正在有力地、规律地收缩扩张。";
Boolean generateAudio = true;
String videoRatio = "16:9";
Long videoDuration = 11L;
Boolean showWatermark = true;
// Create ContentGenerationTool
Tool webSearchTool = Tool.builder().type(ToolType.WEB_SEARCH).build();
System.out.println("----- create request -----");
List<ContentItem> contents = new ArrayList<>();
// text prompt
contents.add(ContentItem.builder()
.type(ContentType.TEXT)
.text(prompt)
.build());
// Create a video generation task
CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder()
.model(model)
.content(contents)
.generateAudio(generateAudio)
.ratio(videoRatio)
.duration(videoDuration)
.watermark(showWatermark)
.tools(Collections.singletonList(webSearchTool))
.build();
CreateContentGenerationTaskResponse createResult = service.createContentGenerationTask(createRequest);
System.out.println(createResult);
// Get the details of the task
String taskId = createResult.getId();
String getRequest = taskId;
// Polling query section
System.out.println("----- polling task status -----");
while (true) {
try {
ContentGenerationTask getResponse = service.getContentGenerationTask(getRequest);
String status = getResponse.getStatus().toString();
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;
}
}
}
}
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/volcengine/ark-runtime-go/arkruntime"
model "github.com/volcengine/ark-runtime-go/arkruntime/model/contentgeneration"
)
func main() {
// Make sure that you have stored the API Key in the environment variable ARK_API_KEY
// Initialize the Ark client to read your API Key from an environment variable
client := arkruntime.NewClientWithApiKey(
// Get your API Key from the environment variable. This is the default mode and you can modify it as required
os.Getenv("ARK_API_KEY"),
// The base URL for model invocation
arkruntime.WithBaseUrl("https://ark.cn-beijing.volces.com/api/v3"),
)
ctx := context.Background()
// Model ID
modelID := "doubao-seedance-2-0-260128"
// Text prompt
prompt := "微距镜头对准叶片上翠绿的玻璃蛙。焦点逐渐从它光滑的皮肤,转移到它完全透明的腹部,一颗鲜红的心脏正在有力地、规律地收缩扩张。"
// Output video parameters
generateAudio := true
videoRatio := "16:9"
videoDuration := int64(11)
showWatermark := true
// Create ContentGenerationTool
tools := []model.Tool{
{Type: model.ToolTypeWebSearch},
}
// Generate a task
fmt.Println("----- create request -----")
createReq := &model.CreateContentGenerationTaskRequest{
Model: modelID,
GenerateAudio: model.NewOptBool(generateAudio),
Ratio: model.NewOptString(videoRatio),
Duration: model.NewOptInt64(videoDuration),
Watermark: model.NewOptBool(showWatermark),
Tools: tools,
Content: []model.ContentItem{
{
// Combination of text prompt and parameters
Type: model.ContentTypeText,
Text: model.NewOptString(prompt),
},
},
}
createResp, err := client.CreateContentGenerationTask(ctx, createReq)
if err != nil {
fmt.Printf("create content generation error: %v\n", err)
return
}
taskID := createResp.ID
fmt.Printf("Task Created with ID: %s\n", taskID)
// 2. Poll task status
pollTaskStatus(ctx, client, taskID)
}
// poll task status
func pollTaskStatus(ctx context.Context, client *arkruntime.Client, taskID string) {
fmt.Println("----- polling task status -----")
for {
getReq := taskID
getResp, err := client.GetContentGenerationTask(ctx, getReq)
if err != nil {
fmt.Printf("get content generation task error: %v\n", err)
return
}
status := getResp.Status
if status == "succeeded" {
fmt.Println("----- task succeeded -----")
fmt.Printf("Task ID: %s \n", getResp.ID)
fmt.Printf("Model: %s \n", getResp.Model)
fmt.Printf("Video URL: %s \n", getResp.Content.Or(model.TaskContent{}).VideoURL.Or(""))
fmt.Printf("Completion Tokens: %d \n", getResp.Usage.Or(model.TaskUsage{}).CompletionTokens)
fmt.Printf("Created At: %d, Updated At: %d\n", getResp.CreatedAt.Or(0), getResp.UpdatedAt.Or(0))
return
} else if status == "failed" {
fmt.Println("----- task failed -----")
if getResp.Error.IsSet() {
fmt.Printf("Error Code: %s, Message: %s\n", getResp.Error.Value.Code, getResp.Error.Value.Message)
}
return
} else {
fmt.Printf("Current status: %s, Retrying in 10 seconds... \n", status)
time.Sleep(10 * time.Second)
}
}
}
更多能力#
Seedance 2.0 系列模型也支持文生视频、首帧图生视频、首尾帧图生视频、自定义视频输出规格(包括:分辨率、宽高比、视频时长、视频中是否包含水印)等通用基础能力,详情请参见 视频生成教程。
便利创作#
Seedance 2.0 系列模型不支持直接上传含有真人人脸的参考图/视频。为便利创作者使用肖像,平台推出了以下解决方案,详细教程请参见 Doubao Seedance 便利创作含肖像视频:
| 方案 | 介绍 |
|---|---|
| 信任模型产物作为输入素材 | 本账号下部分模型生成的含人脸原始产物可作为输入素材,再次调用 Seedance 2.0 系列模型进行二次创作,不会触发输入审核拦截。 |
| 使用预置虚拟人像 | 平台预置虚拟人像库,为创作者提供免费、合规、丰富多样的肖像素材。适用于需真人风格人脸但无需指定具体人物,追求零合规风险、快速创作的场景。 |
| 使用已授权真人素材 | 支持使用已获得授权的真人肖像素材进行视频生成。 |
提示词技巧#
提示词 Skill#
平台提供 Seedance 2.0 提示词优化技能,方便您对提示词进行调优。
-
配置方式:推荐在本地项目中运行以下命令,通过方舟文档 Skills catalog 安装
sd2-pe:npx --yes skills@latest add "https://arkdocs.tos-cn-beijing.volces.com/skills/" \ --skill sd2-pe \ --yes如需手动安装,可以下载以下
SKILL.md文件。以 OpenClaw 为例,将文件完整内容复制到对话输入框中,并发送“请帮我安装这个技能”,等待工具完成安装。 -
使用方式:在 AI 对话框输入
/sd2-pe + 你的提示词内容,开始调试提示词。
提示词规则#
- 提示词中必须使用"素材类型+序号”格式引用素材,序号为请求体中该素材在同类素材中的排序。例如 「图片 n」指代
content数组中第 n 个type="image_url"的参考图片(按数组顺序从1开始计数)。注意不支持使用 Asset ID 指代素材。 - 不同任务的提示词公式及详细规则请参见 Doubao Seedance 2.0 系列提示词指南。
使用限制#
参见 使用限制。
常见问题#
10bit 位深与 H.265/HEVC 编码视频播放兼容性说明#
以下为各平台浏览器及播放器对 10bit 位深与 H.265/HEVC 编码视频的播放兼容性测试结论,实际效果可能因设备配置有所差异。
推荐使用:
- macOS 端:浏览器推荐 Safari、Chrome,播放器推荐 VLC、mpv、QuickTime Player
- Windows 端:浏览器推荐 Edge、Chrome,播放器推荐 VLC、mpv
Windows 平台#
| 浏览器 | 支持情况 |
|---|---|
| Chrome | 有条件支持 |
| Edge | 有条件支持 |
| Firefox | 有条件支持 |
| 360 浏览器 | 有条件支持 |
| QQ 浏览器 | 有条件支持 |
| Opera | 有条件支持 |
| 播放器 | 支持情况 |
|---|---|
| VLC | 支持 |
| 系统「电影和电视」 | 有条件支持 |
| PotPlayer | 有条件支持 |
| 迅雷影音 | 支持 |
| QQ 影音 | 有条件支持 |
| MPC-HC / MPC-BE | 有条件支持 |
| mpv | 支持 |
| KMPlayer | 支持 |
有条件支持说明:需具备较高的硬件解码能力。已知在 Intel i7 + NVIDIA RTX 4070 + Windows 11 及更高配置下可正常播放,其他配置建议以实际测试为准。
macOS 平台#
| 浏览器 | 支持情况 |
|---|---|
| Safari | 支持 |
| Chrome | 有条件支持 |
| Edge | 有条件支持 |
| Firefox | 有条件支持 |
| Opera | 有条件支持 |
| 播放器 | 支持情况 |
|---|---|
| VLC | 支持 |
| QuickTime Player | 支持 |
| IINA | 支持 |
| mpv | 支持 |
| Infuse | 支持 |
| Kodi | 有条件支持 |
有条件支持说明:需具备较高的硬件解码能力。已知 Apple M2 及以上机型可正常播放,M1 及以下机型建议以实际测试为准。
视频画面存在跳变#
典型现象
首帧图生视频、首尾帧图生视频场景中,生成视频部分帧出现画面拉伸、压缩等跳变问题。
根因分析
输入图片与输出视频的分辨率宽高不一致,引发视频画面帧间跳变。
解决方案
- 裁剪输入图片:参考 Seedance 2.0 系列模型支持的宽高像素值表格(见 创建视频生成任务 API ratio 字段),将输入图片裁剪为目标宽高像素值。
- 将 API 的 ratio 字段设置为
adaptive。 - 使用 Seedance 2.0 系列模型重新发起首帧/首尾帧图生视频任务。