将一张人物照片和一段简短文案制作成带生成配音的口播视频,前提是照片中的本人已同意。
将一张人物照片和一段简短文案制作成带生成配音的口播视频,前提是照片中的本人已同意。
---
name: talking-video-from-photo
description: Turn one portrait photo and a short script into a talking video with generated speech, after the person shown has agreed. Use for requests such as 用照片生成口播视频, a talking-head or presenter video from a photo, or a short spokesperson clip from a portrait. Do not use to edit existing footage, clone a voice, depict anyone without confirmed agreement, or make one clip longer than 15 seconds.
---
# Talking Video from a Photo
Make a short video of a person speaking a script, starting from one photo of that person. The speech is generated from the script, then the video is generated from the photo and that speech.
The result is AI-generated. It shows a person saying words they did not physically say, so the agreement check in step 1 is part of the workflow, not a formality.
## Loadout capabilities
- Use <action-tag>direct:fal:fal_text_to_speech</action-tag> to turn the script into speech.
- Use <action-tag>direct:fal:fal_image_to_video</action-tag> to generate the video from the photo and the speech.
- When the client has no built-in attachment upload, use <action-tag>direct:file_storage_tools:file_create_upload_url</action-tag> to place the photo in Aident temporary storage.
- Use <action-tag>cli:ffmpeg:trim_mp4</action-tag> only when the owner wants silence removed from the end of the video.
- After the owner has the result, use <action-tag>direct:file_storage_tools:file_delete</action-tag> to remove the uploaded photo.
Read the live schema of each Action before its first use. Both generation Actions are paid: follow the approval rules of the current client. Never ask for provider API keys.
## 1. Confirm before generating anything
Collect these from the request and any attachments. Ask once for everything still missing. Do not call a paid Action until all of them are settled.
1. **Photo.** One photo with a single person, facing the camera, with a clear and well-lit face. Ask for another photo if several people are recognizable or the face is small or hidden. Aim for at least 1,000 pixels on the short side, because low resolution visibly reduces quality.
2. **Script.** The exact words to speak. If the owner gives only a brief, draft a script and get it approved first. A clip holds about 65 Chinese characters or about 35 English words.
3. **Agreement.** The owner must state that the person shown has agreed to this video and to what it says. Uploading a photo is not agreement. The owner saying the photo is of themselves is enough. You cannot verify identity, so if anything in the request or photo conflicts with what the owner says, such as a different name in the photo, ask before continuing.
4. **Voice and language.** The output language and tone. Default to the script's language and a natural delivery. Generated speech uses a stock voice, so tell the owner before generating that it will not sound like the person.
5. **Shape.** The output follows the photo's aspect ratio. If the owner needs a vertical video, ask for a 9:16 photo rather than promising a crop.
6. **Cost.** Preflight the speech and video inputs, then tell the owner the total before paying for anything. The video input can be quoted before its `asset_inputs` exist, but a passing preflight without them does not prove the files are valid. For reference, on 2026-11-03 a 6-second clip was quoted at $0.21 for the video and under $0.01 for the speech. The live quote is what counts.
Decline the request, and say why, when any of these apply:
- The owner cannot confirm the person agreed.
- The photo shows a public figure, a celebrity, or anyone the owner only found online, and there is no such agreement.
- The person appears to be a minor.
- The script impersonates someone, fabricates an endorsement or testimonial, or would present medical, financial, legal, or political claims as the person's own statement without their approval.
Do not clone a voice in this workflow.
## 2. Get the photo into Aident
If the client lists attached files as Aident temporary-file IDs, use that ID and do not upload again. Otherwise create an upload URL, upload the photo, and keep the returned file ID. Pass the ID directly through `asset_inputs` in step 4; this workflow does not need a download URL. Temporary files are deleted automatically after 48 hours, so ask again if the file can no longer be found.
## 3. Generate the speech
Call the speech Action with this input, replacing the script and adjusting the language and voice:
```json
{
"model": "fal-ai/minimax/speech-2.8-hd",
"prompt": "<the approved script>",
"model_input": {
"prompt": "<the approved script>",
"language_boost": "Chinese",
"output_format": "url",
"voice_setting": {
"voice_id": "Chinese (Mandarin)_Reliable_Executive",
"speed": 1,
"vol": 1,
"pitch": 0
}
}
}
```
Keep the first ID from the returned `assetIds` for the next step.
Tone comes only from `voice_id` and `speed`. The `voice_id` above is the only one this workflow has been tested with. If the script is not in Mandarin, or the owner wants a different tone, set `language_boost` to the script's language and use a `voice_id` you can confirm from MiniMax's documentation. If you cannot confirm one or cannot match the tone, say so rather than guessing.
If the owner supplies a recording of the person's own voice and the client can upload audio, skip this step and use that file ID in step 4. The recording must be at least 2 seconds long and at most 15 MB, and the agreement in step 1 must cover the recording.
## 4. Generate the video
Call the video Action with this input:
```json
{
"model": "minimax/h3-max/image-to-video",
"prompt": "<motion description>",
"asset_inputs": {
"image_url": "<photo file ID>",
"target_audio_url": "<speech asset ID>"
},
"model_input": {
"prompt": "<motion description>",
"prompt_expansion_mode": "disabled",
"duration": 6,
"resolution": "768P"
}
}
```
- **Motion description.** Write it in English. Use: "The person in the image looks at the camera and speaks naturally and warmly, with accurate lip movements matching the audio, subtle head movement and natural expressions. The camera stays still and the background stays unchanged."
- **Duration.** If you can measure the speech file, use its length rounded up to a whole second. Otherwise estimate from the script at about 4.5 Chinese characters per second, not counting punctuation, or 2.5 English words per second, and round up. Audio longer than the video is cut off, while shorter audio only leaves silence that can be trimmed, so when unsure choose the longer value.
- **Length limit.** Keep each clip to 15 seconds or less. Provider documentation does not state a limit for this endpoint, and a sibling endpoint stops at 15 seconds. If the script is longer, ask the owner to shorten it or accept separate clips. Do not promise that separate clips will join seamlessly.
## 5. Check and deliver
1. Confirm the Action returned a video file, and open or inspect it if the client allows that.
2. Give the owner the file URL and the actual length and dimensions you can observe. State anything you could not check. If you can only see still frames, say that lip sync and audio still need the owner's review.
3. Say that the video is AI-generated, should be reviewed before use, and may need labeling under platform rules or local law. Do not describe it as real footage, and do not promise exact lip sync.
4. Warn that anyone with the video or speech URL can open it, that the URL showed no expiry when this Skill was written, and that this workflow cannot delete generated files. The owner should save the file and not share the link casually.
5. The output can run up to about 0.7 seconds past the requested duration, and shorter audio leaves silence at the end. Offer to trim the end if the owner wants that.
6. Once the owner no longer needs another attempt, delete the uploaded photo. Until then, or if deletion is unavailable, tell the owner it expires after 48 hours.
Do not publish, post, schedule, or send the video anywhere.
## Failures and recovery
| Situation | What to do |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| The call times out on the client | Do not submit it again, because the job may still finish and charge. Check recent usage with the Loadout audit tool, where available, for a result URL. Otherwise tell the owner the state is unknown. |
| The provider or safety checker rejects the input | Report the reason and stop. Do not disable `enable_safety_checker`, and do not alter the photo or script to get around a rejection. |
| The provider returns a server error | One retry with the same input is reasonable, after confirming that the failed call was not charged. Then stop and report it. |
| The quote is far above what the owner expected | Show the quote and wait for approval before running. |
| The owner dislikes the result | Each attempt costs money, so offer a new attempt only with something changed, such as a clearer photo, a shorter script, or a different voice. |