Video Lip Sync

Description

This API submits a video lip-sync task. After the task is successfully submitted, the algorithm runs asynchronously. You can actively query the algorithm result through the query API.

Version

1.0

Media Requirements

Supported input media formats include wav, m4a, mp4, mp3, and aac. The original example passes a video URL followed by an audio URL. The source documentation does not specify any resolution, file size, or duration limits.

API URL

    Production environment: https://openapi.meitu.com
    Task submission endpoint: https://openapi.meitu.com/api/v1/sdk/sync/push
    Task name (task): /v1/mt_vace_a2v/482306
    Task type (task_type): formula

Method

POST

Content-Type: application/json

Authentication

Open Platform API Signature

Request Parameters

RequiredParameterTypeDescription
YesparamsstringAlgorithm parameters as a JSON string
Yesinit_imagesobject[]List of media files; the original example passes the video first and the audio second
YestaskstringFixed value: /v1/mt_vace_a2v/482306
Yestask_typestringFixed value: formula
Nosync_timeoutintDefaults to 30; synchronous timeout in seconds

The structure of each media item in init_images is described below.

RequiredParameterTypeDescription
YesurlstringVideo or audio URL, or the corresponding media data encoded as base64
YesprofileobjectMedia attribute description

The profile object is described below.

RequiredParameterTypeDescription
Yesmedia_profilesobjectMedia attributes
YesversionstringFixed value: v1

The media_profiles object is described below.

RequiredParameterTypeDescription
Yesmedia_data_typestringurl indicates a URL; the corresponding media type indicates base64 data

The params inference parameter is a JSON string with the following structure.

RequiredFieldTypeDescription
Norsp_media_typestringDefaults to url; the corresponding media type indicates base64 data
YesparameterobjectCore algorithm parameters

Algorithm parameter details for parameter

The source documentation does not define any additional algorithm parameters. Pass an empty object {} as parameter.

Request Example

{
  "task": "/v1/mt_vace_a2v/482306",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1Mzg1NTIwMA==/c408e44f-5a2d-4744-6c90-a7af8a3e486a.mov",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    },
    {
      "url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1Mzg1NTIwMA==/c4901608-2b1e-4b6c-6358-031eb23eaa5c.mpeg",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"rsp_media_type\":\"url\",\"parameter\":{}}",
  "sync_timeout": 30
}

Response Fields

Generated results are periodically deleted. Download and save them promptly.
FieldTypeDescription
request_idstringRequest identifier
trace_idstringTrace identifier
codeintBusiness status code; 0 indicates that the request was accepted successfully
error_codeintError code; 0 indicates success
messagestringBusiness message
tipsanyAdditional information; may be null
dataobjectTask status and algorithm result

Fields in data

FieldTypeDescription
statusintStatus code: -1, task not found; 0, created; 1, processing; 2, failed; 9, timed out—use the query API; 10, succeeded
resultobjectAlgorithm result
progressnumberTask progress
predict_elapsedintEstimated processing time in milliseconds
create_timeint64Creation timestamp in milliseconds
task_idstringTask ID
custom_task_idstringClient-defined task ID
trace_idstringTrace identifier within data
client_infostringClient information
init_imagesobject[]/nullInput media echoed by the service

Fields in result

FieldTypeDescription
idint/stringTask ID; the source table specifies int, while the response example uses string
parametersobjectTask parameter information
codeintError code returned on failure
dataint/objectTask result data; the source table specifies int, while the response example uses object
data.durationobjectDuration information for each processing stage
data.duration.alg_process_timeintAlgorithm processing time
data.duration.created_timestampintCreation timestamp
data.duration.pull_timestampintPull timestamp
data.duration.repost_timeintForwarding time
data.duration.upload_timeintUpload time
data.duration.waiting_timeintWaiting time
data.error_codeintAlgorithm error code
data.error_msgstringAlgorithm error message
data.extraobjectAdditional information
data.media_info_listobject[]Media information list
data.msg_idstringMessage ID
data.parameterobject/nullAlgorithm parameter information
msglong/stringTask message; the source table specifies long, while the response example uses string
msg_idstringMessage ID

Response Examples

Successful Response Example

Response Status: 200

Content-Type: application/json; charset=utf-8

{
  "request_id": "",
  "trace_id": "",
  "code": 0,
  "error_code": 0,
  "message": "success",
  "tips": null,
  "data": {
    "status": 10,
    "result": {
      "id": "task_id",
      "parameters": {},
      "data": {
        "duration": {
          "alg_process_time": 2087,
          "created_timestamp": 1759224849,
          "pull_timestamp": 1759224849,
          "repost_time": 0,
          "upload_time": 0,
          "waiting_time": 78
        },
        "error_code": 0,
        "error_msg": "success",
        "extra": {},
        "media_info_list": [],
        "msg_id": "msg_id",
        "parameter": {}
      },
      "msg": "success",
      "msg_id": "msg_id"
    },
    "progress": 1,
    "predict_elapsed": 10000,
    "create_time": 1759224844659,
    "task_id": "task_id",
    "custom_task_id": "",
    "trace_id": "trace_id",
    "client_info": "",
    "init_images": null
  }
}

Query-Required Response Example

Use the query API to retrieve the result.

Response Status: 200

Content-Type: application/json; charset=utf-8

{
  "request_id": "",
  "trace_id": "",
  "code": 0,
  "error_code": 0,
  "message": "success",
  "tips": null,
  "data": {
    "status": 9,
    "result": {
      "id": "task_id"
    },
    "progress": 0,
    "predict_elapsed": 10000,
    "create_time": 1759202368761,
    "task_id": "task_id",
    "custom_task_id": "",
    "trace_id": "trace_id",
    "client_info": "",
    "init_images": null
  }
}

Failed Response Example

Response Status: 400

Content-Type: application/json; charset=utf-8

{
  "request_id": "",
  "trace_id": "",
  "code": 26301,
  "error_code": 26301,
  "message": "MTLABSDK - DEPENDENCY MISSING ERROR",
  "tips": null,
  "data": {
    "status": 2,
    "result": {
      "id": "task_id",
      "code": 26301,
      "data": {
        "duration": {
          "alg_process_time": 0,
          "created_timestamp": 1759232149,
          "pull_timestamp": 1759232149,
          "repost_time": 0,
          "upload_time": 0,
          "waiting_time": 81
        },
        "error_code": 26301,
        "error_msg": "MTLABSDK - DEPENDENCY MISSING ERROR",
        "extra": {},
        "media_info_list": [],
        "msg_id": "msg_id",
        "parameter": null
      },
      "msg": "MTLABSDK - DEPENDENCY MISSING ERROR",
      "msg_id": "msg_id"
    },
    "progress": 1,
    "predict_elapsed": 10000,
    "create_time": 1759232149156,
    "task_id": "task_id",
    "custom_task_id": "",
    "trace_id": "trace_id",
    "client_info": "",
    "init_images": null
  }
}

General Error Codes

See API Error Codes for details.

SDK Examples

Python

import json

import requests
from sign_sdk import sign

def api_call_example():
    key = "your_api_key"
    secret = "your_api_secret"
    url = "https://openapi.meitu.com/api/v1/sdk/sync/push"
    method = "POST"

    headers = {
        "Content-Type": "application/json",
        sign.HeaderHost: "openapi.meitu.com",
    }
    inner_params = {
        "rsp_media_type": "url",
        "parameter": {},
    }
    payload = {
        "task": "/v1/mt_vace_a2v/482306",
        "task_type": "formula",
        "init_images": [
            {
                "url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1Mzg1NTIwMA==/c408e44f-5a2d-4744-6c90-a7af8a3e486a.mov",
                "profile": {
                    "media_profiles": {"media_data_type": "url"},
                    "version": "v1",
                },
            },
            {
                "url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1Mzg1NTIwMA==/c4901608-2b1e-4b6c-6358-031eb23eaa5c.mpeg",
                "profile": {
                    "media_profiles": {"media_data_type": "url"},
                    "version": "v1",
                },
            },
        ],
        "params": json.dumps(inner_params, ensure_ascii=False),
        "sync_timeout": 30,
    }
    body = json.dumps(payload, ensure_ascii=False)

    signer = sign.Signer(key, secret)
    signed_request = signer.sign(url, method, headers, body)
    response = requests.Session().send(signed_request)
    print(f"Status: {response.status_code}")
    print(f"Response: {response.text}")

if __name__ == "__main__":
    api_call_example()

Go

package main

import (
	"fmt"
	"io"
	"net/http"

	"github.com/mtlab/api/signer"
)

func main() {
	key := "your_api_key"
	secret := "your_api_secret"
	signObj := signer.NewSigner(key, secret)

	url := "https://openapi.meitu.com/api/v1/sdk/sync/push"
	method := http.MethodPost
	headers := make(http.Header)
	headers.Set(signer.HeaderHost, "openapi.meitu.com")
	headers.Set("Content-Type", "application/json")

	body := `{
  "task": "/v1/mt_vace_a2v/482306",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1Mzg1NTIwMA==/c408e44f-5a2d-4744-6c90-a7af8a3e486a.mov",
      "profile": {
        "media_profiles": {"media_data_type": "url"},
        "version": "v1"
      }
    },
    {
      "url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1Mzg1NTIwMA==/c4901608-2b1e-4b6c-6358-031eb23eaa5c.mpeg",
      "profile": {
        "media_profiles": {"media_data_type": "url"},
        "version": "v1"
      }
    }
  ],
  "params": "{\"rsp_media_type\":\"url\",\"parameter\":{}}",
  "sync_timeout": 30
}`

	req, err := signObj.Sign(url, method, headers, body)
	if err != nil {
		fmt.Println("Failed to sign request:", err)
		return
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		fmt.Println("Failed to send request:", err)
		return
	}
	defer resp.Body.Close()

	responseBody, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Read response failed:", err)
		return
	}
	fmt.Println("Response:", resp.StatusCode, string(responseBody))
}

PHP

<?php
require 'signer.php';

$key = 'your_api_key';
$secret = 'your_api_secret';
$signer = new Signer($key, $secret);

$url = 'https://openapi.meitu.com/api/v1/sdk/sync/push';
$method = 'POST';
$headers = ['Content-Type' => 'application/json'];

$innerParams = json_encode([
    'rsp_media_type' => 'url',
    'parameter' => (object) [],
]);

$body = json_encode([
    'task' => '/v1/mt_vace_a2v/482306',
    'task_type' => 'formula',
    'init_images' => [
        [
            'url' => 'https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1Mzg1NTIwMA==/c408e44f-5a2d-4744-6c90-a7af8a3e486a.mov',
            'profile' => [
                'media_profiles' => ['media_data_type' => 'url'],
                'version' => 'v1',
            ],
        ],
        [
            'url' => 'https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1Mzg1NTIwMA==/c4901608-2b1e-4b6c-6358-031eb23eaa5c.mpeg',
            'profile' => [
                'media_profiles' => ['media_data_type' => 'url'],
                'version' => 'v1',
            ],
        ],
    ],
    'params' => $innerParams,
    'sync_timeout' => 30,
]);

$curl = $signer->sign($url, $method, $headers, $body);
$response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

if ($status === 0) {
    echo 'Error: ' . curl_error($curl);
} else {
    echo "Status: {$status}\n";
    echo "Response: {$response}\n";
}
curl_close($curl);
?>

Java

package com.meitu.openai.common;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) throws Exception {
        Signer signer = new Signer("your_api_key", "your_api_secret");
        String url = "https://openapi.meitu.com/api/v1/sdk/sync/push";
        String method = "POST";

        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put(Signer.HeaderHost, "openapi.meitu.com");

        String body = "{\n" +
                "  \"task\": \"/v1/mt_vace_a2v/482306\",\n" +
                "  \"task_type\": \"formula\",\n" +
                "  \"init_images\": [\n" +
                "    {\n" +
                "      \"url\": \"https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1Mzg1NTIwMA==/c408e44f-5a2d-4744-6c90-a7af8a3e486a.mov\",\n" +
                "      \"profile\": {\n" +
                "        \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
                "        \"version\": \"v1\"\n" +
                "      }\n" +
                "    },\n" +
                "    {\n" +
                "      \"url\": \"https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1Mzg1NTIwMA==/c4901608-2b1e-4b6c-6358-031eb23eaa5c.mpeg\",\n" +
                "      \"profile\": {\n" +
                "        \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
                "        \"version\": \"v1\"\n" +
                "      }\n" +
                "    }\n" +
                "  ],\n" +
                "  \"params\": \"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{}}\",\n" +
                "  \"sync_timeout\": 30\n" +
                "}";

        Map<String, String> signedHeaders = signer.sign(url, method, headers, body);
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setRequestMethod(method);
        for (Map.Entry<String, String> entry : signedHeaders.entrySet()) {
            connection.setRequestProperty(entry.getKey(), entry.getValue());
        }
        connection.setDoOutput(true);
        connection.getOutputStream().write(body.getBytes(StandardCharsets.UTF_8));

        int status = connection.getResponseCode();
        InputStream stream = status >= 400
                ? connection.getErrorStream()
                : connection.getInputStream();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            System.out.println("Response: " + status + " " + response);
        }
    }
}