从写代码,到创作下一幕

探索 字节跳动 - 火山方舟 的 AI 编程与视频创作活动。

火山方舟 Agent Plan 与 Coding Plan 活动,价格 ¥9.9 起

Agent Plan & Coding Plan

一站体验多款热门模型,为 AI 编程与智能体开发提供更多选择。新用户可联系(微信: goo_lvyouyou)免费体验 9.9 agent plan。

查看套餐优惠
Seedance 2.5 视频创作活动:30 秒视频、多模态参考、局部编辑

Seedance 2.5

让创意,跃然成片。探索 30 秒视频、多模态参考与局部编辑,把脑海中的画面变成下一支作品。

探索视频创作

让照片里的角色开口说话

查看 Markdown

本示例使用 Grok Imagine 将角色图片制作成会说话的视频。你将看到如何在一个视频提示词中引用多张图片和多种声音,让两个角色在同一段视频中对话。

提供一张角色图片,例如绘画、吉祥物或宠物照片,选择一种内置声音,再写一句台词。Grok Imagine 会生成一段短视频,让角色用指定声音说出这句话。加入第二个角色后,它会在同一段视频中用自己的声音回应。示例中的网页应用会在你编写时展示请求,并在视频完成后播放。

你将学到什么

  • 在同一视频提示词中引用多张图片和多种声音,使用 <IMAGE_0>、<IMAGE_1>、<AUDIO_0>,<AUDIO_1> 标签

  • 为每个角色指定预设声音,将其 voice_id 填入 reference_audios

  • 使用 client.voice.list() 列出声音,并通过 client.voice.speak() 试听,再决定是否付费生成视频

  • 查询视频任务,使用 client.videos.get() 显示当前进度

  • 通过服务器发送事件(SSE)将进度从 Node 服务器流式传送到网页

运行示例

需要 Node.js 22.13 或更高版本。将 API 密钥放入 .env(位于仓库根目录),或导出环境变量 XAI_API_KEY。

Bash

cd examples/photo-to-talking-character/typescript
npm install
npm run web

打开 http://localhost:3000,点击 Try the dog and the cat,或添加自己的图片,选择声音并写一句台词。然后点击 Make it talk。这个页面就像一个小型动画工作室。左侧每个角色都有图片、台词,以及能用所选声音朗读台词的播放按钮。舞台上的角色旁会用气泡显示台词;舞台下方展示即将发出的请求,每个标签旁边都标出对应的图片或声音。渲染期间,舞台会显示进度,完成后播放视频。点击 Add a character who answers 可添加第二个角色。点击 Stop 仅停止等待。API 不支持取消已启动的视频任务,因此仍会完成渲染并计费。

如需在终端中生成视频,请为每个角色传入图片、声音和台词。使用 voices 可列出声音:

Bash

npm start -- ./your-drawing.png eve "Hello! Somebody finally drew me a mouth."
npm start -- ./dog.png rex "Want to play?" ./cat.png luna "No."
npm start -- voices

不传参数时使用示例图片:一幅小狗的画 sample-dog.jpg 使用 Rex 的声音发言,一幅小猫的画 sample-cat.jpg 则用 Luna 的声音回答。两张图片均使用 grok-imagine-image-2.0 绘制。网页和终端两种版本均将视频保存到 output/<the first line>/scene.mp4,生成视频所用的提示词保存在旁边的 scene.json。

每次运行生成一段 5 至 15 秒的视频,时长取决于台词长度。运行约需一分钟,几乎都用在渲染上。我们测试时,示例生成 10 秒视频的费用为 $1.42;一句台词生成的 5 秒视频为 $0.71,相当于每秒约 14 美分。试听一段声音不足一美分。完成后,网页和终端都会显示视频费用。

工作原理

共享代码位于 src/scene.ts:

  1. writePrompt() 为整个场景编写一个提示词。每个标签都按列表位置引用输入:<IMAGE_0> 指向第一张图片,图片列表为 reference_images,<AUDIO_0> 指向第一个声音,声音列表为 reference_audios。因此,第一个角色来自 <IMAGE_0>,声音来自 <AUDIO_0>,第二个角色来自 <IMAGE_1>,声音来自 <AUDIO_1>。提示词用引号标出每句台词,按顺序列出,并要求不添加其他对白或音乐。

  2. makeScene() 启动视频生成,调用的是 client.videos.generate()。reference_images 接收的图片类型为 Blob,SDK 会将图片作为数据 URL 发送;reference_audios 为每个角色接收一个 { voice_id },最多支持三个角色。sceneLength() 根据台词的词数确定时长,因为每秒都会计费。参考图生视频最高支持 720p。

  3. waitForVideo() 查询视频状态,所用方法为 client.videos.get(),每三秒一次,并报告返回的 progress 百分比。client.videos.wait() 可以代为轮询,但不报告进度。视频 URL 是临时的,因此 makeScene() 会立即下载视频。

  4. listVoices() 列出可选声音,使用的是 client.voice.list(),previewVoice() 则选取其中一种声音朗读台词,调用的是 client.voice.speak()。

关于视频中的声音,需要注意:

  • 只有内置声音对所有用户开放。可信合作伙伴可申请使用自己的录音,办法是将录音作为 url 填入 reference_audios。

  • client.voice.list() 返回 28 种声音,但视频模型不支持其中的 aurora 和 liora,因此 listVoices() 会将这两种声音排除。使用不支持的声音会收到 400 错误,错误信息会列出支持的声音。

  • 试听通过文本转语音朗读台词。在视频中,角色用所选声音演绎台词,节奏由视频中的表演决定。

src/server.ts 是一个小型 node:http 服务器。EventSource 只能发送 GET 请求,因此页面先将每张图片上传到 /api/pictures,再打开 /api/scene,传入图片 ID、声音和台词。服务器运行 makeScene(),将进度以 SSE 发送到网页,并以字节范围提供保存的视频,方便浏览器跳播。/api/voices 列出声音,而 /api/preview 会用所选声音说一句台词。服务器会保存每个试听片段,重播不再计费。/api/prompt 返回 writePrompt() 根据当前台词编写的提示词,供页面在发送前展示请求。每个 API 调用均接收一个 AbortSignal,当页面关闭请求时触发。点击 Stop 也会关闭请求。

public/index.html 使用原生 HTML 和 JavaScript 展示这些事件并播放视频。src/index.ts 则在终端中完成相同的工作。