Remove subtitles and watermarks in one click
Description
Submit a video for one-click cleanup. Processing is asynchronous.
Version
1.0
Video Requirements
Only video input by URL is supported. The source does not specify codec, file size, resolution, or duration limits.
Request URL
Task submission endpoint:
https://openapi.meitu.com/api/v1/sdk/sync/pushTask name (task): /v1/Video_Remove/496462
Task type (task_type): formula
HTTP Method
POST
Content-Type: application/json
Authentication
Use an AK/SK pair with access to this capability and sign requests with the signing SDK. See API Request Signing.
Request Parameters
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | task | string | Fixed value: /v1/Video_Remove/496462. |
| Yes | task_type | string | Fixed value: formula. |
| Yes | init_images | object[] | Input videos. The API field name remains init_images. |
| Yes | params | string | A JSON-serialized string containing the algorithm parameters. |
| No | sync_timeout | integer | Synchronous waiting period in seconds. Default: 30. |
init_images Element
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | url | string | Input video URL. Do not Base64-encode it. |
| Yes | profile | object | Video properties. |
profile
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | version | string | Gateway media configuration version. Fixed value: v1. |
| Yes | media_profiles | object | Video transfer and processing properties. |
media_profiles
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | media_data_type | string | url is used as in the source request example, indicating a video URL. |
| No | skip_frames | array | [a,b]: skip a frames at the beginning and b frames at the end, for slicing. Default: [0,0]. |
| No | encoder_rate_scale | number | Video encoding bitrate scaling factor. The source specifies no default or range. |
params
params must be a JSON string. The decoded object contains:
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | parameter | object | Video cleanup parameters. |
| No | extra | object | Additional processing information in the algorithm protocol. Omit when not needed. |
parameter
| Required | Parameter | Type | Description |
|---|---|---|---|
| No | userboxes | string | User interaction box coordinates as a string. Each box has four relative coordinate points in this order: top-left, top-right, bottom-right, bottom-left. No boxes by default. |
| No | protectboxes | string | Protected-region box coordinates as a string, in the same point order as userboxes. No boxes by default. |
Example string value for one box:
[[0.1,0.1],[0.2,0.1],[0.2,0.2],[0.1,0.2]]When specifying boxes, the decoded params object can be structured as follows. userboxes and protectboxes remain strings, not arrays:
{
"parameter": {
"userboxes": "[[0.1,0.1],[0.2,0.1],[0.2,0.2],[0.1,0.2]]",
"protectboxes": "[[0.6,0.6],[0.8,0.6],[0.8,0.8],[0.6,0.8]]"
}
}The source allows multiple boxes but does not define how they are grouped, so no multi-box example is provided. Its input media type table uses MP4, inconsistent with url in its request example. Video input here follows the source example's URL-based approach.
Request Example
This example specifies one interaction box through userboxes, with no protected region. Replace the video URL and box coordinates as needed.
{
"task": "/v1/Video_Remove/496462",
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/input.mp4",
"profile": {
"media_profiles": {
"media_data_type": "url",
"skip_frames": [
0,
0
]
},
"version": "v1"
}
}
],
"params": "{\"parameter\":{\"userboxes\":\"[[0.1,0.1],[0.2,0.1],[0.2,0.2],[0.1,0.2]]\"}}",
"sync_timeout": 30
}Response Fields
The descriptions below use the common gateway task wrapper. The exact result nesting for this task has not been verified against a response sample. Algorithm fields explicitly documented in the source are listed separately below.
| Field | Type | Description |
|---|---|---|
| code | integer | Gateway business status code. 0 indicates normal request processing, not necessarily task completion. |
| message | string | Gateway response message. |
| data | object | Task status and result. |
| data.task_id | string | Gateway task ID for Task Query. |
| data.status | integer | Task status; see below. |
| data.result | object | Result wrapper. The structural examples below place algorithm output in data.result.data. |
| data.status | Description |
|---|---|
| -1 | Task not found. |
| 0 | Task created. |
| 1 | Running. |
| 2 | Failed. |
| 9 | Synchronous wait timed out. Continue querying; this does not mean the algorithm failed. |
| 10 | Succeeded. |
result
| Field | Type | Description |
|---|---|---|
| id | string | Gateway task identifier. |
| code | integer | Algorithm status code. |
| msg | string | Algorithm response message. |
| msg_id | string | Algorithm request identifier; not a substitute for the gateway task_id. |
| data | object | Original algorithm response. |
Algorithm Result Fields
| Field | Type | Description |
|---|---|---|
| msg_id | string | Algorithm request identifier. The source states that this identifier and algorithm results are deleted after 24 hours. |
| media_info_list | object[] | Processing results. |
| media_info_list[].media_data | string | Result media data; a video URL in the URL-based structural example. |
| media_info_list[].media_profiles | object | Result media properties. |
| parameter | object | Output type, algorithm version, and removal status. |
| parameter.rsp_media_type | string | Output delivery type; url in the structural example. |
| parameter.version | string | Algorithm version. |
| parameter.exist_text | boolean | Whether removal was performed on the video. No removal is performed if no content to remove is detected. |
| error_code | integer | Algorithm error code in the source error response. |
| error_msg | string | Algorithm error message in the source error response. |
The source response field descriptions still refer to jpg / Base64 and provide no complete successful video response JSON. These descriptions are not treated as confirmation of Base64 video output support.
Use data.task_id, not the algorithm msg_id, for gateway queries. Query and save results promptly. The source's 24-hour statement applies to algorithm identifiers and results, not a confirmed gateway retention policy for this task.
Response Examples
These structural examples combine the common gateway template with algorithm fields from the source. They are not records of real API calls. The actual response for this task determines the field nesting, values, and error messages.
Success Structure Example
{
"code": 0,
"message": "success",
"data": {
"status": 10,
"task_id": "example-task-id",
"result": {
"id": "example-task-id",
"code": 0,
"msg": "success",
"msg_id": "example-message-id",
"data": {
"msg_id": "example-message-id",
"media_info_list": [
{
"media_data": "https://example.com/result.mp4",
"media_profiles": {
"media_data_type": "url"
}
}
],
"parameter": {
"rsp_media_type": "url",
"version": "1.0",
"exist_text": true
}
}
}
}
}Query Required Structure Example
If data.status = 9, use data.task_id with Task Query. Do not resubmit merely because the synchronous wait timed out.
{
"code": 0,
"message": "success",
"data": {
"status": 9,
"task_id": "example-task-id",
"result": {
"id": "example-task-id"
}
}
}Error Structure Example
The example uses 20001 / ALGO_MODEL_CRASH to illustrate an error structure. It does not mean that every failure returns this error.
{
"code": 20001,
"message": "ALGO_MODEL_CRASH",
"data": {
"status": 2,
"task_id": "example-task-id",
"result": {
"id": "example-task-id",
"code": 20001,
"msg": "ALGO_MODEL_CRASH",
"msg_id": "example-message-id",
"data": {
"error_code": 20001,
"error_msg": "ALGO_MODEL_CRASH",
"msg_id": "example-message-id"
}
}
}
}Common Error Codes
See API Error Codes.
SDK Examples
Each example embeds the complete request body and requires no separate JSON file. Set up the SDK for your language and replace the AK, SK, and video URL.
The examples submit once and print the response. If the task has not completed, retrieve its result using Task Query.
Python
import json
import requests
from sign_sdk import sign
def main():
key = "YOUR_ACCESS_KEY"
secret = "YOUR_SECRET_KEY"
url = "https://openapi.meitu.com/api/v1/sdk/sync/push"
params = {
"parameter": {
"userboxes": "[[0.1,0.1],[0.2,0.1],[0.2,0.2],[0.1,0.2]]"
}
}
payload = {
"task": "/v1/Video_Remove/496462",
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/input.mp4",
"profile": {
"media_profiles": {
"media_data_type": "url",
"skip_frames": [
0,
0
]
},
"version": "v1"
}
}
],
"params": json.dumps(params, ensure_ascii=True),
"sync_timeout": 30
}
body = json.dumps(payload, ensure_ascii=True)
headers = {
"Content-Type": "application/json",
sign.HeaderHost: "openapi.meitu.com",
}
signer = sign.Signer(key, secret)
signed_request = signer.sign(url, "POST", headers, body)
with requests.Session() as session:
response = session.send(
signed_request, timeout=(10, 60), verify=True, allow_redirects=False
)
print("Status:", response.status_code)
print("Response:", response.text)
if __name__ == "__main__":
main()Go
package main
import (
"fmt"
"io"
"net/http"
"time"
"github.com/mtlab/api/signer"
)
func main() {
body := `{
"task": "/v1/Video_Remove/496462",
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/input.mp4",
"profile": {
"media_profiles": {
"media_data_type": "url",
"skip_frames": [
0,
0
]
},
"version": "v1"
}
}
],
"params": "{\"parameter\":{\"userboxes\":\"[[0.1,0.1],[0.2,0.1],[0.2,0.2],[0.1,0.2]]\"}}",
"sync_timeout": 30
}`
url := "https://openapi.meitu.com/api/v1/sdk/sync/push"
headers := make(http.Header)
headers.Set("Content-Type", "application/json")
headers.Set(signer.HeaderHost, "openapi.meitu.com")
signObj := signer.NewSigner("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY")
req, err := signObj.Sign(url, http.MethodPost, headers, body)
if err != nil {
fmt.Println("Sign request failed:", err)
return
}
client := &http.Client{
Timeout: 60 * time.Second,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Send request failed:", err)
return
}
defer resp.Body.Close()
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Read response failed:", err)
return
}
fmt.Println("Status:", resp.StatusCode)
fmt.Println("Response:", string(responseBody))
}PHP
<?php
require_once __DIR__ . '/signer.php';
$params = json_encode([
'parameter' => [
'userboxes' => '[[0.1,0.1],[0.2,0.1],[0.2,0.2],[0.1,0.2]]',
],
]);
$body = json_encode([
'task' => '/v1/Video_Remove/496462',
'task_type' => 'formula',
'init_images' => [
[
'url' => 'https://example.com/input.mp4',
'profile' => [
'media_profiles' => [
'media_data_type' => 'url',
'skip_frames' => [0, 0],
],
'version' => 'v1',
],
],
],
'params' => $params,
'sync_timeout' => 30,
], JSON_UNESCAPED_SLASHES);
$url = 'https://openapi.meitu.com/api/v1/sdk/sync/push';
$headers = [
'Content-Type' => 'application/json',
'Host' => 'openapi.meitu.com',
];
$signer = new Signer('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY');
$curl = $signer->sign($url, 'POST', $headers, $body);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
$response = curl_exec($curl);
if ($response === false) {
echo 'Error: ' . curl_error($curl) . PHP_EOL;
} else {
echo 'Status: ' . curl_getinfo($curl, CURLINFO_HTTP_CODE) . PHP_EOL;
echo 'Response: ' . $response . PHP_EOL;
}
curl_close($curl);Java
import com.meitu.openai.common.Signer;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
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 {
String body =
"{\n" +
" \"task\": \"/v1/Video_Remove/496462\",\n" +
" \"task_type\": \"formula\",\n" +
" \"init_images\": [\n" +
" {\n" +
" \"url\": \"https://example.com/input.mp4\",\n" +
" \"profile\": {\n" +
" \"media_profiles\": {\n" +
" \"media_data_type\": \"url\",\n" +
" \"skip_frames\": [\n" +
" 0,\n" +
" 0\n" +
" ]\n" +
" },\n" +
" \"version\": \"v1\"\n" +
" }\n" +
" }\n" +
" ],\n" +
" \"params\": \"{\\\"parameter\\\":{\\\"userboxes\\\":\\\"[[0.1,0.1],[0.2,0.1],[0.2,0.2],[0.1,0.2]]\\\"}}\",\n" +
" \"sync_timeout\": 30\n" +
"}";
String url = "https://openapi.meitu.com/api/v1/sdk/sync/push";
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put(Signer.HeaderHost, "openapi.meitu.com");
Signer signer = new Signer("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");
Map<String, String> signedHeaders = signer.sign(url, "POST", headers, body);
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
try {
connection.setRequestMethod("POST");
connection.setConnectTimeout(10000);
connection.setReadTimeout(60000);
connection.setInstanceFollowRedirects(false);
connection.setDoOutput(true);
for (Map.Entry<String, String> entry : signedHeaders.entrySet()) {
connection.setRequestProperty(entry.getKey(), entry.getValue());
}
byte[] bodyBytes = body.getBytes(StandardCharsets.UTF_8);
connection.setFixedLengthStreamingMode(bodyBytes.length);
try (OutputStream output = connection.getOutputStream()) {
output.write(bodyBytes);
}
int status = connection.getResponseCode();
System.out.println("Status: " + status);
InputStream responseStream = status >= 400
? connection.getErrorStream() : connection.getInputStream();
if (responseStream != null) {
try (InputStream input = responseStream;
ByteArrayOutputStream output = new ByteArrayOutputStream()) {
byte[] buffer = new byte[4096];
int length;
while ((length = input.read(buffer)) != -1) {
output.write(buffer, 0, length);
}
System.out.println("Response: " + output.toString("UTF-8"));
}
}
} finally {
connection.disconnect();
}
}
}