Corso
In questo tutorial ti mostrerò come usare l’API di BytePlus Ark per interagire con Seedance 2 usando Python.
Seedance 2 è un potente modello di IA generativa di ByteDance che funge da "regista multimodale", in grado di elaborare contemporaneamente input di testo, immagini, video e audio per creare sequenze video cinematografiche con audio sincronizzato. Che tu voglia animare immagini statiche o dare vita a prompt testuali complessi, questa guida ti accompagnerà nell’installazione e nell’implementazione.
Generare una chiave API di Seedance 2
Per iniziare, dobbiamo creare un account BytePlus e una chiave API. Per farlo:
- Vai al sito ufficiale di BytePlus e crea un account.
- Vai alla pagina di creazione della chiave API e clicca su “Create API Key”.
Questa chiave viene usata per effettuare richieste all’API ModelArk, la loro API ufficiale.
La prassi migliore è salvare la chiave in un file chiamato .env nella stessa cartella in cui scriviamo gli script Python. Assicurati di mantenerla segreta perché chiunque potrebbe usarla per interagire con l’API tramite il tuo account.
Incolla la chiave API nel file .env con il seguente formato:
ARK_API_KEY=<paste_api_key_here>
Attivare il modello Seedance 2 e struttura dei prezzi
Per poter usare Seedance 2, dobbiamo prima attivare il modello:

Tieni presente che usare l’API non è gratuito e l’attivazione di Seedance 2 richiede l’acquisto di crediti per il modello. Per questo articolo, ho acquistato un pacchetto da 7 milioni di token per Seedance 2 al costo di $30,10.

Purtroppo, i token sono specifici per il modello. Ciò significa che se compriamo token per le versioni fast o mini di Seedance 2, non possiamo usarli con il modello base.
Di seguito trovi una tabella con i piani tariffari dell’API:

Come generare video con l’API Seedance 2 in Python
Ho incluso gli script completi corrispondenti al codice creato in questo tutorial in questa repository GitHub.
In questa sezione impariamo come effettuare una richiesta text-to-video per generare questo video:
1. Configurare l’ambiente Python e l’SDK
Per connetterci all’API BytePlus Ark usando Python, useremo il pacchetto ufficiale byteplus-python-sdk-v2.
Il modo più semplice per impostare le dipendenze di questo progetto è creare un ambiente Anaconda e installare il file requirements.txt, così:
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. Inizializzare il client Python di BytePlus Ark
Crea un nuovo script chiamato text_to_video.py nella stessa cartella del file .env che abbiamo creato prima.
Per prima cosa, importiamo i pacchetti necessari:
import os
from byteplussdkarkruntime import Ark
from dotenv import load_dotenv
Poi carichiamo la chiave API dal file .env usando la funzione load_dotenv():
load_dotenv()
API_KEY = os.getenv("ARK_API_KEY")
Ora inizializziamo il client Ark, che ci permette di effettuare richieste all’API BytePlus Ark.
Usiamo la libreria os per ottenere la chiave API dalle variabili d’ambiente e impostiamo la base URL appropriata per l’accesso internazionale all’API:
client = Ark(
api_key=os.getenv("ARK_API_KEY"),
base_url="https://ark.ap-southeast.bytepluses.com/api/v3"
)
Infine, impostiamo un prompt e usiamo la funzione content_generation.tasks.create() del client per generare il 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}")
Dopo aver richiesto la generazione di un video, non lo otteniamo subito perché richiede tempo per essere generato.
Questo significa che la variabile response non è il video in sé.
È invece un oggetto che contiene informazioni sull’attività di generazione del video.
In particolare, contiene l’identificatore del task, che ci permette di monitorare l’avanzamento della generazione e scaricare il video una volta che il modello ha finito.
3. Monitorare lo stato della generazione del video (Polling del task)
Possiamo recuperare lo stato di un task fornendo l’identificatore del task alla funzione content_generation.tasks.get(), così:
task = client.content_generation.tasks.get(task_id=task_id)
status = task.status
print(f"Status: {status}")
Per semplificare il tracciamento dell’avanzamento, creiamo un nuovo script utils.py nella stessa cartella e aggiungiamo questa funzione che monitora il progresso dato l’istanza del client e l’identificatore del task:
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. Scaricare il video generato con Python requests
La funzione poll_task() implementata sopra restituisce l’URL del video
Ora che possiamo monitorare il processo di generazione, ci serve solo un modo per scaricarlo quando termina.
Poiché l’API BytePlus Ark restituisce un URL diretto al file video generato nella risposta del task, possiamo scaricarlo usando la libreria requests.
Ecco una funzione che lo fa:
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 completo: Text-to-video con Seedance 2
Mettendo tutto insieme, ecco uno script completo per generare un video da un prompt testuale usando 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")
Guida di riferimento ai parametri core dell’API Seedance 2
Di seguito trovi l’elenco dei valori accettati per i parametri principali di una richiesta di generazione video:

Guida avanzata: funzionalità Image-to-Video di Seedance 2.0
Nella sezione precedente abbiamo visto come generare un video usando un prompt testuale. Seedance 2 supporta anche input di immagini, video e audio, quindi iniziamo dalle immagini.
Usare immagini di riferimento per la coerenza dei personaggi
Per testare gli input di immagini, ho generato due personaggi con l’IA da usare in una scena in stile sitcom.

Possiamo fornire immagini di riferimento al modello aggiungendole al campo content della richiesta, così:
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",
)
Per questo video, ho usato il seguente prompt:
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.
Nota che il prompt usa @Image1 e @Image2 per fare riferimento alle immagini nell’ordine in cui sono state fornite nell’elenco.
Purtroppo, quando ho provato a generare questo video, ho ricevuto un errore che diceva:
The request failed because the input image may contain a real person.
L’ho riscontrato sistematicamente quando ho cercato di usare Seedance 2 con un’immagine di riferimento contenente un essere umano realistico, anche se generato con l’IA.
Per superare il problema, ho convertito i personaggi in stile cartoon e ho riprovato.

Questa volta ha funzionato alla perfezione e credo che il risultato sia stato esattamente quello che volevo creare.
Il codice completo di questo esempio è disponibile nel file image_to_video.py.
Impostare il primo e l’ultimo fotogramma per un’animazione guidata
Nell’esempio precedente abbiamo visto come usare le immagini come riferimenti impostando ”role”: “reference_image” nella richiesta.
Seedance 2 supporta altre due tipologie di ruolo per le immagini:
”first_frame”: indica al modello di usare l’immagine fornita come fotogramma iniziale esatto del video generato. È l’impostazione standard per la generazione diretta da immagine a video.”last_frame”: indica al modello di concludere il video generato con questa specifica immagine. Nota: puoi usarla solo se fornisci anche unfirst_framenella stessa richiesta, chiedendo di fatto al modello di interpolare il video tra le due immagini.
L’ho provato generando una successione di fotogrammi iniziali che mostrano un laboratorio di robotica IA che cerca di ricreare piante in un mondo in cui la vita naturale è scomparsa.

Per ogni fotogramma ho generato un video usando quel fotogramma come first frame. Ecco come strutturare ogni richiesta:
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",
)
Ho generato i video senza audio perché l’audio non sarebbe stato coerente, dato che ogni video è stato generato separatamente. Ecco il risultato dell’unione delle cinque clip:
Lo script completo usato per generare un video a partire da un fotogramma iniziale è disponibile qui.
Interpolazione di immagini con last_frame
In questo esempio forniamo sia un first_frame sia un last_frame per generare un video tra i due.
Ho generato due immagini della stessa stanza, una vuota senza mobili e l’altra con la stanza completamente arredata. L’obiettivo è generare un video che animi l’arredamento della stanza.

Il prompt che ho usato descrive come voglio che i mobili compaiano nel 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.
Ecco la richiesta:
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",
)
Ed ecco il risultato:
Lo script completo è disponibile qui.
Input multimodali in Seedance 2.0: aggiungere riferimenti audio e video
In quanto modello multimodale, Seedance 2 va oltre gli input di testo e immagine. Supporta anche input video e audio. Questi possono essere usati come riferimenti stilistici, per guidare i movimenti o per il video editing.
Questo esempio dal loro sito ufficiale lo illustra molto bene. Hanno preso una scena di due attori che combattono e l’hanno usata per guidare l’azione, sostituendo gli attori con immagini di riferimento:
Inviare un input video
Come per le immagini, gli input video vengono forniti nel parametro content della richiesta.
Tuttavia, al momento della stesura, gli input video supportano solo URL. Questo significa che se vogliamo usare un video che abbiamo in locale sulla nostra macchina, dovremo prima ospitarlo online.
Per questo esempio, ho usato questo video di skate a uso gratuito di Marc Espejo. L’idea era usare Seedance 2 per aggiungere alcuni VFX. Ecco il risultato:
Per generarlo, ho usato la seguente richiesta:
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",
)
Lo script completo è disponibile qui. Il prompt che ho usato è stato:
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.
Inviare un input audio
Per testare gli input audio, ho generato un’immagine per un personaggio e ho usato Fish Audio per generare una traccia audio con emozioni diverse.

Per l’audio, volevo alcune emozioni diverse per vedere se Seedance 2 riusciva a identificarle durante la generazione del video.
Fish Audio AI ci permette di specificare le emozioni usando [emotion] nel prompt, quindi era perfetto per lo scopo. Ecco il prompt audio che ho usato:
[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!
Per caricare il file audio, ho scritto questa funzione che ho aggiunto a 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}"
Fornire l’audio al modello funziona in modo molto simile alle immagini.
Le carichiamo come data URI in base 64 e le inviamo al modello nel parametro contents, così:
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",
)
Questo è il video generato da Seedance 2:
Nel complesso, penso che si sia comportato piuttosto bene.
In qualche modo, verso la fine, il personaggio ha iniziato a piangere, cosa che non era esattamente quello che mi aspettavo da un’emozione di rabbia.
Ma nota che Seedance 2 non ha ricevuto il prompt audio; gli è stato fornito solo il file audio finale.
Lo script completo è disponibile qui.
Idea di progetto con Seedance 2.0: creare uno strumento di transizione video con IA
Se vuoi un progetto divertente per consolidare quanto hai imparato, ti suggerisco di scrivere uno script Python che prenda due video in input e:
- Estrae l’ultimo fotogramma del primo video.
- Estrae il primo fotogramma del secondo video.
- Usa l’interpolazione video che abbiamo visto qui per generare una transizione tra i due video.
- Infine, unisce i tre video in uno solo.
Conclusione
In questo articolo abbiamo esplorato come usare l’API di Seedance 2 per generare video da testo, immagini e audio.
Abbiamo coperto l’impostazione dell’ambiente, la connessione all’API e la gestione dei vari input multimediali necessari per dare vita alle idee. Il processo è semplice e la possibilità di combinare questi input apre interessanti possibilità creative.
Nel complesso, trovo che il modello sia affidabile e produca risultati solidi.
Tuttavia, non sembra rappresentare una svolta o un grande salto in avanti rispetto ad altri modelli di generazione video attualmente sul mercato. Fa il suo dovere, ma non cambia necessariamente le regole del gioco.
Infine, pur comprendendo pienamente le ragioni dietro le linee guida di sicurezza che limitano l’uso di volti umani reali negli input, ho trovato che queste regole limitano in modo significativo l’uso pratico del modello.
Quando ho provato a usare lo strumento per migliorare i miei contenuti, ha rifiutato sistematicamente qualsiasi video in cui comparisse il mio volto.
Questo rappresenta un ostacolo per i creator che vogliono creare media personalizzati ed è un aspetto da considerare se intendi usare questo strumento per progetti professionali o personali.
Seedance 2.0 - Domande frequenti
Che cos’è Seedance 2?
Seedance 2 è un modello di IA generativa multimodale di ByteDance che funge da "regista multimodale", capace di elaborare contemporaneamente input di testo, immagini, video e audio per creare sequenze video cinematografiche.
Esiste un livello gratuito per Seedance?
No, non esiste un livello gratuito; attivare e usare l’API Seedance 2 richiede l’acquisto di crediti specifici per il modello tramite la console BytePlus Ark.
Posso usare immagini di riferimento con volti umani realistici nei miei video Seedance?
No, l’API rifiuta costantemente input che contengono volti umani realistici, anche se generati dall’IA, restituendo spesso un errore. Una soluzione suggerita è convertire i personaggi in immagini in stile cartone animato.
Seedance 2 è multimodale?
Sì, Seedance 2 è un modello multimodale, il che significa che può elaborare e integrare input di testo, immagini, video e audio per creare contenuti con video e audio sincronizzati.


