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): formulaMethod
POST
Content-Type: application/json
Authentication
Request Parameters
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | params | string | Algorithm parameters as a JSON string |
| Yes | init_images | object[] | List of media files; the original example passes the video first and the audio second |
| Yes | task | string | Fixed value: /v1/mt_vace_a2v/482306 |
| Yes | task_type | string | Fixed value: formula |
| No | sync_timeout | int | Defaults to 30; synchronous timeout in seconds |
The structure of each media item in init_images is described below.
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | url | string | Video or audio URL, or the corresponding media data encoded as base64 |
| Yes | profile | object | Media attribute description |
The profile object is described below.
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | media_profiles | object | Media attributes |
| Yes | version | string | Fixed value: v1 |
The media_profiles object is described below.
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | media_data_type | string | url indicates a URL; the corresponding media type indicates base64 data |
The params inference parameter is a JSON string with the following structure.
| Required | Field | Type | Description |
|---|---|---|---|
| No | rsp_media_type | string | Defaults to url; the corresponding media type indicates base64 data |
| Yes | parameter | object | Core 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.| Field | Type | Description |
|---|---|---|
| request_id | string | Request identifier |
| trace_id | string | Trace identifier |
| code | int | Business status code; 0 indicates that the request was accepted successfully |
| error_code | int | Error code; 0 indicates success |
| message | string | Business message |
| tips | any | Additional information; may be null |
| data | object | Task status and algorithm result |
Fields in data
| Field | Type | Description |
|---|---|---|
| status | int | Status code: -1, task not found; 0, created; 1, processing; 2, failed; 9, timed out—use the query API; 10, succeeded |
| result | object | Algorithm result |
| progress | number | Task progress |
| predict_elapsed | int | Estimated processing time in milliseconds |
| create_time | int64 | Creation timestamp in milliseconds |
| task_id | string | Task ID |
| custom_task_id | string | Client-defined task ID |
| trace_id | string | Trace identifier within data |
| client_info | string | Client information |
| init_images | object[]/null | Input media echoed by the service |
Fields in result
| Field | Type | Description |
|---|---|---|
| id | int/string | Task ID; the source table specifies int, while the response example uses string |
| parameters | object | Task parameter information |
| code | int | Error code returned on failure |
| data | int/object | Task result data; the source table specifies int, while the response example uses object |
| data.duration | object | Duration information for each processing stage |
| data.duration.alg_process_time | int | Algorithm processing time |
| data.duration.created_timestamp | int | Creation timestamp |
| data.duration.pull_timestamp | int | Pull timestamp |
| data.duration.repost_time | int | Forwarding time |
| data.duration.upload_time | int | Upload time |
| data.duration.waiting_time | int | Waiting time |
| data.error_code | int | Algorithm error code |
| data.error_msg | string | Algorithm error message |
| data.extra | object | Additional information |
| data.media_info_list | object[] | Media information list |
| data.msg_id | string | Message ID |
| data.parameter | object/null | Algorithm parameter information |
| msg | long/string | Task message; the source table specifies long, while the response example uses string |
| msg_id | string | Message 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);
}
}
}