El modelo de edición universal de video Wanxiang admite entradas multimodales (texto, imagen y video) y proporciona cinco capacidades principales: referencia de múltiples imágenes, repintado de video, edición local, extensión de video y expansión de video.
Ámbito de aplicación
- Los modelos compatibles varían según la región. Los recursos están aislados entre regiones. Para consultar los modelos compatibles en cada región, consulte la consola de Model Studio.
- Al realizar una llamada, asegúrese de que su modelo, URL de endpoint y clave de API pertenezcan todos a la misma región. Las llamadas entre regiones fallarán.
NotaEl código de ejemplo en este tema aplica a la región de Singapur.
Capacidades principales
Referencia de múltiples imágenes
Introducción a la función: Admite hasta 3 imágenes de referencia, que pueden incluir sujetos y fondos (como personas, animales, ropa y escenas). El modelo fusiona múltiples imágenes para generar contenido de video coherente.
Parámetros:function: Debe establecerse enimage_reference.ref_images_url: Una matriz de URLs. Puede introducir de 1 a 3 imágenes de referencia.obj_or_bg: Identifica cada imagen como sujeto (obj) o fondo (bg). La longitud debe ser la misma queref_images_url.
| Prompt de entrada | Imagen de referencia de entrada 1 (sujeto de referencia) | Imagen de referencia de entrada 2 (fondo de referencia) | Video de salida |
En el video, una chica sale de las profundidades de un antiguo bosque brumoso. Sus pasos son ligeros, y la cámara captura cada uno de sus momentos llenos de gracia. Cuando se detiene y mira a su alrededor hacia el frondoso bosque, una sonrisa de sorpresa y alegría aparece en su rostro. Este momento, capturado en el juego de luces y sombras, registra su maravilloso encuentro con la naturaleza. | ![]() | ![]() |
Antes de realizar una llamada, primero debe obtener una clave API y luego configurar la clave API como variable de entorno (pendiente de publicación y fusión en Configurar clave API).
curl
Paso 1: Cree una tarea para obtener un ID de tarea# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis' \
--header 'X-DashScope-Async: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "wan2.1-vace-plus",
"input": {
"function": "image_reference",
"prompt": "In the video, a girl gracefully emerges from a misty, ancient forest. Her steps are light, and the camera captures her every nimble moment. When she stops to look at the lush woods around her, a smile of surprise and joy blossoms on her face. This scene, frozen in an interplay of light and shadow, records her wonderful encounter with nature.",
"ref_images_url": [
"http://wanx.alicdn.com/material/20250318/image_reference_2_5_16.png",
"http://wanx.alicdn.com/material/20250318/image_reference_1_5_16.png"
]
},
"parameters": {
"prompt_extend": true,
"obj_or_bg": ["obj","bg"],
"size": "1280*720"
}
}'
Paso 2: Recupere el resultado basado en el ID de tareaReemplace {task_id} con el valor task_id devuelto por la llamada a la API anterior. El task_id es válido para consultas durante 24 horas. Reemplace {WorkspaceId} con su ID de espacio de trabajo real.
curl -X GET https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/tasks/{task_id} \
--header "Authorization: Bearer $DASHSCOPE_API_KEY"
Python
import os
import requests
import time
# The following is the URL for the Singapore region. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/wanx-vace-api-reference
BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1"
# API keys vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/get-api-key
API_KEY = os.getenv("DASHSCOPE_API_KEY", "YOUR_API_KEY")
headers = {"X-DashScope-Async": "enable", "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def create_task():
"""Create a video synthesis task and return the task_id"""
try:
resp = requests.post(
f"{BASE_URL}/services/aigc/video-generation/video-synthesis",
headers={
"X-DashScope-Async": "enable",
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"model": "wan2.1-vace-plus",
"input": {
"function": "image_reference",
"prompt": "In the video, a girl walks out from the depths of an ancient, misty forest. Her steps are light, and the camera captures her every graceful moment. When she stops and looks around at the lush woods, a smile of surprise and joy appears on her face. This moment, captured in the interplay of light and shadow, records her wonderful encounter with nature.",
"ref_images_url": [
"http://wanx.alicdn.com/material/20250318/image_reference_2_5_16.png",
"http://wanx.alicdn.com/material/20250318/image_reference_1_5_16.png"
]
},
"parameters": {"prompt_extend": True, "obj_or_bg": ["obj", "bg"], "size": "1280*720"}
},
timeout=30
)
resp.raise_for_status()
return resp.json()["output"]["task_id"]
except requests.RequestException as e:
raise RuntimeError(f"Failed to create the task: {e}")
def poll_result(task_id):
while True:
try:
resp = requests.get(
f"{BASE_URL}/tasks/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10
)
resp.raise_for_status()
data = resp.json()["output"]
status = data["task_status"]
print(f"Status: {status}")
if status == "SUCCEEDED":
return data["video_url"]
elif status in ("FAILED", "CANCELLED"):
raise RuntimeError(f"Task failed: {data.get('message', 'Unknown error')}")
time.sleep(15)
except requests.RequestException as e:
print(f"Polling exception: {e}. Retrying in 15 seconds...")
time.sleep(15)
if __name__ == "__main__":
task_id = create_task()
print(f"Task ID: {task_id}")
video_url = poll_result(task_id)
print(f"\nVideo generated successfully: {video_url}")
Java
import org.json.*;
import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
public class VideoSynthesis {
// The following is the URL for the Singapore region. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/wanx-vace-api-reference
static final String BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
// API keys vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/get-api-key
static final String API_KEY = System.getenv("DASHSCOPE_API_KEY");
private static final Map<String, String> COMMON_HEADERS = new HashMap<>();
static {
if (API_KEY == null || API_KEY.isEmpty()) {
throw new IllegalStateException("DASHSCOPE_API_KEY is not set");
}
COMMON_HEADERS.put("Authorization", "Bearer " + API_KEY);
// Enable HTTP keep-alive (enabled by default in JVM, but explicit setting is more reliable)
System.setProperty("http.keepAlive", "true");
System.setProperty("http.maxConnections", "20");
}
public static boolean isValidUserUrl(String urlString) {
try {
URL url = new URL(urlString);
// Check if the protocol is secure
String protocol = url.getProtocol();
if (!"https".equalsIgnoreCase(protocol) && !"http".equalsIgnoreCase(protocol)) {
return false;
}
return true;
} catch (Exception e) {
System.err.println("Invalid URL: " + e.getMessage());
return false;
}
}
// General HTTP POST request
private static String httpPost(String path, JSONObject body) throws Exception {
HttpURLConnection conn = createConnection(path, "POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
os.write(body.toString().getBytes("UTF-8"));
}
return readResponse(conn);
}
// General HTTP GET request
private static String httpGet(String path) throws Exception {
HttpURLConnection conn = createConnection(path, "GET");
return readResponse(conn);
}
// Create a connection (reuse connection parameters)
private static HttpURLConnection createConnection(String path, String method) throws Exception {
URL url = new URL(BASE_URL + path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// Configure connection properties
conn.setRequestMethod(method);
conn.setConnectTimeout(30000); // 30-second connection timeout
conn.setReadTimeout(60000); // 60-second read timeout
conn.setInstanceFollowRedirects(true); // Allow redirection
// Set common headers
for (Map.Entry<String, String> entry : COMMON_HEADERS.entrySet()) {
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
// Header for asynchronous tasks
if (path.contains("video-synthesis")) {
conn.setRequestProperty("X-DashScope-Async", "enable");
}
// Set content type and accept type
conn.setRequestProperty("Accept", "application/json");
return conn;
}
// Read the response (automatically handle error streams)
private static String readResponse(HttpURLConnection conn) throws IOException {
InputStream is = (conn.getResponseCode() >= 200 && conn.getResponseCode() < 400)
? conn.getInputStream()
: conn.getErrorStream();
if (is == null) {
throw new IOException("Cannot get response stream. Response code: " + conn.getResponseCode());
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append("\n"); // Add a line feed to maintain the original format
}
return sb.toString();
}
}
// Step 1: Create a task
public static String createTask() throws Exception {
JSONObject body = new JSONObject()
.put("model", "wan2.1-vace-plus")
.put("input", new JSONObject()
.put("function", "image_reference")
.put("prompt", "In the video, a girl walks out from the depths of an ancient, misty forest. Her steps are light, and the camera captures her every graceful moment. When she stops and looks around at the lush woods, a smile of surprise and joy appears on her face. This moment, captured in the interplay of light and shadow, records her wonderful encounter with nature.")
.put("ref_images_url", new JSONArray()
.put("http://wanx.alicdn.com/material/20250318/image_reference_2_5_16.png")
.put("http://wanx.alicdn.com/material/20250318/image_reference_1_5_16.png")))
.put("parameters", new JSONObject()
.put("prompt_extend", true)
.put("obj_or_bg", new JSONArray().put("obj").put("bg"))
.put("size", "1280*720"));
String resp = httpPost("/services/aigc/video-generation/video-synthesis", body);
JSONObject jsonResponse = new JSONObject(resp);
// Check if the response contains an error message
if (jsonResponse.has("code") && jsonResponse.getInt("code") != 200) {
String errorMessage = jsonResponse.optString("message", "Unknown error");
throw new RuntimeException("Failed to create the task: " + errorMessage + ", Details: " + resp);
}
JSONObject output = jsonResponse.getJSONObject("output");
return output.getString("task_id");
}
// Step 2: Poll for the result (15-second interval, no limit on retries)
public static String pollResult(String taskId) throws Exception {
while (true) {
String resp = httpGet("/tasks/" + taskId);
JSONObject responseJson = new JSONObject(resp);
// Validate the response structure
if (!responseJson.has("output")) {
throw new RuntimeException("The API response is missing the 'output' field: " + resp);
}
JSONObject output = responseJson.getJSONObject("output");
String status = output.getString("task_status");
System.out.println("Status: " + status);
if ("SUCCEEDED".equals(status)) {
return output.getString("video_url");
} else if ("FAILED".equals(status) || "CANCELLED".equals(status)) {
String message = output.optString("message", "Unknown error");
throw new RuntimeException("Task failed: " + message + ", Task ID: " + taskId + ", Details: " + resp);
}
Thread.sleep(15000);
}
}
public static void main(String[] args) {
try {
System.out.println("Creating video synthesis task...");
String taskId = createTask();
System.out.println("Task created successfully. Task ID: " + taskId);
System.out.println("Polling for task result...");
String videoUrl = pollResult(taskId);
System.out.println("Video URL: " + videoUrl);
} catch (Exception e) {
System.err.println("An error occurred: " + e.getMessage());
e.printStackTrace(); // Print the full stack trace for debugging
}
}
}
Repintado de video
Introducción a la función: Extrae la pose y las acciones del sujeto, la composición y los contornos de movimiento, o la estructura del boceto de un video de entrada. Luego genera un nuevo video con las mismas características dinámicas basándose en un prompt de texto. También puede reemplazar el sujeto en el video original usando una imagen de referencia.
Parámetros:-
function: Debe establecerse envideo_repainting. -
video_url: Obligatorio. La URL del video de entrada (formato MP4, ≤50 MB, ≤5 segundos). -
control_condition: Obligatorio. Establece el método para la extracción de características del video, lo cual determina qué características del video original se conservan en el nuevo video.posebodyface: Extrae expresiones faciales y movimientos corporales (conserva los detalles de las expresiones faciales).posebody: Extrae solo movimientos corporales, excluyendo el rostro (controla solo acciones corporales).depth: Extrae contornos de composición y movimiento (conserva la estructura de la escena).scribble: Extrae la estructura del boceto (conserva los detalles de los bordes del boceto).
-
strength: Opcional. Controla la fuerza de la extracción de características. El rango es [0.0, 1.0]. El valor predeterminado es 1.0. Un valor mayor acerca más la salida al video original, mientras que un valor menor permite mayor libertad creativa. -
ref_images_url: Opcional. Proporcione la URL de una imagen de referencia para reemplazar el sujeto en el video de entrada.
| Prompt de entrada | Video de entrada | Video de salida |
El video muestra un automóvil negro estilo steampunk conducido por un caballero, adornado con engranajes y tuberías de cobre. El fondo es una fábrica de dulces impulsada por vapor con elementos retro, creando una escena vintage y lúdica. |
curl
Paso 1: Cree una tarea para obtener un ID de tarea# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis' \
--header 'X-DashScope-Async: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "wan2.1-vace-plus",
"input": {
"function": "video_repainting",
"prompt": "The video shows a black steampunk-style car driven by a gentleman, adorned with gears and copper pipes. The background is a steam-powered candy factory with retro elements, creating a vintage and fun scene.",
"video_url": "http://wanx.alicdn.com/material/20250318/video_repainting_1.mp4"
},
"parameters": {
"prompt_extend": false,
"control_condition": "depth"
}
}'
Paso 2: Recupere el resultado basado en el ID de tareaReemplace {task_id} con el valor task_id devuelto por la llamada a la API anterior. El task_id es válido para consultas durante 24 horas. Reemplace {WorkspaceId} con su ID de espacio de trabajo real.
curl -X GET https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/tasks/{task_id} \
--header "Authorization: Bearer $DASHSCOPE_API_KEY"
Python
import os
import requests
import time
# The following is the URL for the Singapore region. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/wanx-vace-api-reference
BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1"
# API keys vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/get-api-key
API_KEY = os.getenv("DASHSCOPE_API_KEY", "YOUR_API_KEY")
def create_task():
"""Create a video repainting task and return the task_id"""
try:
resp = requests.post(
f"{BASE_URL}/services/aigc/video-generation/video-synthesis",
headers={
"X-DashScope-Async": "enable",
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"model": "wan2.1-vace-plus",
"input": {
"function": "video_repainting",
"prompt": "The video shows a black steampunk-style car driven by a gentleman, adorned with gears and copper pipes. The background is a steam-powered candy factory with retro elements, creating a vintage and playful scene.",
"video_url": "http://wanx.alicdn.com/material/20250318/video_repainting_1.mp4"
},
"parameters": {
"prompt_extend": False, # For video repainting, we recommend disabling prompt rewriting.
"control_condition": "depth" # Optional: posebodyface, posebody, depth, scribble
}
},
timeout=30
)
resp.raise_for_status()
return resp.json()["output"]["task_id"]
except requests.RequestException as e:
raise RuntimeError(f"Failed to create the task: {e}")
def poll_result(task_id):
while True:
try:
resp = requests.get(
f"{BASE_URL}/tasks/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10
)
resp.raise_for_status()
data = resp.json()["output"]
status = data["task_status"]
print(f"Status: {status}")
if status == "SUCCEEDED":
return data["video_url"]
elif status in ("FAILED", "CANCELLED"):
raise RuntimeError(f"Task failed: {data.get('message', 'Unknown error')}")
time.sleep(15)
except requests.RequestException as e:
print(f"Polling exception: {e}. Retrying in 15 seconds...")
time.sleep(15)
if __name__ == "__main__":
task_id = create_task()
print(f"Task ID: {task_id}")
video_url = poll_result(task_id)
print(f"\nVideo generated successfully: {video_url}")
Java
import org.json.*;
import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
public class VideoRepainting {
// The following is the URL for the Singapore region. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/wanx-vace-api-reference
static final String BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
// API keys vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/get-api-key
static final String API_KEY = System.getenv("DASHSCOPE_API_KEY");
private static final Map<String, String> COMMON_HEADERS = new HashMap<>();
static {
if (API_KEY == null || API_KEY.isEmpty()) {
throw new IllegalStateException("DASHSCOPE_API_KEY is not set");
}
COMMON_HEADERS.put("Authorization", "Bearer " + API_KEY);
System.setProperty("http.keepAlive", "true");
System.setProperty("http.maxConnections", "20");
}
// General HTTP POST request
private static String httpPost(String path, JSONObject body) throws Exception {
HttpURLConnection conn = createConnection(path, "POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
os.write(body.toString().getBytes("UTF-8"));
}
return readResponse(conn);
}
// General HTTP GET request
private static String httpGet(String path) throws Exception {
HttpURLConnection conn = createConnection(path, "GET");
return readResponse(conn);
}
// Create a connection
private static HttpURLConnection createConnection(String path, String method) throws Exception {
URL url = new URL(BASE_URL + path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(method);
conn.setConnectTimeout(30000);
conn.setReadTimeout(60000);
conn.setInstanceFollowRedirects(true);
for (Map.Entry<String, String> entry : COMMON_HEADERS.entrySet()) {
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
if (path.contains("video-synthesis")) {
conn.setRequestProperty("X-DashScope-Async", "enable");
}
conn.setRequestProperty("Accept", "application/json");
return conn;
}
// Read the response
private static String readResponse(HttpURLConnection conn) throws IOException {
InputStream is = (conn.getResponseCode() >= 200 && conn.getResponseCode() < 400)
? conn.getInputStream()
: conn.getErrorStream();
if (is == null) throw new IOException("Cannot get response stream. Response code: " + conn.getResponseCode());
try (BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
}
}
// Step 1: Create a video repainting task
public static String createTask() throws Exception {
JSONObject body = new JSONObject()
.put("model", "wan2.1-vace-plus")
.put("input", new JSONObject()
.put("function", "video_repainting")
.put("prompt", "The video shows a black steampunk-style car driven by a gentleman, adorned with gears and copper pipes. The background is a steam-powered candy factory with retro elements, creating a vintage and playful scene.")
.put("video_url", "http://wanx.alicdn.com/material/20250318/video_repainting_1.mp4"))
.put("parameters", new JSONObject()
.put("prompt_extend", false)
.put("control_condition", "depth"));
String resp = httpPost("/services/aigc/video-generation/video-synthesis", body);
JSONObject jsonResponse = new JSONObject(resp);
if (jsonResponse.has("code") && jsonResponse.getInt("code") != 200) {
String errorMessage = jsonResponse.optString("message", "Unknown error");
throw new RuntimeException("Failed to create the task: " + errorMessage);
}
return jsonResponse.getJSONObject("output").getString("task_id");
}
// Step 2: Poll for the result
public static String pollResult(String taskId) throws Exception {
while (true) {
String resp = httpGet("/tasks/" + taskId);
JSONObject output = new JSONObject(resp).getJSONObject("output");
String status = output.getString("task_status");
System.out.println("Status: " + status);
if ("SUCCEEDED".equals(status)) {
return output.getString("video_url");
} else if ("FAILED".equals(status) || "CANCELLED".equals(status)) {
throw new RuntimeException("Task failed: " + output.optString("message", "Unknown error"));
}
Thread.sleep(15000);
}
}
public static void main(String[] args) {
try {
System.out.println("Creating video repainting task...");
String taskId = createTask();
System.out.println("Task created successfully. Task ID: " + taskId);
System.out.println("Polling for task result...");
String videoUrl = pollResult(taskId);
System.out.println("Video URL: " + videoUrl);
} catch (Exception e) {
System.err.println("An error occurred: " + e.getMessage());
e.printStackTrace();
}
}
}
Edición local
Introducción a la función: Realiza edición de grano fino en áreas específicas de un video. Admite agregar, eliminar o modificar elementos, y reemplazar sujetos o fondos. Puede cargar una imagen de máscara para especificar el área de edición, y el modelo rastreará automáticamente el objetivo y fusionará el contenido generado.
Parámetros:-
function: Debe establecerse envideo_edit. -
video_url: Obligatorio. La URL del video de entrada original. -
mask_image_url: Opcional. Elija entre este ymask_video_url. Recomendamos usar este parámetro. Puede ingresar la URL de una imagen de máscara donde el área blanca representa la parte a editar y el área negra permanece sin cambios. -
mask_frame_id: Opcional. Se usa conmask_image_urlpara especificar a qué fotograma del video corresponde la máscara (el valor predeterminado es el primer fotograma). -
mask_type: Opcional. Especifica el comportamiento del área de edición:tracking(predeterminado): El área de edición sigue automáticamente la trayectoria de movimiento del objeto objetivo.fixed: El área de edición permanece en una posición fija.
-
expand_ratio: Opcional. Efectivo solo cuandomask_typeestracking.- Función: Establece la relación con la que el área de la máscara se expande hacia afuera. El rango de valores es [0.0, 1.0], y el valor predeterminado es 0.05.
- Descripción: Un valor más pequeño hace que la máscara se ajuste más al objetivo. Un valor más grande amplía el rango de la máscara.
-
ref_images_url: Opcional. Proporcione la URL de una imagen de referencia para reemplazar el contenido en el área de edición con el contenido de la imagen de referencia.
| Prompt de entrada | Video de entrada | Imagen de máscara de entrada | Video de salida |
El video muestra un café francés de estilo parisino donde un león con traje bebe café elegantemente. Sostiene una taza de café en una mano, bebiendo con una expresión relajada. El café está decorado con buen gusto, con tonos suaves y una iluminación cálida que ilumina el área donde se encuentra el león. | ![]()
|
curl
Paso 1: Cree una tarea para obtener un ID de tarea# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis' \
--header 'X-DashScope-Async: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "wan2.1-vace-plus",
"input": {
"function": "video_edit",
"prompt": "The video shows a Parisian-style French cafe where a lion in a suit elegantly sips coffee. It holds a coffee cup in one hand, taking a gentle sip with a relaxed expression. The cafe is tastefully decorated, with soft hues and warm lighting illuminating the lion's area.",
"mask_image_url": "http://wanx.alicdn.com/material/20250318/video_edit_1_mask.png",
"video_url": "http://wanx.alicdn.com/material/20250318/video_edit_2.mp4",
"mask_frame_id": 1
},
"parameters": {
"prompt_extend": false,
"mask_type": "tracking",
"expand_ratio": 0.05
}
}'
Paso 2: Recupere el resultado basado en el ID de tareaReemplace {task_id} con el valor task_id devuelto por la llamada a la API anterior. El task_id es válido para consultas durante 24 horas. Reemplace {WorkspaceId} con su ID de espacio de trabajo real.
curl -X GET https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/tasks/{task_id} \
--header "Authorization: Bearer $DASHSCOPE_API_KEY"
Python
Instale las dependencias: pip install requests.
import os
import requests
import time
# The following is the URL for the Singapore region. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/wanx-vace-api-reference
BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1"
# API keys vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/get-api-key
API_KEY = os.getenv("DASHSCOPE_API_KEY", "YOUR_API_KEY")
def create_task():
"""Create a local editing task and return the task_id"""
try:
resp = requests.post(
f"{BASE_URL}/services/aigc/video-generation/video-synthesis",
headers={
"X-DashScope-Async": "enable",
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"model": "wan2.1-vace-plus",
"input": {
"function": "video_edit",
"prompt": "The video shows a Parisian-style French cafe where a lion in a suit is elegantly drinking coffee. It holds a coffee cup in one hand, sipping with a relaxed expression. The cafe is tastefully decorated, with soft tones and warm lighting illuminating the area where the lion is.",
"mask_image_url": "http://wanx.alicdn.com/material/20250318/video_edit_1_mask.png",
"video_url": "http://wanx.alicdn.com/material/20250318/video_edit_2.mp4",
"mask_frame_id": 1 # The index of the video frame corresponding to the mask
},
"parameters": {
"prompt_extend": False,
"mask_type": "tracking", # Tracking mode
"expand_ratio": 0.05
}
},
timeout=30
)
resp.raise_for_status()
return resp.json()["output"]["task_id"]
except requests.RequestException as e:
raise RuntimeError(f"Failed to create the task: {e}")
def poll_result(task_id):
while True:
try:
resp = requests.get(
f"{BASE_URL}/tasks/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10
)
resp.raise_for_status()
data = resp.json()["output"]
status = data["task_status"]
print(f"Status: {status}")
if status == "SUCCEEDED":
return data["video_url"]
elif status in ("FAILED", "CANCELLED"):
raise RuntimeError(f"Task failed: {data.get('message', 'Unknown error')}")
time.sleep(15)
except requests.RequestException as e:
print(f"Polling exception: {e}. Retrying in 15 seconds...")
time.sleep(15)
if __name__ == "__main__":
task_id = create_task()
print(f"Task ID: {task_id}")
video_url = poll_result(task_id)
print(f"\nVideo generated successfully: {video_url}")
Java
import org.json.*;
import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
public class VideoRegionalEdit {
// The following is the URL for the Singapore region. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/wanx-vace-api-reference
static final String BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
// API keys vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/get-api-key
static final String API_KEY = System.getenv("DASHSCOPE_API_KEY");
private static final Map<String, String> COMMON_HEADERS = new HashMap<>();
static {
if (API_KEY == null || API_KEY.isEmpty()) {
throw new IllegalStateException("DASHSCOPE_API_KEY is not set");
}
COMMON_HEADERS.put("Authorization", "Bearer " + API_KEY);
System.setProperty("http.keepAlive", "true");
}
private static String httpPost(String path, JSONObject body) throws Exception {
HttpURLConnection conn = createConnection(path, "POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
os.write(body.toString().getBytes("UTF-8"));
}
return readResponse(conn);
}
private static String httpGet(String path) throws Exception {
HttpURLConnection conn = createConnection(path, "GET");
return readResponse(conn);
}
private static HttpURLConnection createConnection(String path, String method) throws Exception {
URL url = new URL(BASE_URL + path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(method);
conn.setConnectTimeout(30000);
conn.setReadTimeout(60000);
for (Map.Entry<String, String> entry : COMMON_HEADERS.entrySet()) {
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
if (path.contains("video-synthesis")) {
conn.setRequestProperty("X-DashScope-Async", "enable");
}
return conn;
}
private static String readResponse(HttpURLConnection conn) throws IOException {
InputStream is = (conn.getResponseCode() >= 200 && conn.getResponseCode() < 400) ? conn.getInputStream() : conn.getErrorStream();
try (BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) sb.append(line).append("\n");
return sb.toString();
}
}
// Step 1: Create a local editing task
public static String createTask() throws Exception {
JSONObject body = new JSONObject()
.put("model", "wan2.1-vace-plus")
.put("input", new JSONObject()
.put("function", "video_edit")
.put("prompt", "The video shows a Parisian-style French cafe where a lion in a suit is elegantly drinking coffee. It holds a coffee cup in one hand, sipping with a relaxed expression. The cafe is tastefully decorated, with soft tones and warm lighting illuminating the area where the lion is.")
.put("mask_image_url", "http://wanx.alicdn.com/material/20250318/video_edit_1_mask.png")
.put("video_url", "http://wanx.alicdn.com/material/20250318/video_edit_2.mp4")
.put("mask_frame_id", 1))
.put("parameters", new JSONObject()
.put("prompt_extend", false)
.put("mask_type", "tracking")
.put("expand_ratio", 0.05));
String resp = httpPost("/services/aigc/video-generation/video-synthesis", body);
JSONObject jsonResponse = new JSONObject(resp);
if (jsonResponse.has("code") && jsonResponse.getInt("code") != 200) {
String errorMessage = jsonResponse.optString("message", "Unknown error");
throw new RuntimeException("Failed to create the task: " + errorMessage);
}
return jsonResponse.getJSONObject("output").getString("task_id");
}
// Step 2: Poll for the result
public static String pollResult(String taskId) throws Exception {
while (true) {
String resp = httpGet("/tasks/" + taskId);
JSONObject output = new JSONObject(resp).getJSONObject("output");
String status = output.getString("task_status");
System.out.println("Status: " + status);
if ("SUCCEEDED".equals(status)) return output.getString("video_url");
else if ("FAILED".equals(status) || "CANCELLED".equals(status))
throw new RuntimeException("Task failed: " + output.optString("message"));
Thread.sleep(15000);
}
}
public static void main(String[] args) {
try {
System.out.println("Creating local editing task...");
String taskId = createTask();
System.out.println("Task created successfully. Task ID: " + taskId);
String videoUrl = pollResult(taskId);
System.out.println("Video URL: " + videoUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Extensión de video
Introducción a la función: Predice y genera contenido posterior continuo basándose en una imagen o clip de video de entrada. Admite la extensión hacia adelante desde el "primer fotograma/primer clip" o la extensión hacia atrás desde el "último fotograma/último clip". La duración total del video final generado es fija en 5 segundos.
Parámetros:-
function: Debe establecerse envideo_extension. -
prompt: Obligatorio. Describe el contenido extendido deseado. -
first_clip_url: Opcional. Puede ingresar la URL del primer clip de video (≤3 segundos). El modelo generará el resto del video basándose en este clip. -
last_clip_url: Opcional. Puede ingresar la URL del último clip de video (≤3 segundos). El modelo generará la parte anterior del video basándose en este clip. -
first_frame_url: Opcional. Puede ingresar la URL de la imagen del primer fotograma. El video se extenderá hacia adelante desde este fotograma. -
last_frame_url: Opcional. Puede ingresar la URL de la imagen del último fotograma. El video se extenderá hacia atrás desde este fotograma.Nota: Usted debe proporcionar al menos uno de los siguientes cuatro parámetros como entrada: first_clip_url, last_clip_url, first_frame_url o last_frame_url.
| Prompt de entrada | Primer clip de entrada (1 segundo) | Video de salida (extendido a 5 segundos) |
Un perro con gafas de sol anda en patineta por la calle, caricatura 3D. |
curl
Paso 1: Cree una tarea para obtener un ID de tarea# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis' \
--header 'X-DashScope-Async: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "wan2.1-vace-plus",
"input": {
"function": "video_extension",
"prompt": "A dog wearing sunglasses skateboarding on the street, 3D cartoon.",
"first_clip_url": "http://wanx.alicdn.com/material/20250318/video_extension_1.mp4"
},
"parameters": {
"prompt_extend": false
}
}'
Paso 2: Recupere el resultado basado en el ID de tareaReemplace {task_id} con el valor task_id devuelto por la llamada a la API anterior. El task_id es válido para consultas durante 24 horas. Reemplace {WorkspaceId} con su ID de espacio de trabajo real.
curl -X GET https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/tasks/{task_id} \
--header "Authorization: Bearer $DASHSCOPE_API_KEY"
Python
import os
import requests
import time
# The following is the URL for the Singapore region. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/wanx-vace-api-reference
BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1"
# API keys vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/get-api-key
API_KEY = os.getenv("DASHSCOPE_API_KEY", "YOUR_API_KEY")
def create_task():
"""Create a video extension task and return the task_id"""
try:
resp = requests.post(
f"{BASE_URL}/services/aigc/video-generation/video-synthesis",
headers={
"X-DashScope-Async": "enable",
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"model": "wan2.1-vace-plus",
"input": {
"function": "video_extension",
"prompt": "A dog wearing sunglasses is skateboarding on the street, 3D cartoon.",
"first_clip_url": "http://wanx.alicdn.com/material/20250318/video_extension_1.mp4"
},
"parameters": {
"prompt_extend": False
}
},
timeout=30
)
resp.raise_for_status()
return resp.json()["output"]["task_id"]
except requests.RequestException as e:
raise RuntimeError(f"Failed to create the task: {e}")
def poll_result(task_id):
while True:
try:
resp = requests.get(
f"{BASE_URL}/tasks/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10
)
resp.raise_for_status()
data = resp.json()["output"]
status = data["task_status"]
print(f"Status: {status}")
if status == "SUCCEEDED":
return data["video_url"]
elif status in ("FAILED", "CANCELLED"):
raise RuntimeError(f"Task failed: {data.get('message', 'Unknown error')}")
time.sleep(15)
except requests.RequestException as e:
print(f"Polling exception: {e}. Retrying in 15 seconds...")
time.sleep(15)
if __name__ == "__main__":
task_id = create_task()
print(f"Task ID: {task_id}")
video_url = poll_result(task_id)
print(f"\nVideo generated successfully: {video_url}")
Java
import org.json.*;
import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
public class VideoExtension {
// The following is the URL for the Singapore region. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/wanx-vace-api-reference
static final String BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
// API keys vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/get-api-key
static final String API_KEY = System.getenv("DASHSCOPE_API_KEY");
private static final Map<String, String> COMMON_HEADERS = new HashMap<>();
static {
if (API_KEY == null || API_KEY.isEmpty()) {
throw new IllegalStateException("DASHSCOPE_API_KEY is not set");
}
COMMON_HEADERS.put("Authorization", "Bearer " + API_KEY);
System.setProperty("http.keepAlive", "true");
}
private static String httpPost(String path, JSONObject body) throws Exception {
HttpURLConnection conn = createConnection(path, "POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
os.write(body.toString().getBytes("UTF-8"));
}
return readResponse(conn);
}
private static String httpGet(String path) throws Exception {
HttpURLConnection conn = createConnection(path, "GET");
return readResponse(conn);
}
private static HttpURLConnection createConnection(String path, String method) throws Exception {
URL url = new URL(BASE_URL + path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(method);
conn.setConnectTimeout(30000);
conn.setReadTimeout(60000);
for (Map.Entry<String, String> entry : COMMON_HEADERS.entrySet()) {
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
if (path.contains("video-synthesis")) {
conn.setRequestProperty("X-DashScope-Async", "enable");
}
return conn;
}
private static String readResponse(HttpURLConnection conn) throws IOException {
InputStream is = (conn.getResponseCode() >= 200 && conn.getResponseCode() < 400) ? conn.getInputStream() : conn.getErrorStream();
try (BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) sb.append(line).append("\n");
return sb.toString();
}
}
// Step 1: Create a video extension task
public static String createTask() throws Exception {
JSONObject body = new JSONObject()
.put("model", "wan2.1-vace-plus")
.put("input", new JSONObject()
.put("function", "video_extension")
.put("prompt", "A dog wearing sunglasses is skateboarding on the street, 3D cartoon.")
.put("first_clip_url", "http://wanx.alicdn.com/material/20250318/video_extension_1.mp4"))
.put("parameters", new JSONObject()
.put("prompt_extend", false));
String resp = httpPost("/services/aigc/video-generation/video-synthesis", body);
JSONObject jsonResponse = new JSONObject(resp);
if (jsonResponse.has("code") && jsonResponse.getInt("code") != 200) {
String errorMessage = jsonResponse.optString("message", "Unknown error");
throw new RuntimeException("Failed to create the task: " + errorMessage);
}
return jsonResponse.getJSONObject("output").getString("task_id");
}
// Step 2: Poll for the result
public static String pollResult(String taskId) throws Exception {
while (true) {
String resp = httpGet("/tasks/" + taskId);
JSONObject output = new JSONObject(resp).getJSONObject("output");
String status = output.getString("task_status");
System.out.println("Status: " + status);
if ("SUCCEEDED".equals(status)) return output.getString("video_url");
else if ("FAILED".equals(status) || "CANCELLED".equals(status))
throw new RuntimeException("Task failed: " + output.optString("message"));
Thread.sleep(15000);
}
}
public static void main(String[] args) {
try {
System.out.println("Creating video extension task...");
String taskId = createTask();
System.out.println("Task created successfully. Task ID: " + taskId);
String videoUrl = pollResult(taskId);
System.out.println("Video URL: " + videoUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Expansión de video
Introducción a la función: Expande el contenido del video en las direcciones superior, inferior, izquierda y derecha basándose en un prompt y una relación especificada, manteniendo la coherencia del sujeto del video y la fusión natural del fondo.
Parámetros:function: Debe establecerse envideo_outpainting.video_url: Obligatorio. La URL del video de entrada original.top_scale: Opcional. La relación de expansión hacia arriba. El rango es [1.0, 2.0]. El valor predeterminado es 1.0 (sin expansión).bottom_scale: Opcional. La relación de expansión hacia abajo. El rango es [1.0, 2.0]. El valor predeterminado es 1.0.left_scale: Opcional. La relación de expansión hacia la izquierda. El rango es [1.0, 2.0]. El valor predeterminado es 1.0.right_scale: Opcional. La relación de expansión hacia la derecha. El rango es [1.0, 2.0]. El valor predeterminado es 1.0.
Ejemplo: Establecer
left_scaleen 1.5 significa que el lado izquierdo del fotograma se expandirá a 1.5 veces su ancho original.
| Prompt de entrada | Video de entrada | Video de salida |
Una dama elegante toca el violín con pasión, con una orquesta sinfónica completa detrás de ella. |
curl
Paso 1: Cree una tarea para obtener un ID de tarea# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis' \
--header 'X-DashScope-Async: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "wan2.1-vace-plus",
"input": {
"function": "video_outpainting",
"prompt": "An elegant woman passionately plays the violin, with a full symphony orchestra behind her.",
"video_url": "http://wanx.alicdn.com/material/20250318/video_outpainting_1.mp4"
},
"parameters": {
"prompt_extend": false,
"top_scale": 1.5,
"bottom_scale": 1.5,
"left_scale": 1.5,
"right_scale": 1.5
}
}'
Paso 2: Recupere el resultado basado en el ID de tareaReemplace {task_id} con el valor task_id devuelto por la llamada a la API anterior. El task_id es válido para consultas durante 24 horas. Reemplace {WorkspaceId} con su ID de espacio de trabajo real.
curl -X GET https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/tasks/{task_id} \
--header "Authorization: Bearer $DASHSCOPE_API_KEY"
Python
import os
import requests
import time
# The following is the URL for the Singapore region. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/wanx-vace-api-reference
BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1"
# API keys vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/get-api-key
API_KEY = os.getenv("DASHSCOPE_API_KEY", "YOUR_API_KEY")
def create_task():
"""Create a video outpainting task and return the task_id"""
try:
resp = requests.post(
f"{BASE_URL}/services/aigc/video-generation/video-synthesis",
headers={
"X-DashScope-Async": "enable",
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"model": "wan2.1-vace-plus",
"input": {
"function": "video_outpainting",
"prompt": "An elegant lady is passionately playing the violin, with a full symphony orchestra behind her.",
"video_url": "http://wanx.alicdn.com/material/20250318/video_outpainting_1.mp4"
},
"parameters": {
"prompt_extend": False,
"top_scale": 1.5, # Upward expansion ratio
"bottom_scale": 1.5, # Downward expansion ratio
"left_scale": 1.5, # Leftward expansion ratio
"right_scale": 1.5 # Rightward expansion ratio
}
},
timeout=30
)
resp.raise_for_status()
return resp.json()["output"]["task_id"]
except requests.RequestException as e:
raise RuntimeError(f"Failed to create the task: {e}")
def poll_result(task_id):
while True:
try:
resp = requests.get(
f"{BASE_URL}/tasks/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10
)
resp.raise_for_status()
data = resp.json()["output"]
status = data["task_status"]
print(f"Status: {status}")
if status == "SUCCEEDED":
return data["video_url"]
elif status in ("FAILED", "CANCELLED"):
raise RuntimeError(f"Task failed: {data.get('message', 'Unknown error')}")
time.sleep(15)
except requests.RequestException as e:
print(f"Polling exception: {e}. Retrying in 15 seconds...")
time.sleep(15)
if __name__ == "__main__":
task_id = create_task()
print(f"Task ID: {task_id}")
video_url = poll_result(task_id)
print(f"\nVideo generated successfully: {video_url}")
Java
import org.json.*;
import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
public class VideoOutpainting {
// The following is the URL for the Singapore region. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/wanx-vace-api-reference
static final String BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
// API keys vary by region. For more information, see https://www.alibabacloud.com/help/model-studio/get-api-key
static final String API_KEY = System.getenv("DASHSCOPE_API_KEY");
private static final Map<String, String> COMMON_HEADERS = new HashMap<>();
static {
if (API_KEY == null || API_KEY.isEmpty()) {
throw new IllegalStateException("DASHSCOPE_API_KEY is not set");
}
COMMON_HEADERS.put("Authorization", "Bearer " + API_KEY);
System.setProperty("http.keepAlive", "true");
}
private static String httpPost(String path, JSONObject body) throws Exception {
HttpURLConnection conn = createConnection(path, "POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
os.write(body.toString().getBytes("UTF-8"));
}
return readResponse(conn);
}
private static String httpGet(String path) throws Exception {
HttpURLConnection conn = createConnection(path, "GET");
return readResponse(conn);
}
private static HttpURLConnection createConnection(String path, String method) throws Exception {
URL url = new URL(BASE_URL + path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(method);
conn.setConnectTimeout(30000);
conn.setReadTimeout(60000);
for (Map.Entry<String, String> entry : COMMON_HEADERS.entrySet()) {
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
if (path.contains("video-synthesis")) {
conn.setRequestProperty("X-DashScope-Async", "enable");
}
return conn;
}
private static String readResponse(HttpURLConnection conn) throws IOException {
InputStream is = (conn.getResponseCode() >= 200 && conn.getResponseCode() < 400) ? conn.getInputStream() : conn.getErrorStream();
try (BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) sb.append(line).append("\n");
return sb.toString();
}
}
// Step 1: Create a video outpainting task
public static String createTask() throws Exception {
JSONObject body = new JSONObject()
.put("model", "wan2.1-vace-plus")
.put("input", new JSONObject()
.put("function", "video_outpainting")
.put("prompt", "An elegant lady is passionately playing the violin, with a full symphony orchestra behind her.")
.put("video_url", "http://wanx.alicdn.com/material/20250318/video_outpainting_1.mp4"))
.put("parameters", new JSONObject()
.put("prompt_extend", false)
.put("top_scale", 1.5)
.put("bottom_scale", 1.5)
.put("left_scale", 1.5)
.put("right_scale", 1.5));
String resp = httpPost("/services/aigc/video-generation/video-synthesis", body);
JSONObject jsonResponse = new JSONObject(resp);
if (jsonResponse.has("code") && jsonResponse.getInt("code") != 200) {
String errorMessage = jsonResponse.optString("message", "Unknown error");
throw new RuntimeException("Failed to create the task: " + errorMessage);
}
return jsonResponse.getJSONObject("output").getString("task_id");
}
// Step 2: Poll for the result
public static String pollResult(String taskId) throws Exception {
while (true) {
String resp = httpGet("/tasks/" + taskId);
JSONObject output = new JSONObject(resp).getJSONObject("output");
String status = output.getString("task_status");
System.out.println("Status: " + status);
if ("SUCCEEDED".equals(status)) return output.getString("video_url");
else if ("FAILED".equals(status) || "CANCELLED".equals(status))
throw new RuntimeException("Task failed: " + output.optString("message"));
Thread.sleep(15000);
}
}
public static void main(String[] args) {
try {
System.out.println("Creating video outpainting task...");
String taskId = createTask();
System.out.println("Task created successfully. Task ID: " + taskId);
String videoUrl = pollResult(taskId);
System.out.println("Video URL: " + videoUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Cómo introducir imágenes y videos
Imágenes de entrada
-
Número de imágenes: Puede proporcionar la cantidad de imágenes correspondientes a la función seleccionada.
-
Métodos de entrada:
- URL pública: Admite el protocolo HTTP o HTTPS. Ejemplo: https://xxxx/xxx.png.
Videos de entrada
-
Número de videos: Puede proporcionar la cantidad de videos correspondientes a la función seleccionada.
-
Métodos de entrada:
- URL pública: Admite el protocolo HTTP o HTTPS. Ejemplo: https://xxxx/xxx.mp4.
Videos de salida
-
Número de videos: 1.
-
Especificaciones del video: La resolución total es fija en 720P, con una tasa de fotogramas de 30 fps, en formato MP4 (codificación H.264).
-
Validez de la URL del video: 24 horas.
-
Dimensiones del video: Varían según la función seleccionada.
-
Referencia de múltiples imágenes / Edición local:
- La resolución de salida es fija en 720P.
- El ancho y alto específicos están determinados por el parámetro de solicitud size.
-
Repintado de video / Extensión de video / Expansión de video:
- Si la resolución del video de entrada es ≤ 720P: La salida mantiene la resolución original.
- Si la resolución del video de entrada es > 720P: La salida se reduce a 720P manteniendo la relación de aspecto.
-
Facturación y limitación de tasa
-
Para obtener más información sobre la cuota gratuita del modelo y las tarifas de facturación, consulte Precios del modelo.
-
Para obtener más información sobre los límites de tasa del modelo, consulte la serie Wanxiang.
-
Descripción de facturación:
- No se le cobra por las entradas. La facturación se basa en la duración en segundos del video generado exitosamente.
- Las llamadas fallidas al modelo o los errores de procesamiento no generan ningún cargo y no consumen la cuota gratuita para nuevos usuarios.
- La edición de video universal también admite planes de ahorro.
Documentación de la API
Referencia de la API de edición de video universal
FAQ
P: ¿Cuántas imágenes admite como máximo la función de referencia de múltiples imágenes?
R: Admite hasta 3 imágenes de referencia. Si proporciona más de 3, solo las primeras 3 se utilizan como entrada. Recomendamos usar un fondo sólido para la imagen del sujeto para resaltar mejor al sujeto, y una imagen de fondo que no contenga ningún sujeto.
P: ¿Cuándo debo desactivar la reescritura de prompts para el repintado de video?
R: Cuando la descripción de texto no coincide con el contenido del video de entrada, el modelo puede malinterpretarlo. Recomendamos desactivar manualmente la reescritura de prompts estableciendo prompt_extend=false, y proporcionar una descripción clara y específica de la escena en el prompt para mejorar la consistencia y precisión de la generación.
P: En la función de edición local, ¿cuál es la diferencia entre una imagen de máscara y un video de máscara?
R: Debe proporcionar mask_image_url o mask_video_url. Recomendamos usar una imagen de máscara. Solo necesita especificar el área de edición para un fotograma, y el sistema rastreará automáticamente el objetivo.


