Use these scenarios when you want an AI coding assistant, bot, or internal automation tool to prove that a Weydub API integration works end to end.
The scenarios use public demo assets and the same double-MD5 signing model described in Auth and signing. Provide credentials through environment variables only.
Demo Assets
| Asset | URL | Recommended Tests |
|---|---|---|
| English source video | http://gc9.cdn.izhaoli.cn/ghostcut_demo/TextRemoval_Dubbing_Eng.mp4 | Advanced subtitle/text removal; English-to-Spanish video translation. |
| Chinese source video | http://gc9.cdn.izhaoli.cn/ghostcut_demo/HighEmotion_Dubbing_cn2en.mp4 | High-emotion voice cloning and Chinese-to-English dubbing. |
| Chinese annotation JSON | http://gc9.cdn.izhaoli.cn/ghostcut_demo/HighEmotion_Dubbing_cn2en.json | Customer input for high-emotion voice cloning. |
Environment
export WEYDUB_APP_KEY="your_app_key"
export WEYDUB_APP_SECRET="your_app_secret"Scenario 1: Advanced Subtitle And Text Removal
Use the English source video and the Advanced Pro full-screen inpainting model.
{
"urls": ["http://gc9.cdn.izhaoli.cn/ghostcut_demo/TextRemoval_Dubbing_Eng.mp4"],
"needChineseOcclude": 1,
"videoInpaintLang": "all",
"extraOptions": "{\"extra_inpaint_config\":{\"model\":\"advanced_full\"}}"
}Endpoint:
POST /v-w-c/gateway/ve/work/freeScenario 2: Video Translation With Dubbing
Translate the English source video to Spanish, generate subtitles, and dub it with a high-quality voice.
{
"urls": ["http://gc9.cdn.izhaoli.cn/ghostcut_demo/TextRemoval_Dubbing_Eng.mp4"],
"needWanyin": 1,
"sourceLang": "en",
"lang": "es",
"wyTaskType": "FULL",
"wyNeedText": 1,
"wyVoiceParam": "{\"voice_type\":\"CLONE\",\"character_voices\":[{\"character\":\"role_default\",\"id\":102052}],\"font_param\":{\"style\":\"tpl-31-1-T\",\"font_size\":32,\"position\":0.8}}"
}Endpoint:
POST /v-w-c/gateway/ve/work/freeScenario 3: High-Emotion Voice Cloning
Use the Chinese video and paired JSON to run Chinese-to-English high-emotion voice cloning. This scenario is best for short drama, film, and character-driven content because the model can preserve actor timbre, emotion, and spatial feeling from the original clip.
{
"urls": ["http://gc9.cdn.izhaoli.cn/ghostcut_demo/HighEmotion_Dubbing_cn2en.mp4"],
"incorporatePro": true,
"sourceLang": "zh",
"lang": "en",
"extraOptions": "{\"customer_input\":{\"url\":\"http://gc9.cdn.izhaoli.cn/ghostcut_demo/HighEmotion_Dubbing_cn2en.json\"}}"
}Endpoint:
POST /v-w-c/gateway/ve/work/voice/incorporatePython Template
import hashlib
import json
import os
import time
import requests
APP_KEY = os.environ["WEYDUB_APP_KEY"]
APP_SECRET = os.environ["WEYDUB_APP_SECRET"]
BASE_URL = "https://api.zhaoli.com"
DEMO_ENG_VIDEO = "http://gc9.cdn.izhaoli.cn/ghostcut_demo/TextRemoval_Dubbing_Eng.mp4"
DEMO_CN_VIDEO = "http://gc9.cdn.izhaoli.cn/ghostcut_demo/HighEmotion_Dubbing_cn2en.mp4"
DEMO_CN_JSON = "http://gc9.cdn.izhaoli.cn/ghostcut_demo/HighEmotion_Dubbing_cn2en.json"
def api_post(path: str, payload: dict) -> dict:
body = json.dumps(payload, ensure_ascii=False, separators=(",", ":"))
body_md5 = hashlib.md5(body.encode("utf-8")).hexdigest()
app_sign = hashlib.md5((body_md5 + APP_SECRET).encode("utf-8")).hexdigest()
headers = {
"Content-Type": "application/json",
"AppKey": APP_KEY,
"AppSign": app_sign,
}
response = requests.post(f"{BASE_URL}{path}", headers=headers, data=body, timeout=30)
response.raise_for_status()
return response.json()
def extract_work_ids(response: dict) -> list[int]:
body = response.get("body") or {}
data_list = body.get("dataList") or body.get("content") or []
if isinstance(data_list, dict):
data_list = [data_list]
return [item["id"] for item in data_list if isinstance(item, dict) and item.get("id")]
def wait_for_work(work_id: int) -> dict:
while True:
status = api_post("/v-w-c/gateway/ve/work/status", {"idWorks": [work_id]})
item = ((status.get("body") or {}).get("content") or [{}])[0]
process_status = item.get("processStatus")
if process_status == 1:
return item
if isinstance(process_status, int) and process_status > 1:
raise RuntimeError(item.get("errorDetail") or f"Task {work_id} failed")
print(f"Task {work_id} processing...")
time.sleep(10)
scenarios = [
(
"advanced_text_removal",
"/v-w-c/gateway/ve/work/free",
{
"urls": [DEMO_ENG_VIDEO],
"needChineseOcclude": 1,
"videoInpaintLang": "all",
"extraOptions": json.dumps(
{"extra_inpaint_config": {"model": "advanced_full"}},
separators=(",", ":"),
),
},
),
(
"video_translation_en_to_es",
"/v-w-c/gateway/ve/work/free",
{
"urls": [DEMO_ENG_VIDEO],
"needWanyin": 1,
"sourceLang": "en",
"lang": "es",
"wyTaskType": "FULL",
"wyNeedText": 1,
"wyVoiceParam": json.dumps(
{
"voice_type": "CLONE",
"character_voices": [{"character": "role_default", "id": 102052}],
"font_param": {"style": "tpl-31-1-T", "font_size": 32, "position": 0.8},
},
separators=(",", ":"),
),
},
),
(
"high_emotion_clone_zh_to_en",
"/v-w-c/gateway/ve/work/voice/incorporate",
{
"urls": [DEMO_CN_VIDEO],
"incorporatePro": True,
"sourceLang": "zh",
"lang": "en",
"extraOptions": json.dumps(
{"customer_input": {"url": DEMO_CN_JSON}},
separators=(",", ":"),
),
},
),
]
for name, path, payload in scenarios:
print(f"Submitting {name}...")
response = api_post(path, payload)
print(json.dumps(response, ensure_ascii=False, indent=2))
for work_id in extract_work_ids(response):
result = wait_for_work(work_id)
print(f"{name} done:", result.get("videoUrl") or result.get("tgtSrtUrl") or result)Local Repo Helper
This repository also includes a safe helper script:
python3 scripts/run-weydub-api-demos.py --dry-run
python3 scripts/run-weydub-api-demos.py --scenario removal --submitThe helper reads WEYDUB_APP_KEY and WEYDUB_APP_SECRET from environment variables. It does not store credentials.
Notes For AI Assistants
- Keep
extraOptionsandwyVoiceParamas compact JSON strings. - Use
json.dumps(..., separators=(",", ":"))before signing. - Poll
/v-w-c/gateway/ve/work/statuswith returned work IDs. - Prefer callback webhooks for production systems.
- Never put
AppSecretin frontend code or files committed to a repository.