You generated a nice 5 to 10 second clip with an AI video model, and now you need 20 seconds of it. Most video APIs cap a single generation at a few seconds, so "just make it longer" is not an option. The standard workaround is to continue the clip from where it ended, and the details of doing that cleanly are where most of the time goes. This post walks through the three common approaches, what you have to handle if you build the stitching yourself, and how to get the same result from one API request.
The three ways to extend a clip
| Approach | How it works | Pros | Cons |
|---|---|---|---|
| Native continuation | The model itself accepts a video and keeps going | Best motion and scene continuity, no stitching on your side | Only a few models offer it; you still get a separate file unless the provider joins it |
| Last frame as first frame | Grab the final frame of your clip, feed it to an image-to-video model, then concatenate the two files | Works with any image-to-video model | Visible seams unless you handle frames, sound, color and format; motion direction is not remembered |
| Reference tail | Pass the last few seconds of your clip to a model that accepts reference video, then concatenate | Carries over motion and some sound context | Needs a model with reference-video input and a clip-length limit; still needs joining |
Native continuation is the nicest when it exists, but it is rare. Last-frame continuation is the one you can do with almost anything, so it is the one worth getting right. The rest of this post is about it.
What last-frame stitching actually involves
The idea fits in one sentence. The practice is a checklist.
1. Extract the last frame. With ffmpeg that looks like this:
ffmpeg -sseof -1 -i clip.mp4 -update 1 -q:v 1 last.png
-sseof -1 seeks one second before the end, and -update 1 keeps overwriting the output so the file you end up with is the final decoded frame. Mind the rotation metadata on phone footage and the color range of the source, otherwise the frame you send to the model looks slightly different from what the viewer sees.
2. Generate the continuation from that frame with your image-to-video model of choice.
3. Drop the duplicate frame. The new segment starts on the frame your clip ended on. If you concatenate naively, the viewer sees a one-frame stall at the join. Some models also start with a few static frames or a brightness flash, so check the first handful of frames.
4. Match the format. Concatenation only works cleanly when both pieces agree on resolution, aspect ratio, frame rate and pixel format. Models often return a different frame rate than your source (24 fps against 30 fps is common) and sometimes a slightly different frame size. You have to scale, crop or pad, and choose which one you are willing to distort.
5. Fix the sound seam. If both pieces have audio, a hard cut produces a click and often a jump in loudness. You want a short crossfade and some loudness matching. If one piece is silent, pad it with silence so the audio track does not end early.
6. Re-encode or stream copy? Stream copy (-c copy) is fast and lossless, but it only works when both files share codec, profile, timebase and parameter sets. Otherwise you must re-encode, which costs time and a little quality. In practice you end up with both paths in your code.
7. Watch the color. The new segment's first frame can be a shade brighter or darker than your clip's last frame. A slight shift is noticeable exactly at the cut.
None of this is hard in isolation. Together it is a few hundred lines of ffmpeg glue plus a worker to run it, and every model you add behaves a little differently.
The same thing with one request
SpicyAPI exposes this as a video-extend endpoint on 31 video model families. The examples below use Wan 3.0. You send the clip you want to continue, an optional prompt describing what happens next, and a length for the new segment. The last frame of your clip opens the new Wan 3.0 image-to-video shot, and the platform joins the pieces: it removes the duplicate frame, aligns the frame rate, crossfades the sound and returns the result.
The model id is alibaba/wan-3.0/video-extend. The input fields:
| Field | Notes |
|---|---|
video_url |
Required. The clip to continue: MP4, MOV or WebM, up to 60 seconds |
prompt |
Optional. What happens next: action, camera move, sound |
duration_seconds |
Length of the new segment, 2 to 30 (default 5), or -1 to let the model choose |
resolution |
480p, 720p (default) or 1080p
|
generate_audio |
Default true. Your source keeps its own sound either way |
last_image_url |
Optional target end frame for the new segment |
seed |
Optional |
With curl
The API is asynchronous: you create a task, then poll it. Set SPICY_API_KEY first.
curl -sS https://api.spicyapi.ai/api/v1/jobs/createTask \
-H "Authorization: Bearer $SPICY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: extend-$(date +%s)" \
-d '{
"model": "alibaba/wan-3.0/video-extend",
"input": {
"video_url": "https://example.com/my-clip.mp4",
"prompt": "The camera keeps tracking the cyclist as she turns into the sunlit street, long shadows, soft ambient city sound.",
"duration_seconds": 5,
"resolution": "720p"
}
}'
The response uses the usual {code, msg, data, request_id} envelope, and data.taskId is what you poll:
curl -sS "https://api.spicyapi.ai/api/v1/jobs/recordInfo?taskId=$TASK_ID" \
-H "Authorization: Bearer $SPICY_API_KEY"
The task moves through queued and running to succeeded. If you want to know the price before you commit, POST /api/v1/jobs/quote takes the same body and starts nothing.
What comes back
A finished task has two entries in output.assets, in a fixed order:
| Index | role |
Contents |
|---|---|---|
| 0 | video |
Your original clip and the continuation joined into one file |
| 1 | segment |
The new segment on its own |
Each asset carries a signed url, plus durationSeconds, width, height and mime. Download them promptly: the signed URL is valid for about 20 minutes, and results are kept for up to 14 days. Having the standalone segment is handy when you want to re-edit the join yourself or chain another extension from the new footage.
With the Python SDK
If you prefer Python, the spicyapi package (pip install spicyapi) wraps the same calls:
import uuid
from spicyapi import SpicyClient, output_assets
client = SpicyClient() # reads SPICY_API_KEY
source = client.upload_file("my-clip.mp4") # returns a spicy:// uri
task = client.create_task(
model="alibaba/wan-3.0/video-extend",
input_data={
"video_url": source["uri"],
"prompt": "The camera keeps tracking the cyclist as she turns into the sunlit street.",
"duration_seconds": 5,
"resolution": "720p",
},
idempotency_key=str(uuid.uuid4()),
)
final = client.wait_for_terminal(task["taskId"])
for asset in output_assets(final):
print(asset.get("role"), asset.get("durationSeconds"), asset.get("url"))
Reuse the same idempotency key if you resend after a timeout, so a dropped connection never turns into a second paid task.
Chaining extensions
Because the first asset is a complete, normal MP4, you can feed it straight back in as the next video_url. A 5 second clip becomes 10, then 15 and so on, until the joined clip reaches the source limit (60 seconds on Wan 3.0). The model only sees the last frame each time, so very long chains can drift: characters and lighting slowly change. The optional last_image_url helps when you need the final segment to land on a specific composition.
What it costs
Billing is per second of the new segment, at the resolution you choose. The source clip you send is not billed. At the time of writing (2026-10-13), the public catalog lists Wan 3.0 video extend at $0.045 per second at 480p, $0.09 at 720p and $0.18 at 1080p, so a 5 second extension at 720p is $0.45. Prices change, so check the model page or request a quote before you build a budget around them.
Practical tips
- Match
resolutionto your source to avoid a visible step in sharpness at the seam. - Write the prompt as what happens next, not a description of the clip you already have.
- Keep the source clip's last second stable. If it ends mid-blur, the continuation starts from a blurry frame.
- Extending a clip does not fix a bad ending. If the last frame has artifacts, trim the source first.
Try it
The Wan 3.0 model page, with the current price table and examples, is at spicyapi.ai/models/wan-3-0, and the API reference is at docs.spicyapi.ai. If you would rather not write code, there is also a browser version at spicyapi.ai/create/ai-video-extender. Questions about the endpoint or the seam handling are welcome in the comments.
Top comments (0)