すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Model Studio:ビデオ編集 2.1

最終更新日:Jun 13, 2026

Wanxiang ユニバーサルビデオ編集モデルは、マルチモーダル入力(テキスト、画像、ビデオ)をサポートし、次の 5 つのコア機能を提供します。マルチイメージリファレンス、ビデオリペインティング、ローカル編集、ビデオエクステンション、ビデオアウトペインティング

適用範囲

  • サポートされるモデルはリージョンによって異なります。リソースはリージョン間で分離されています。各リージョンでサポートされているモデルについては、Model Studio コンソールをご参照ください。

  • API 呼び出しを行う際は、ご利用のモデル、エンドポイント URL、API キーがすべて同一リージョンに属していることを確認してください。リージョンをまたいだ呼び出しは失敗します。

説明

本トピックのサンプルコードは シンガポール リージョン向けです。

コア機能

マルチイメージリファレンス

機能概要: 最大 3 枚のリファレンス画像をサポートします。リファレンス画像には被写体や背景(人物、動物、衣装、シーンなど)を含めることができます。モデルは複数の画像をマージして、一貫性のあるビデオコンテンツを生成します。

パラメーター:

  • functionimage_reference に設定する必要があります。

  • ref_images_url: URL の配列です。1~3 枚のリファレンス画像を入力できます。

  • obj_or_bg: 各画像を被写体(obj)または背景(bg)として識別します。長さは ref_images_url と同じである必要があります。

入力プロンプト

入力リファレンス画像 1(被写体)

入力リファレンス画像 2(背景)

出力ビデオ

ビデオでは、少女が霧に包まれた古代の森の奥深くから現れます。その足取りは軽やかで、カメラは彼女の優雅な動きを捉えています。彼女が立ち止まり、周囲の豊かな森を見渡すと、驚きと喜びの笑みが顔に浮かびます。光と影が織りなすこの瞬間は、自然との素晴らしい出会いを記録しています。

image

image

API 呼び出しを行う前に、まずAPI キーを取得し、次にAPI キーを環境変数として設定(非公開予定で「API キーの設定」に統合)する必要があります。

curl

ステップ 1:タスクを作成してタスク ID を取得します

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"
    }
}'

ステップ 2:タスク ID に基づいて結果を取得します

{task_id} は、前の API 呼び出しで返された task_id の値に置き換えてください。task_id は 24 時間有効です。

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/ja/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/ja/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/ja/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/ja/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
        }
    }

}

ビデオリペインティング

機能概要: 入力ビデオから被写体のポーズと動作、構図とモーション輪郭、またはスケッチ構造を抽出します。その後、テキストプロンプトに基づいて、同じ動的特徴を持つ新しいビデオを生成します。リファレンス画像を使用して、元のビデオ内の被写体を置き換えることもできます。

パラメーター:

  • functionvideo_repainting に設定する必要があります。

  • video_url必須。入力ビデオの URL(MP4 形式、50 MB 以下、5 秒以下)。

  • control_condition必須。ビデオ特徴抽出の方法を設定します。これにより、元のビデオのどの特徴を新しいビデオに保持するかが決まります。

    • posebodyface: 顔の表情と身体の動きを抽出します(顔の表情の詳細を保持)。

    • posebody: 身体の動きのみを抽出し、顔は除外します(身体の動作のみを制御)。

    • depth: 構図とモーション輪郭を抽出します(シーン構造を保持)。

    • scribble: スケッチ構造を抽出します(スケッチのエッジ詳細を保持)。

  • strength: 任意。特徴抽出の強度を制御します。範囲は [0.0, 1.0] で、デフォルトは 1.0 です。値が大きいほど出力は元のビデオに近くなり、小さいほど創造的な自由度が高くなります。

  • ref_images_url: 任意。1 枚のリファレンス画像の URL を指定して、入力ビデオ内の被写体を置き換えます。

入力プロンプト

入力ビデオ

出力ビデオ

ビデオでは、歯車や銅管で装飾された紳士が運転する黒色のスチームパンク風の車が登場します。背景はレトロ要素を備えた蒸気動力のキャンディ工場で、ヴィンテージかつ遊び心あふれるシーンを演出しています。

curl

ステップ 1:タスクを作成してタスク ID を取得します

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"
    }
}'

ステップ 2:タスク ID に基づいて結果を取得します

{task_id} は、前の API 呼び出しで返された task_id の値に置き換えてください。task_id は 24 時間有効です。

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/ja/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/ja/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/ja/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/ja/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();
        }
    }
}

ローカル編集

機能概要: ビデオの指定された領域に対して詳細な編集を行います。要素の追加、削除、変更、および被写体や背景の置き換えをサポートします。マスク画像をアップロードして編集領域を指定すると、モデルが自動的にターゲットをトラッキングし、生成されたコンテンツをブレンドします。

パラメーター:

  • functionvideo_edit に設定する必要があります。

  • video_url必須。元の入力ビデオの URL です。

  • mask_image_url: 任意。mask_video_url とのいずれか一方を選択します。このパラメーターの使用を推奨します。編集対象を白、未編集部分を黒で示したマスク画像の URL を入力できます。

  • mask_frame_id: 任意。mask_image_url と併用して、マスクがビデオのどのフレームに対応するかを指定します(デフォルトは最初のフレーム)。

  • mask_type: 任意。編集領域の動作を指定します。

    • tracking(デフォルト): 編集領域がターゲットオブジェクトの動作軌跡に自動的に追従します。

    • fixed: 編集領域が固定位置に留まります。

  • expand_ratio: 任意。mask_typetracking の場合にのみ有効です。

    • 機能: マスク領域が外側に拡張する比率を設定します。値の範囲は [0.0, 1.0] で、デフォルトは 0.05 です。

    • 説明: 値が小さいほどマスクがターゲットに密着し、大きいほどマスクの範囲が広がります。

  • ref_images_url: 任意。1 枚のリファレンス画像の URL を指定して、編集領域のコンテンツをリファレンス画像のコンテンツで置き換えます。

入力プロンプト

入力ビデオ

入力マスク画像

出力ビデオ

ビデオでは、パリ風のフランスカフェでスーツを着たライオンが優雅にコーヒーを飲んでいます。片手にコーヒーカップを持ち、リラックスした表情で一口ずつ味わっています。カフェは洗練された装飾が施されており、柔らかな色調と温かい照明がライオンのいるエリアを照らしています。

mask

白い領域が編集領域を示します。

curl

ステップ 1:タスクを作成してタスク ID を取得します

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
    }
}'

ステップ 2:タスク ID に基づいて結果を取得します

{task_id} は、前の API 呼び出しで返された task_id の値に置き換えてください。task_id は 24 時間有効です。

curl -X GET https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/tasks/{task_id} \
--header "Authorization: Bearer $DASHSCOPE_API_KEY"

Python

依存関係のインストール: 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/ja/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/ja/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/ja/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/ja/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();
        }
    }
}

ビデオエクステンション

機能概要: 入力画像またはビデオクリップに基づいて、連続する後続コンテンツを予測・生成します。「最初のフレーム/最初のクリップ」から前方に拡張するか、「最後のフレーム/最後のクリップ」から後方に拡張するかが可能です。最終的に生成されるビデオの総再生時間は 5 秒に固定されます。

パラメーター:

  • functionvideo_extension に設定する必要があります。

  • prompt必須。拡張したいコンテンツを記述します。

  • first_clip_url: 任意。最初のビデオクリップ(3 秒以下)の URL を入力できます。モデルはこのクリップに基づいて残りのビデオを生成します。

  • last_clip_url: 任意。最後のビデオクリップ(3 秒以下)の URL を入力できます。モデルはこのクリップに基づいて先行する部分のビデオを生成します。

  • first_frame_url: 任意。最初のフレーム画像の URL を入力できます。このフレームから前方にビデオが拡張されます。

  • last_frame_url: 任意。最後のフレーム画像の URL を入力できます。このフレームから後方にビデオが拡張されます。

    : 次の 4 つのパラメーターのうち少なくとも 1 つを入力として指定する必要があります: first_clip_url、last_clip_url、first_frame_url、または last_frame_url。

入力プロンプト

入力最初のクリップ(1 秒)

出力ビデオ(5 秒に拡張)

サングラスをかけた犬が路上でスケートボードをする、3D カートゥーン。

curl

ステップ 1:タスクを作成してタスク ID を取得します

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
    }
}'

ステップ 2:タスク ID に基づいて結果を取得します

{task_id} は、前の API 呼び出しで返された task_id の値に置き換えてください。task_id は 24 時間有効です。

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/ja/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/ja/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/ja/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/ja/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();
        }
    }
}

ビデオアウトペインティング

機能概要: プロンプトと指定された比率に基づいて、ビデオコンテンツを上下左右の方向に拡張します。この際、ビデオの被写体の一貫性を維持し、背景を自然にブレンドします。

パラメーター:

  • functionvideo_outpainting に設定する必要があります。

  • video_url必須。元の入力ビデオの URL です。

  • top_scale: 任意。上方向への拡張比率です。範囲は [1.0, 2.0] で、デフォルトは 1.0(拡張なし)です。

  • bottom_scale: 任意。下方向への拡張比率です。範囲は [1.0, 2.0] で、デフォルトは 1.0 です。

  • left_scale: 任意。左方向への拡張比率です。範囲は [1.0, 2.0] で、デフォルトは 1.0 です。

  • right_scale: 任意。右方向への拡張比率です。範囲は [1.0, 2.0] で、デフォルトは 1.0 です。

left_scale を 1.5 に設定すると、フレームの左側が元の幅の 1.5 倍に拡張されます。

入力プロンプト

入力ビデオ

出力ビデオ

優雅な女性が情熱的にバイオリンを演奏しており、背後にはフルシンフォニーのオーケストラが控えています。

curl

ステップ 1:タスクを作成してタスク ID を取得します

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
    }
}'

ステップ 2:タスク ID に基づいて結果を取得します

{task_id} は、前の API 呼び出しで返された task_id の値に置き換えてください。task_id は 24 時間有効です。

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/ja/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/ja/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/ja/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/ja/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();
        }
    }
}

画像およびビデオの入力方法

入力画像

  • 画像枚数選択した機能に対応する枚数の画像を提供できます。

  • 入力方法

    • パブリック URL: HTTP または HTTPS プロトコルをサポートします。例: https://xxxx/xxx.png。

入力ビデオ

  • ビデオ本数選択した機能に対応する本数のビデオを提供できます。

  • 入力方法

    • パブリック URL: HTTP または HTTPS プロトコルをサポートします。例: https://xxxx/xxx.mp4。

出力ビデオ

  • ビデオ本数: 1 本。

  • ビデオ仕様: 総解像度は 720P 固定、フレームレートは 30 fps、形式は MP4(H.264 エンコーディング)です。

  • ビデオ URL の有効期間24 時間

  • ビデオサイズ: 選択した機能によって異なります。

    • マルチイメージリファレンス/ローカル編集

      • 出力解像度は 720P 固定です。

      • 具体的な幅と高さは、size リクエストパラメーターによって決定されます。

    • ビデオリペインティング/ビデオエクステンション/ビデオアウトペインティング

      • 入力ビデオの解像度が 720P 以下の場合: 出力は元の解像度を維持します。

      • 入力ビデオの解像度が 720P より大きい場合: 出力は縦横比を維持したまま 720P にダウンスケールされます。

課金とレート制限

  • モデルの無料クォータおよび課金レートの詳細については、「モデルの価格設定」をご参照ください。

  • モデルのレート制限の詳細については、「Wanxiang シリーズ」をご参照ください。

  • 課金の説明:

    • 入力に対して課金されません。課金は、正常に生成されたビデオの秒単位の持続時間に基づいて行われます。

    • 失敗したモデル呼び出しや処理エラーに対しては、料金が発生せず、新規ユーザー無料クォータも消費しません。

    • ユニバーサルビデオ編集は節約プランもサポートしています。

API ドキュメント

ユニバーサルビデオ編集 API リファレンス

よくある質問

Q:マルチイメージリファレンス機能でサポートされる画像の最大枚数はいくつですか?

A: 最大 3 枚のリファレンス画像をサポートします。3 枚を超えて提供した場合、最初の 3 枚のみが入力として使用されます。被写体画像にはソリッドカラーの背景を使用して被写体をより際立たせることを推奨します。また、背景画像には被写体を含まないものを使用してください。

Q:ビデオリペインティングでプロンプトリライトを無効にするべきタイミングはいつですか?

A: テキストの説明が入力ビデオの内容と一致しない場合、モデルが誤って解釈する可能性があります。prompt_extend=false を設定してプロンプトリライトを手動で無効にし、プロンプト内でシーンを明確かつ具体的に記述することを推奨します。これにより、生成の一貫性と精度が向上します。

Q:ローカル編集機能において、マスク画像とマスクビデオの違いは何ですか?

A: mask_image_url または mask_video_url のいずれか一方を提供する必要があります。マスク画像の使用を推奨します。1 フレーム分の編集領域を指定するだけで、システムが自動的にターゲットをトラッキングします。