A newer version of the Gradio SDK is available: 6.22.0
title: AI Talking Photo
emoji: ποΈ
colorFrom: indigo
colorTo: purple
sdk: gradio
sdk_version: 6.9.0
app_file: app.py
pinned: false
suggested_hardware: cpu-basic
startup_duration_timeout: 10m
fullWidth: true
AI Talking Photo
Banuba AI Talking Photo lets users create realistic talking videos from a single photo, with a simple, intuitive workflow that anyone can understand. It transforms static images into lifelike talking avatars with natural lip-sync, facial expressions, and full-body motion β delivering studio-quality presentations, lessons, and other videos without cameras, actors, or editing. It supports any language, and reliably outputs content up to 1 hour long.
This Space is a free, hosted demo built on the Banuba AI Tasks API: no video
generation happens in the Space itself β it uploads your reference image and audio,
creates a video.lipsync task, and shows the result video once it is ready.
Demo limits: this showcase outputs 480p video capped at 1β10 seconds (set by the Maximum duration field, default 4s). The full product supports the longer, higher-resolution output described above β for production use email support@banuba.com or use the contact form at banuba.com.
How to use
- Upload a reference image β a clear, front-facing portrait works best.
- Upload a reference audio clip β the voice the photo will lip-sync to. (Or click one of the ready-made examples under the inputs.) You can trim the clip directly in the audio player if you want a specific section.
- (Optional) Edit the Prompt. The field is pre-filled with a sensible default. The prompt guides how the avatar performs β framing, delivery, gestures, lighting and background. Leave it as-is, or tweak it to change the style. If you clear it, the default is used.
- (Optional) Set the Maximum duration (default 4 seconds, 1β10s) β the length of the generated video.
- Click Generate Talking Photo.
- Wait while the task runs β generation usually takes a couple of minutes. You can leave the page and return from the same browser; the Space resumes and keeps polling your latest task.
- The finished video appears in the Output panel. Press play to watch it.
About the API
The Space is built on the Banuba AI Tasks API (https://ai.banuba.net/api/v1).
Calling it requires a client_id / client_secret issued by Banuba.
The end-to-end flow is four steps.
1. Get an access token (OAuth2 client credentials)
curl -X POST https://ai.banuba.net/auth/v1/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "scope=tasks:write tasks:read" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET"
2. Request an upload URL, then upload each asset
# Ask for a presigned upload location
curl -X POST https://ai.banuba.net/api/v1/upload \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"filename": "portrait.png", "content_type": "image/png"}'
# -> { "url": "<asset-url>", "upload_url": "<presigned-put-url>" }
# Upload the file bytes to the presigned URL
curl -X PUT "<presigned-put-url>" \
-H "Content-Type: image/png" \
--data-binary @portrait.png
Repeat for the audio file. Keep each returned url β those are the asset URLs
you pass to the task.
3. Create a video.lipsync task
curl -X POST https://ai.banuba.net/api/v1/tasks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "video.lipsync",
"input": {
"assets": {
"image": { "url": "<image-asset-url>" },
"audio": { "url": "<audio-asset-url>" }
},
"seconds": 4,
"seed": 7,
"prompt": "Waist-up, direct-to-camera, natural gestures, neutral background"
}
}'
# -> { "id": "<task-id>", ... }
seconds, seed, and prompt are optional. Omit seconds to let the API use
min(audio_duration_seconds, 10).
The prompt is a free-text instruction that steers the performance β
framing, delivery, gestures, lighting and background. If you omit it, the API
applies its own defaults. This Space sends the following prompt unless you edit
the field in the UI:
Waist-up, direct-to-camera. I read the script confidently and friendly, with natural hand gestures timed to speech, brief pauses, subtle facial expressions. Even lighting, neutral background, steady camera.
4. Poll the task until it finishes
curl https://ai.banuba.net/api/v1/tasks/<task-id> \
-H "Authorization: Bearer $TOKEN"
# -> { "status": "COMPLETED",
# "result": { "result_file_url": "<video-url>", "content_type": "video/mp4" } }
When status is COMPLETED, download the video from result.result_file_url.