Khóa học
Trong tutorial này, tôi sẽ trình diễn cách dùng BytePlus Ark API để tương tác với Seedance 2 bằng Python.
Seedance 2 là một mô hình AI tạo sinh mạnh mẽ của ByteDance hoạt động như một “đạo diễn đa phương thức,” có khả năng xử lý đồng thời đầu vào văn bản, hình ảnh, video và âm thanh để tạo ra chuỗi video mang tính điện ảnh với âm thanh đồng bộ. Dù bạn muốn làm động các hình ảnh tĩnh hay hiện thực hóa các gợi ý văn bản phức tạp, hướng dẫn này sẽ đưa bạn qua phần cài đặt và triển khai.
Tạo khóa API Seedance 2
Để bắt đầu, chúng ta cần tạo tài khoản BytePlus và một khóa API. Thực hiện như sau:
- Truy cập trang web chính thức của BytePlus và tạo tài khoản.
- Vào trang tạo API key và nhấp “Create API Key”.
Khóa này được dùng để gửi yêu cầu tới ModelArk API, API chính thức của họ.
Cách tốt nhất là lưu khóa trong tệp tên .env trong cùng thư mục với các script Python. Hãy giữ bí mật khóa vì bất kỳ ai cũng có thể dùng nó để tương tác với API bằng tài khoản của bạn.
Dán API key vào tệp .env theo định dạng sau:
ARK_API_KEY=<paste_api_key_here>
Kích hoạt mô hình Seedance 2 và cấu trúc giá
Để sử dụng Seedance 2, trước tiên chúng ta cần kích hoạt mô hình:

Lưu ý rằng dùng API không miễn phí và kích hoạt Seedance 2 yêu cầu mua credit cho mô hình. Trong bài này, tôi đã mua gói token 7 triệu token cho Seedance 2 với giá $30,10.

Đáng tiếc là token gắn với từng mô hình cụ thể. Nghĩa là nếu mua token cho phiên bản fast hoặc mini của Seedance 2, chúng ta không thể dùng chúng với mô hình nền tảng (base).
Dưới đây là bảng các gói giá cho API:

Cách tạo video với Seedance 2 API bằng Python
Tôi đã đưa đầy đủ các script tương ứng với mã trong tutorial này vào kho GitHub này.
Trong phần này, chúng ta học cách gửi yêu cầu text-to-video để tạo video này:
1. Thiết lập môi trường Python và SDK
Để kết nối với BytePlus Ark API bằng Python, chúng ta sẽ dùng gói chính thức byteplus-python-sdk-v2.
Cách đơn giản để thiết lập phụ thuộc cho dự án là tạo môi trường Anaconda và cài đặt tệp requirements.txt như sau:
git clone git@github.com:fran-aubry/seedance2-tutorial.git
conda create --name seedance2 python=3.11
conda activate seedance2
pip install -r requirements.txt
2. Khởi tạo client Python của BytePlus Ark
Tạo script mới tên text_to_video.py trong cùng thư mục với tệp .env đã tạo trước đó.
Đầu tiên, chúng ta import các gói cần thiết:
import os
from byteplussdkarkruntime import Ark
from dotenv import load_dotenv
Tiếp theo, tải API key từ tệp .env bằng hàm load_dotenv():
load_dotenv()
API_KEY = os.getenv("ARK_API_KEY")
Bây giờ khởi tạo client Ark, cho phép chúng ta gửi yêu cầu tới BytePlus Ark API.
Chúng ta dùng thư viện os để lấy API key từ biến môi trường và đặt base URL phù hợp cho truy cập API quốc tế:
client = Ark(
api_key=os.getenv("ARK_API_KEY"),
base_url="https://ark.ap-southeast.bytepluses.com/api/v3"
)
Cuối cùng, đặt một prompt và dùng hàm content_generation.tasks.create() từ client để tạo video:
prompt = """
A cinematic close-up of a weary but hopeful female astronaut inside a dimly lit, dusty spaceship cabin.
Soft blue light illuminates her face.
She takes a deep breath, showing subtle emotional relief, looks directly into the camera, and says:
'We finally made it. The atmosphere is stable.'
The ambient sound of a low, rhythmic spaceship engine hums in the background.
"""
response = client.content_generation.tasks.create(
model="dreamina-seedance-2-0-260128",
content=[
{
"type": "text",
"text": prompt,
}
],
generate_audio=True,
ratio="16:9",
duration=8,
watermark=True,
resolution="480p",
)
task_id = response.id
print(f"Task successfully submitted! Task ID: {task_id}")
Sau khi yêu cầu tạo video, chúng ta không nhận được video ngay vì cần thời gian để dựng.
Điều này có nghĩa biến response không phải chính là video.
Thay vào đó, nó là một đối tượng chứa thông tin về tác vụ tạo video.
Cụ thể, nó chứa mã định danh tác vụ, cho phép chúng ta theo dõi tiến độ tạo video và tải xuống khi mô hình dựng xong.
3. Theo dõi trạng thái dựng video (thăm dò tác vụ)
Chúng ta có thể lấy trạng thái một tác vụ bằng cách cung cấp mã định danh cho hàm content_generation.tasks.get(), như sau:
task = client.content_generation.tasks.get(task_id=task_id)
status = task.status
print(f"Status: {status}")
Để dễ theo dõi tiến độ video, chúng ta tạo script mới utils.py trong cùng thư mục và thêm hàm này để theo dõi tiến trình dựa trên client và mã tác vụ:
import time
import requests
def poll_task(client, task_id, poll_interval=5):
while True:
try:
task_status = client.content_generation.tasks.get(task_id=task_id)
status = getattr(task_status, "status", None) or (task_status.get("status") if isinstance(task_status, dict) else None)
if status == "succeeded":
print("\nTask completed successfully.")
return task_status.content.video_url
elif status == "failed":
error_details = getattr(task_status, "error", "Unknown error occurred during processing.")
raise RuntimeError(f"Task failed: {error_details}")
print(".", end="", flush=True)
time.sleep(poll_interval)
except Exception as e:
if isinstance(e, RuntimeError):
raise
print(f"\nWarning: Error polling task (will retry): {e}")
time.sleep(poll_interval)
4. Tải video đã tạo bằng Python requests
Hàm poll_task() chúng ta triển khai ở trên trả về
Giờ đây khi đã theo dõi được quá trình dựng video, điều còn lại là cách tải xuống khi hoàn tất.
Vì BytePlus Ark API trả về URL trực tiếp tới tệp video trong phản hồi tác vụ, chúng ta có thể tải bằng thư viện requests.
Đây là một hàm để thực hiện việc đó:
def download_video(url, output_path = "video.mp4"):
try:
print(f"Downloading video from {url} to {output_path}...")
response = requests.get(url, stream=True)
response.raise_for_status()
with open(output_path, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
print(f"Video successfully downloaded to '{output_path}'")
return True
except Exception as e:
print(f"Error downloading video: {e}")
return False
Script Python hoàn chỉnh: Text-to-video với Seedance 2
Gộp tất cả lại, đây là script đầy đủ để tạo video từ prompt văn bản bằng Seedance 2:
import os
from byteplussdkarkruntime import Ark
from dotenv import load_dotenv
import utils
load_dotenv()
API_KEY = os.getenv("ARK_API_KEY")
client = Ark(
api_key=os.getenv("ARK_API_KEY"),
base_url="https://ark.ap-southeast.bytepluses.com/api/v3"
)
prompt = """
A cinematic close-up of a weary but hopeful female astronaut inside a dimly lit, dusty spaceship cabin.
Soft blue light illuminates her face.
She takes a deep breath, showing subtle emotional relief, looks directly into the camera, and says:
'We finally made it. The atmosphere is stable.'
The ambient sound of a low, rhythmic spaceship engine hums in the background.
"""
response = client.content_generation.tasks.create(
model="dreamina-seedance-2-0-260128",
content=[
{
"type": "text",
"text": prompt,
}
],
generate_audio=True,
ratio="16:9",
duration=8,
watermark=True,
resolution="480p",
)
task_id = response.id
print(f"Task successfully submitted! Task ID: {task_id}")
# Wait for the video to finish generating
video_url = utils.poll_task(client, task_id)
utils.download_video(video_url, "./videos/space.mp4")
Tài liệu tham chiếu tham số lõi API Seedance 2
Dưới đây là danh sách các giá trị chấp nhận cho những tham số lõi của yêu cầu tạo video:

Hướng dẫn nâng cao: Khả năng Image-to-Video của Seedance 2.0
Ở phần trước, chúng ta đã học cách tạo video bằng prompt văn bản. Seedance 2 cũng hỗ trợ đầu vào hình ảnh, video và âm thanh, nên hãy bắt đầu với hình ảnh.
Dùng ảnh tham chiếu để giữ nhất quán nhân vật
Để thử đầu vào hình ảnh, tôi đã tạo hai nhân vật bằng AI để dùng trong một cảnh kiểu sitcom.

Chúng ta có thể cung cấp ảnh tham chiếu cho mô hình bằng cách thêm chúng vào trường content của yêu cầu, như sau:
response = client.content_generation.tasks.create(
model="dreamina-seedance-2-0-260128",
content=[
{
"type": "text",
"text": prompt,
},
{
"type": "image_url",
"image_url": {
"url": utils.load_image("./images/male-character.png")
},
"role": "reference_image"
},
{
"type": "image_url",
"image_url": {
"url": utils.load_image("./images/female-character.png")
},
"role": "reference_image"
}
],
generate_audio=True,
ratio="16:9",
duration=15,
watermark=True,
resolution="480p",
)
Với video này, tôi dùng prompt sau:
Context: A cozy, warmly lit independent coffee shop counter with wooden accents.
Reference:
- The male barista's face and clothing follow @Image1.
- The female customer's face and styling follow @Image2.
Action & Dialogue (10 Seconds Total):
0:00 - 0:04:
Medium close-up on the male barista (@Image1) standing behind the counter,
next to the coffee machine. He leans across the counter with a smooth,
flirtatious smirk, acting like he is making a highly exclusive offer:
"The WiFi password? It's actually my phone number: five-five-five, zero-one—"
0:04 - 0:07:
Camera cuts to the female customer (@Image2), instantly interrupting him.
She holds up her phone screen toward him, entirely unimpressed:
"Your network is called 'Free_Guest_WiFi' and there is literally no password."
0:07 - 0:08: Quick cut back to the two-shot.
Flustered, the barista becomes visibly embarrassed, his confident smirk
instantly vanishing as he nervously breaks eye contact.
0:08 - 0:10: Camera cuts back to a medium shot of the female customer (@Image2).
She lowers her phone, tapping her fingers lightly on the counter,
and delivers her order with perfect deadpan clarity:
"It will be an espresso please. No milk, no sugar, and no phone number."
Framing/Timing:
Clean cuts to perfectly pace the comedic timing over exactly 10 seconds.
Tone/Audio:
Lighthearted sitcom vibe. Synchronized voice generation for the dialogue, a subtle low cafe background hum, and the sound of the customer's fingers lightly tapping the wooden counter at the end.
Lưu ý prompt dùng @Image1 và @Image2 để tham chiếu tới các hình theo thứ tự được cung cấp trong danh sách.
Đáng tiếc, khi tôi thử tạo video này, tôi nhận lỗi:
The request failed because the input image may contain a real person.
Tôi thấy điều này lặp lại khi dùng Seedance 2 với ảnh tham chiếu có khuôn mặt người thật, kể cả khi là ảnh do AI tạo.
Để vượt qua, tôi chuyển các nhân vật sang dạng hoạt hình và thử lại.

Lần này mọi thứ hoạt động hoàn hảo, và tôi cho rằng kết quả đúng như điều tôi muốn tạo ra.
Toàn bộ mã cho ví dụ này có trong tệp image_to_video.py.
Đặt khung hình đầu và cuối để dẫn hướng hoạt ảnh
Ví dụ trước cho thấy cách dùng hình ảnh làm tham chiếu bằng cách đặt ”role”: “reference_image” trong yêu cầu.
Seedance 2 hỗ trợ hai vai trò hình ảnh khác:
”first_frame”: Chỉ định mô hình dùng ảnh cung cấp làm khung hình bắt đầu chính xác của video được tạo. Đây là thiết lập tiêu chuẩn cho tạo Image-to-Video trực tiếp.”last_frame”: Chỉ định mô hình kết thúc video được tạo bằng ảnh cụ thể này. Lưu ý: Bạn chỉ có thể dùng nếu cũng cung cấpfirst_frametrong cùng yêu cầu, về bản chất là yêu cầu mô hình nội suy video giữa hai hình.
Tôi đã thử bằng cách tạo một chuỗi khung đầu cho thấy phòng thí nghiệm AI của robot cố tái tạo thực vật trong một thế giới mà sự sống tự nhiên đã biến mất.

Với mỗi khung, tôi tạo một video dùng khung đó làm khung đầu. Đây là cấu trúc cho mỗi yêu cầu:
response = client.content_generation.tasks.create(
model="dreamina-seedance-2-0-260128",
content=[
{
"type": "text",
"text": prompt,
},
{
"type": "image_url",
"image_url": {
"url": utils.load_image("./images/robot-lab1.jpeg")
},
"role": "first_frame"
}
],
generate_audio=False,
ratio="16:9",
duration=4,
watermark=True,
resolution="480p",
)
Tôi tạo video không kèm âm thanh vì âm thanh sẽ không nhất quán do mỗi video được tạo riêng lẻ. Đây là kết quả khi ghép năm clip lại:
Script đầy đủ dùng để tạo video dựa trên khung đầu có tại đây.
Nội suy hình ảnh với last_frame
Trong ví dụ này, chúng ta cung cấp cả first_frame và last_frame để tạo video ở giữa hai hình.
Tôi đã tạo hai ảnh của cùng một căn phòng, một trống không có nội thất và một đã được bày đầy đủ. Mục tiêu là tạo video mô tả quá trình bày trí nội thất cho căn phòng.

Prompt tôi dùng mô tả cách tôi muốn nội thất xuất hiện trong video:
A dynamic, fast-paced sequence where furniture pops into existence piece by piece. First, a rug rapidly unfolds itself, then the sofa drops from just above the floor with a heavy, realistic bounce. Lamps, artwork, and plants quickly spring into reality one after another. Vibrant lighting, photorealistic materials, lively and snappy energetic rhythm.
Đây là yêu cầu:
response = client.content_generation.tasks.create(
model="dreamina-seedance-2-0-260128",
content=[
{
"type": "text",
"text": prompt,
},
{
"type": "image_url",
"image_url": {
"url": utils.load_image("./images/room-start.png")
},
"role": "first_frame"
},
{
"type": "image_url",
"image_url": {
"url": utils.load_image("./images/room-end.png")
},
"role": "last_frame"
}
],
generate_audio=True,
ratio="16:9",
duration=8,
watermark=True,
resolution="480p",
)
Và đây là kết quả:
Script đầy đủ có tại đây.
Đầu vào đa phương thức Seedance 2.0: Thêm tham chiếu âm thanh và video
Là một mô hình đa phương thức, Seedance 2 vượt ra ngoài đầu vào văn bản và hình ảnh. Nó cũng hỗ trợ đầu vào video và âm thanh. Các đầu vào này có thể dùng làm tham chiếu phong cách, điều khiển chuyển động hoặc chỉnh sửa video.
Ví dụ này từ trang web chính thức của họ minh họa rất rõ. Họ lấy một cảnh hai diễn viên đánh nhau và dùng nó để điều khiển hành động, thay thế diễn viên bằng các ảnh tham chiếu:
Gửi đầu vào video
Tương tự hình ảnh, đầu vào video được cung cấp trong tham số content của yêu cầu.
Tuy nhiên, tại thời điểm viết bài, đầu vào video chỉ hỗ trợ URL. Điều này có nghĩa nếu muốn dùng video lưu cục bộ trên máy, chúng ta cần host nó trước.
Trong ví dụ này, tôi dùng video trượt ván miễn phí của Marc Espejo. Ý tưởng là dùng Seedance 2 để thêm VFX. Đây là kết quả:
Để tạo ra điều này, tôi dùng yêu cầu sau:
response = client.content_generation.tasks.create(
model="dreamina-seedance-2-0-260128",
content=[
{
"type": "text",
"text": prompt,
},
{
"type": "video_url",
"video_url": {
"url": "https://www.pexels.com/download/video/38213009/"
},
"role": "reference_video"
}
],
generate_audio=True,
ratio="16:9",
duration=6,
watermark=True,
resolution="480p",
)
Script đầy đủ có tại đây. Prompt tôi dùng là:
The original skater, environment, and camera movement must remain
unchanged and untouched.
Only add gaming-style visual effects: intense glowing sparks and electric arcs
streaming from the skateboard-rail contact point during the grind, and a
brilliant energy shockwaves and dust burst at the jump/pop.
Gửi đầu vào âm thanh
Để thử đầu vào âm thanh, tôi tạo một ảnh cho nhân vật và dùng Fish Audio để tạo một track âm thanh với nhiều cảm xúc khác nhau.

Với âm thanh, tôi muốn có vài trạng thái cảm xúc khác nhau để xem Seedance 2 có thể nhận diện chúng khi tạo video hay không.
Fish Audio AI cho phép chỉ định cảm xúc bằng [emotion] trong prompt, nên rất phù hợp. Đây là audio prompt tôi dùng:
[sighing] Nothing much is happening today. [surprised] Wait a minute... what are those on my ears?[laughing] Oh my gosh, I can't believe I got piercings last night! [angry] But hold on, I specifically told you not to let me do it!
Để tải tệp âm thanh, tôi viết hàm này và thêm vào utils.py:
def load_audio(file_path):
if not os.path.exists(file_path):
raise FileNotFoundError(f"Audio file not found at: {file_path}")
# Guess the mime type (e.g., audio/mpeg for mp3, audio/wav for wav)
mime_type, _ = mimetypes.guess_type(file_path)
if mime_type is None:
mime_type = "audio/mpeg" # Fallback to mp3 just in case
with open(file_path, "rb") as audio_file:
encoded_string = base64.b64encode(audio_file.read()).decode('utf-8')
return f"data:{mime_type};base64,{encoded_string}"
Cung cấp âm thanh cho mô hình hoạt động tương tự như hình ảnh.
Chúng ta tải chúng dưới dạng data URI base64 và gửi vào tham số contents, như sau:
response = client.content_generation.tasks.create(
model="dreamina-seedance-2-0-260128",
content=[
{
"type": "text",
"text": prompt,
},
{
"type": "image_url",
"image_url": {
"url": utils.load_image("./images/cat.png")
},
"role": "reference_image"
},
{
"type": "audio_url",
"audio_url": {
"url": utils.load_audio("./audio/voice.mp3")
},
"role": "reference_audio"
}
],
ratio="16:9",
duration=11,
watermark=True,
resolution="480p",
)
Đây là video Seedance 2 đã tạo:
Nhìn chung, tôi nghĩ nó hoạt động khá tốt.
Tuy nhiên, về cuối, nhân vật bắt đầu khóc, không đúng như kỳ vọng từ cảm xúc tức giận.
Nhưng lưu ý Seedance 2 không nhận audio prompt; nó chỉ nhận tệp âm thanh cuối cùng.
Script đầy đủ có tại đây.
Ý tưởng dự án Seedance 2.0: Xây dựng công cụ chuyển cảnh video bằng AI
Nếu bạn muốn một dự án thú vị để củng cố những gì đã học, tôi gợi ý viết một script Python nhận hai video đầu vào và:
- Trích khung cuối từ video thứ nhất.
- Trích khung đầu từ video thứ hai.
- Dùng nội suy video như đã học để tạo phần chuyển cảnh giữa hai video.
- Cuối cùng, script ghép ba video thành một.
Kết luận
Trong bài viết này, chúng ta đã khám phá cách dùng Seedance 2 API để tạo video từ văn bản, hình ảnh và âm thanh.
Chúng ta đã đề cập thiết lập môi trường, kết nối API, và quản lý các đầu vào đa phương tiện để biến ý tưởng thành hiện thực. Quy trình khá đơn giản, và khả năng kết hợp các đầu vào này mở ra nhiều khả năng sáng tạo thú vị.
Nhìn chung, tôi thấy mô hình hoạt động ổn định và cho kết quả tốt.
Tuy nhiên, so với các mô hình tạo video khác trên thị trường hiện nay, nó không tạo cảm giác là một bước đột phá lớn. Nó hoàn thành công việc, nhưng không hẳn là thay đổi cuộc chơi.
Cuối cùng, dù tôi hoàn toàn hiểu lý do đằng sau các hướng dẫn an toàn hạn chế sử dụng khuôn mặt người thật trong đầu vào, tôi nhận thấy các quy định này hạn chế đáng kể tính thực tiễn của mô hình.
Khi tôi cố dùng công cụ để nâng cấp nội dung của chính mình, nó liên tục từ chối bất kỳ video nào có mặt tôi.
Điều này tạo ra rào cản cho những nhà sáng tạo muốn xây dựng nội dung cá nhân hóa, và là điểm cần cân nhắc nếu bạn định dùng công cụ này cho dự án chuyên nghiệp hoặc cá nhân.
Câu hỏi thường gặp về Seedance 2.0
Seedance 2 là gì?
Seedance 2 là một mô hình AI tạo sinh đa phương thức của ByteDance, hoạt động như một “đạo diễn đa phương thức,” có khả năng xử lý đồng thời văn bản, hình ảnh, video và âm thanh để tạo ra các chuỗi video mang tính điện ảnh.
Seedance có gói miễn phí không?
Không, không có gói miễn phí; việc kích hoạt và sử dụng Seedance 2 API yêu cầu mua credit dành riêng cho mô hình qua bảng điều khiển BytePlus Ark.
Tôi có thể dùng ảnh tham chiếu chứa khuôn mặt người thật trong video Seedance không?
Không, API liên tục từ chối đầu vào có khuôn mặt người thật, ngay cả khi là ảnh do AI tạo, và thường trả về lỗi. Chuyển nhân vật sang phong cách hoạt hình là một cách khắc phục được gợi ý.
Seedance 2 có phải là đa phương thức không?
Có, Seedance 2 là mô hình đa phương thức, nghĩa là có thể xử lý và tích hợp văn bản, hình ảnh, video và âm thanh để tạo nội dung video và âm thanh đồng bộ.
