Portrait Enhancement (Ultimate)

Description

This API submits portrait enhancement requests. See the documentation details for the specific effects.

Version

5.0

Media Requirements

The input media must be a video.

  • Supported video codecs: h263, h264, h265, AV1, MPEG4, VP8, and VP9.
  • Video dimensions: PVG does not support videos at or below 144 × 144. Hardware codecs support a maximum long edge of 4096 pixels, and both the width and height must be even numbers.

API URL

Production host: https://openapi.meitu.com Task submission endpoint: https://openapi.meitu.com/api/v1/sdk/sync/push Task name (task): /v1/portrait_enhancement_pro/488148 Task type (task_type): formula

Method

POST

Content-Type: application/json

Authentication

Open Platform API Signature

Credits cannot be used to pay for API calls. Please visit the MV console to activate this API and purchase or manage resource packages.

Request Parameters

RequiredParameterTypeDescription
YesparamsstringAlgorithm parameters as a JSON string
Yesinit_imagesobject[]Input media list
YestaskstringFixed value: /v1/portrait_enhancement_pro/488148
Yestask_typestringFixed value: formula
Nosync_timeoutintSynchronous timeout in seconds; default: 30

init_images item fields:

RequiredParameterTypeDescription
YesurlstringVideo URL or base64-encoded video data
YesprofileobjectMedia profile

profile fields:

RequiredParameterTypeDescription
Yesmedia_profilesobjectMedia attributes
YesversionstringFixed value: v1

media_profiles fields:

RequiredParameterTypeDescription
Yesmedia_data_typestringurl indicates a URL; jpg indicates base64-encoded image data

params is a JSON string. After decoding, it has the following structure:

RequiredFieldTypeDescription
Norsp_media_typestringDefault: url; jpg indicates base64 output
YesparameterobjectAlgorithm-specific parameters

parameter fields:

RequiredParameterTypeDescription
Nosr_ratefloatVideo dimension scale factor in the range [1, +∞); the maximum output resolution does not exceed 4096; when set to 1 and the input resolution is at least 1080, the original dimensions are retained; default: 1
Noopen_degreeintWhether to enable enhancement-level adjustment: 1 enables it and 0 disables it; default: 0
Noassign_degreeintRestoration intensity in the range [0, 100]; effective when open_degree = 0; default: 80
Nohdv4_flagintBackground restoration version: 1 selects the new version (default) and 0 selects the legacy version; replaces client_pc; when using the legacy version, setting assign_degree = 70 is recommended

Request Example

{
  "task": "/v1/portrait_enhancement_pro/488148",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1NDkwNjQwMA==/4d0f2421-2c5a-4075-49d8-187624c5a4c5.mp4",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"assign_degree\":60}}",
  "sync_timeout": 30
}

Response Fields

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

data fields:

FieldTypeDescription
statusint-1: task not found; 0: created; 1: running; 2: failed; 9: timed out and requires the query API; 10: succeeded
resultobjectAlgorithm result
progressnumberTask progress in the range 0–1
predict_elapsedintEstimated processing time in milliseconds
create_timeint64Creation timestamp in milliseconds
task_idstringTask ID
custom_task_idstringClient-supplied custom task ID
trace_idstringTrace identifier
client_infostringClient information
init_imagesobject[]/nullEcho of input media

result fields:

FieldTypeDescription
idstringUnique task identifier
urlsstring[]Output media URL list
imagesstring[]Output media (compatibility field)
msgstringResponse message
msg_idstringMessage ID
parametersobjectOutput parameter information
dataobjectDetailed processing result
media_info_listobject[]Media information list
mtlab_resobjectUnderlying service response

result.parameters fields:

FieldTypeDescription
rsp_media_typestringOutput media type, such as url
versionstringAlgorithm version, for example HDVideov5 version: 1.1.0

result.data fields:

FieldTypeDescription
durationobjectProcessing time for each stage
error_codenumberError code
error_msgstringError message
extraobjectAdditional information
media_info_listobject[]Media information
msg_idstringMessage ID
parameterobjectParameter information (same as parameters)

duration fields:

FieldTypeDescription
alg_process_timenumberAlgorithm processing time in milliseconds
created_timestampnumberCreation time as a Unix timestamp in seconds
pull_timestampnumberPull time
repost_timenumberRetry time
upload_timenumberUpload time
waiting_timenumberQueueing time

extra fields:

FieldTypeDescription
algo_msgobjectInternal algorithm information
sale_pathstringAPI path
trans_metaobjectTranscoding information

algo_msg fields:

FieldTypeDescription
alg_timefloatAlgorithm execution time in seconds

trans_meta.req_meta input fields:

FieldTypeDescription
durationfloatInput media duration
media_typestringMedia type

trans_meta.rsp_meta output fields:

FieldTypeDescription
data_ratefloatVideo bitrate
durationnumberVideo duration
frame_numnumberTotal frame count
frame_ratenumberFrame rate
widthnumberVideo width
heightnumberVideo height
resolutionstringResolution
sizenumberFile size in bytes
media_typestringMedia type

media_info_list fields:

FieldTypeDescription
media_datastringOutput video URL
media_extraobject/nullAdditional information
media_profilesobjectMedia attributes

media_profiles fields:

FieldTypeDescription
media_data_fpsnumberFrame rate
media_data_widthnumberVideo width
media_data_heightnumberVideo height
media_data_sizenumberFile size in bytes
media_data_typestringMedia type, such as url

mtlab_res fields:

FieldTypeDescription
ErrorCodenumberError code
ErrorMsgstringError message
error_codenumberError code (compatibility field)
error_msgstringError message (compatibility field)
media_info_listobject[]/nullMedia information
msg_idstringMessage ID
parameterobject/nullParameter information

Response Examples

Successful Response Example

{
  "request_id": "",
  "trace_id": "",
  "code": 0,
  "error_code": 0,
  "message": "success",
  "tips": null,
  "data": {
    "status": 10,
    "result": {
      "id": "t_mt1a3i5n7b259a74f1-xxxx-4a67-a959-2b5608b29289",
      "urls": [
        "https://obs-large.mtlab.meitu.com/mtopen/4e200dc6bf574fee899cf9e0dabe27e6/83b9c64a-75de-4e90-4741-b376301ba3fa.mp4"
      ],
      "parameters": {
        "rsp_media_type": "url",
        "version": "HDVideov5 version: 1.1.0 - [feat] 1208 pruned vae"
      },
      "data": {
        "duration": {
          "alg_process_time": 21851,
          "created_timestamp": 1773741035,
          "pull_timestamp": 1773741035,
          "repost_time": 0,
          "upload_time": 540,
          "waiting_time": 201
        },
        "error_code": 0,
        "error_msg": "success",
        "extra": {
          "algo_msg": {
            "alg_time": 21.306300163269043
          },
          "sale_path": "/v5/hdvideo_async",
          "trans_meta": {
            "req_meta": [
              {
                "duration": 5100,
                "media_type": "video"
              }
            ],
            "rsp_meta": [
              {
                "data_rate": 57651.85597110972,
                "duration": 5099,
                "frame_num": 153,
                "frame_rate": 30,
                "height": 1536,
                "media_type": "video",
                "resolution": "1080P",
                "size": 39354947,
                "width": 1312
              }
            ]
          }
        },
        "media_info_list": [
          {
            "media_data": "https://obs-large.mtlab.meitu.com/mtopen/4e200dc6bf574fee899cf9e0dabe27e6/83b9c64a-75de-4e90-4741-b376301ba3fa.mp4",
            "media_extra": null,
            "media_profiles": {
              "media_data_fps": 30,
              "media_data_height": 1536,
              "media_data_size": 39354947,
              "media_data_type": "url",
              "media_data_width": 1312
            }
          }
        ],
        "msg_id": "f224adb4-bbce-xxxx-5096-r0097d794edf",
        "parameter": {
          "rsp_media_type": "url",
          "version": "HDVideov5 version: 1.1.0 - [feat] 1208 pruned vae"
        }
      },
      "msg": "success",
      "msg_id": "f224adb4-bbce-xxxx-5096-r0097d794edf",
      "images": [
        "https://obs-large.mtlab.meitu.com/mtopen/4e200dc6bf574fee899cf9e0dabe27e6/83b9c64a-75de-4e90-4741-b376301ba3fa.mp4"
      ],
      "mtlab_res": {
        "ErrorCode": 0,
        "ErrorMsg": "",
        "error_code": 0,
        "error_msg": "",
        "media_info_list": null,
        "msg_id": "f224adb4-xxxx-490b-5096-r0097d794edf",
        "parameter": null
      },
      "media_info_list": [
        {
          "media_data": "https://obs-large.mtlab.meitu.com/mtopen/4e200dc6bf574fee899cf9e0dabe27e6/83b9c64a-75de-4e90-4741-b376301ba3fa.mp4",
          "media_extra": null,
          "media_profiles": {
            "media_data_fps": 30,
            "media_data_height": 1536,
            "media_data_size": 39354947,
            "media_data_type": "url",
            "media_data_width": 1312
          }
        }
      ]
    },
    "progress": 1,
    "predict_elapsed": 10000,
    "create_time": 1773741035373,
    "task_id": "t_mt1a3i5n7b259a74f1-xxxx-4a67-a959-2b5608b29289",
    "custom_task_id": "",
    "trace_id": "",
    "client_info": "",
    "init_images": null
  }
}

Pending 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": "t_mt1a3i5n7b259a74f1-xxxx-4a67-a959-2b5608b29289"
    },
    "progress": 0,
    "predict_elapsed": 10000,
    "create_time": 1773741035373,
    "task_id": "t_mt1a3i5n7b259a74f1-xxxx-4a67-a959-2b5608b29289",
    "custom_task_id": "",
    "trace_id": "1607a9d0-xxxx-4cec-ba59-2a8ca2e1d288",
    "client_info": "",
    "init_images": null
  }
}

Failed Response Example

Response Status: 400

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

{
  "request_id": "",
  "trace_id": "",
  "code": 20001,
  "error_code": 20001,
  "message": "PROCESS_ERROR",
  "tips": null,
  "data": {
    "status": 2,
    "result": {
      "error_code": 20001,
      "error_msg": "PROCESS_ERROR"
    },
    "progress": 0,
    "predict_elapsed": 0,
    "create_time": 0,
    "task_id": "",
    "custom_task_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": {"assign_degree": 60},
    }
    payload = {
        "task": "/v1/portrait_enhancement_pro/488148",
        "task_type": "formula",
        "init_images": [
            {
                "url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1NDkwNjQwMA==/4d0f2421-2c5a-4075-49d8-187624c5a4c5.mp4",
                "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/portrait_enhancement_pro/488148",
  "task_type": "formula",
  "init_images": [{
    "url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1NDkwNjQwMA==/4d0f2421-2c5a-4075-49d8-187624c5a4c5.mp4",
    "profile": {
      "media_profiles": {"media_data_type": "url"},
      "version": "v1"
    }
  }],
  "params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"assign_degree\":60}}",
  "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' => ['assign_degree' => 60],
]);

$body = json_encode([
    'task' => '/v1/portrait_enhancement_pro/488148',
    'task_type' => 'formula',
    'init_images' => [
        [
            'url' => 'https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1NDkwNjQwMA==/4d0f2421-2c5a-4075-49d8-187624c5a4c5.mp4',
            '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/portrait_enhancement_pro/488148\",\n" +
                "  \"task_type\": \"formula\",\n" +
                "  \"init_images\": [{\n" +
                "    \"url\": \"https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc1NDkwNjQwMA==/4d0f2421-2c5a-4075-49d8-187624c5a4c5.mp4\",\n" +
                "    \"profile\": {\n" +
                "      \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
                "      \"version\": \"v1\"\n" +
                "    }\n" +
                "  }],\n" +
                "  \"params\": \"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{\\\"assign_degree\\\":60}}\",\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);
        }
    }
}