P-Video-2

P-Video-2 is Pruna AI's quality-focused successor to P-Video, creating clips from text, images, or audio-conditioned inputs through one model. It produces sharper close-ups and foreground subjects, stronger identity and input-image consistency, improved lip synchronization for natively generated speech, and clearer on-screen text while generating dialogue, music, and sound effects with the video. It supports optional first-and-last-frame guidance, draft iteration, durations up to 20 seconds, 720p or 1080p output, and 24 or 48 FPS.

Complete technical specification for integration
Ready-to-use code snippets for common workflows
Step-by-step tutorials for advanced use cases
← All GuidesPinning the first and last frame
How to give Pruna P-Video-2 both ends of a shot, how far apart the two stills can sit before the transition breaks, and the pairing trick that produces a seamless loop.
Introduction
A single first frame decides where a shot starts and leaves the ending to the model. Pinning both ends turns the request into a different kind of instruction: you are no longer describing motion and hoping, you are handing over a start state and an end state and asking for the path between them.
The lid lifts smoothly straight up off the box, moves back and sets down behind it, the tissue paper folds open and the jar inside is revealed. Steady and unhurried, the camera holds still throughout. Audio: quiet studio room tone, the soft friction of a rigid lid lifting and tissue paper unfolding, no music, no voice.
- First frame

A closed rigid gift box in deep forest green with a matte finish and a narrow gold foil band around its lid, sitting centred on a pale limestone surface against a soft neutral grey background. Even soft studio lighting from above and left, a gentle contact shadow. Photoreal packaging photography, medium close-up, no text, no logos, no hands.
- Last frame

The same deep forest green rigid gift box with its lid lifted clear and set behind it, revealing a folded sheet of cream tissue paper opened back and an unbranded amber glass jar of cream nested inside, sitting centred on a pale limestone surface against a soft neutral grey background. Even soft studio lighting from above and left, a gentle contact shadow. Photoreal packaging photography, medium close-up, no text, no logos, no hands.
That is an unboxing shot where the product is guaranteed to be correct in the final frame, because the final frame is a still you approved. No amount of prompting a single first frame gets you that. This guide covers the request, how far apart the two ends can sit, how duration changes the pace of the transition, and the pairing that gives you a seamless loop.
The request
inputs.frameImages takes two items, one for each end. frame accepts the names "first" and "last", or the indices 0 and -1, and the two forms are interchangeable.
{
"inputs": {
"frameImages": [
{ "image": "https://…/closed.jpg", "frame": "first" },
{ "image": "https://…/open.jpg", "frame": "last" }
]
}
}Order in the array does not matter, because frame is what assigns the position. Naming both is the habit worth keeping: a bare image with no frame is read as the first frame, so a two-item array that forgets to label the second one is not the request you meant.
import { createClient } from '@runware/sdk'
const client = await createClient({ apiKey: process.env.RUNWARE_API_KEY })
await client.connect()
const [result] = await client.run({
model: 'prunaai:p-video@2',
positivePrompt: 'The lid lifts smoothly straight up off the box, moves back and sets down behind it, the tissue paper folds open and the jar inside is revealed. Steady and unhurried, the camera holds still throughout. Audio: quiet studio room tone, the soft friction of a rigid lid lifting and tissue paper unfolding, no music, no voice.',
inputs: {
frameImages: [
{
image: 'https://im.runware.ai/image/os/a14d18/ws/2/ii/2f9d4c81-7b35-4e60-9a18-5c2d8a7f1e93.jpg',
frame: 'first'
},
{
image: 'https://im.runware.ai/image/os/a14d18/ws/2/ii/6b3e8a15-4c92-4d07-8f61-9a2c7d5b3e48.jpg',
frame: 'last'
}
]
},
resolution: '720p',
duration: 6,
deliveryMethod: 'async'
})import asyncio
import os
from runware import Runware
async def main():
async with Runware(api_key=os.environ["RUNWARE_API_KEY"]) as client:
results = await client.run({
"model": "prunaai:p-video@2",
"positivePrompt": "The lid lifts smoothly straight up off the box, moves back and sets down behind it, the tissue paper folds open and the jar inside is revealed. Steady and unhurried, the camera holds still throughout. Audio: quiet studio room tone, the soft friction of a rigid lid lifting and tissue paper unfolding, no music, no voice.",
"inputs": {
"frameImages": [
{
"image": "https://im.runware.ai/image/os/a14d18/ws/2/ii/2f9d4c81-7b35-4e60-9a18-5c2d8a7f1e93.jpg",
"frame": "first"
},
{
"image": "https://im.runware.ai/image/os/a14d18/ws/2/ii/6b3e8a15-4c92-4d07-8f61-9a2c7d5b3e48.jpg",
"frame": "last"
}
]
},
"resolution": "720p",
"duration": 6,
"deliveryMethod": "async"
})
asyncio.run(main())curl https://api.runware.ai/v1 \
-H "Authorization: Bearer $RUNWARE_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"taskType": "videoInference",
"taskUUID": "a5c81e37-9d24-4b60-8f15-3e7a2c9d4b81",
"model": "prunaai:p-video@2",
"positivePrompt": "The lid lifts smoothly straight up off the box, moves back and sets down behind it, the tissue paper folds open and the jar inside is revealed. Steady and unhurried, the camera holds still throughout. Audio: quiet studio room tone, the soft friction of a rigid lid lifting and tissue paper unfolding, no music, no voice.",
"inputs": {
"frameImages": [
{
"image": "https://im.runware.ai/image/os/a14d18/ws/2/ii/2f9d4c81-7b35-4e60-9a18-5c2d8a7f1e93.jpg",
"frame": "first"
},
{
"image": "https://im.runware.ai/image/os/a14d18/ws/2/ii/6b3e8a15-4c92-4d07-8f61-9a2c7d5b3e48.jpg",
"frame": "last"
}
]
},
"resolution": "720p",
"duration": 6,
"deliveryMethod": "async"
}
]'runware run prunaai:p-video@2 \
positivePrompt="The lid lifts smoothly straight up off the box, moves back and sets down behind it, the tissue paper folds open and the jar inside is revealed. Steady and unhurried, the camera holds still throughout. Audio: quiet studio room tone, the soft friction of a rigid lid lifting and tissue paper unfolding, no music, no voice." \
inputs.frameImages.0.image=https://im.runware.ai/image/os/a14d18/ws/2/ii/2f9d4c81-7b35-4e60-9a18-5c2d8a7f1e93.jpg \
inputs.frameImages.0.frame=first \
inputs.frameImages.1.image=https://im.runware.ai/image/os/a14d18/ws/2/ii/6b3e8a15-4c92-4d07-8f61-9a2c7d5b3e48.jpg \
inputs.frameImages.1.frame=last \
resolution=720p \
duration=6 \
deliveryMethod=async{
"taskType": "videoInference",
"taskUUID": "a5c81e37-9d24-4b60-8f15-3e7a2c9d4b81",
"model": "prunaai:p-video@2",
"positivePrompt": "The lid lifts smoothly straight up off the box, moves back and sets down behind it, the tissue paper folds open and the jar inside is revealed. Steady and unhurried, the camera holds still throughout. Audio: quiet studio room tone, the soft friction of a rigid lid lifting and tissue paper unfolding, no music, no voice.",
"inputs": {
"frameImages": [
{
"image": "https://im.runware.ai/image/os/a14d18/ws/2/ii/2f9d4c81-7b35-4e60-9a18-5c2d8a7f1e93.jpg",
"frame": "first"
},
{
"image": "https://im.runware.ai/image/os/a14d18/ws/2/ii/6b3e8a15-4c92-4d07-8f61-9a2c7d5b3e48.jpg",
"frame": "last"
}
]
},
"resolution": "720p",
"duration": 6,
"deliveryMethod": "async"
}Response
[
{
"taskType": "videoInference",
"taskUUID": "a5c81e37-9d24-4b60-8f15-3e7a2c9d4b81",
"videoUUID": "9e4a7c25-3f18-4b60-8d73-1c5a9d2f7b84",
"videoURL": "https://vm.runware.ai/video/os/a14d18/ws/2/vi/9e4a7c25-3f18-4b60-8d73-1c5a9d2f7b84.mp4"
}
]Everything that applies to a single first frame applies here too. width and height are still rejected, the aspect still comes from the stills, and resolution still picks the tier. Animating a still covers that rule and the source-quality requirements, both of which now apply twice over.
The pair has to match
Two stills that disagree about anything other than the thing you want to change will not interpolate. The pair below is a deliberate bad one, changing three things at once so you can see what that looks like:

A wide shot of a tidy home workspace from across the room, a pale oak desk against a white wall with a closed laptop, a small ceramic vase and a task lamp on it, a rug on the floor and a plant in the corner. Bright soft daylight from a window out of frame to the left. Photoreal interior photography, wide shot, no text.

A tight close-up of a closed laptop lid and the base of a task lamp on a pale oak desk, shot from just above desk height with the background thrown completely out of focus. Hard warm lamplight from the right, deep shadows, evening feel. Photoreal detail photography, close-up, no text.
The camera moves in from the wide view of the room to the close view of the desk as the light changes from day to evening. Audio: quiet interior room tone, no music, no voice.
That pair asks for a camera move, a lens change and a lighting change in six seconds. There is no single continuous path that does all three, so the model stops trying to find one: it holds the first frame, then cross-fades into the second, with a brief double exposure in the middle where both rooms are visible at once.
That fade is worth recognizing, because it is the model telling you something. A dissolve means your pair was unreachable. When two frames are connected by something physical, you get movement instead, the way the lid lifts off the box above. When they are not, you get a slideshow transition. Watch the middle third of any first-and-last clip: ghosting there means the ends were too far apart, whatever the prompt asked for.
The rule that comes out of it: change one thing between the two frames. The light, or the position of an object, or the camera, not several. When a shot genuinely needs a move and a light change, split it into two clips and cut.
Everything else about the pair should be identical: the aspect ratio, the focal length, the position of the camera, the palette, and anything in frame you are not deliberately changing. The most reliable way to get that is to generate the second still from the first one in your image model rather than writing it fresh.
How far apart the two ends can sit
The interesting question is not whether two stills work, it is how much distance the interpolation can cover. Three pairs from one anchor still, all on the same seed and duration:

A hotel suite living area with a low oatmeal linen sofa, a walnut side table and a wide window looking onto rooftops, shot square on from the middle of the room. Bright midday daylight, curtains open, cool even light across a pale wool rug. Photoreal hospitality interior photography, wide shot, no people, no text.

The same hotel suite living area with the same low oatmeal linen sofa, walnut side table and wide window onto rooftops, shot square on from the same position in the middle of the room. Late golden afternoon sun raking in low through the window, warm light across the pale wool rug, long soft shadows. Photoreal hospitality interior photography, wide shot, no people, no text.

The same hotel suite living area with the same low oatmeal linen sofa, walnut side table and wide window onto rooftops, shot square on from the same position in the middle of the room. Night outside with city lights in the window, the room lit warmly by a single table lamp and a floor lamp, deep pools of shadow. Photoreal hospitality interior photography, wide shot, no people, no text.

A busy pedestrianised shopping street at midday seen from head height, rows of shopfronts on both sides, striped awnings, planters and dozens of people walking in both directions. Bright flat overcast daylight. Photoreal street photography, wide shot, no readable text.
The daylight in the room warms and lowers as the afternoon passes, shadows lengthening across the rug. The camera holds still and nothing in the room moves. Audio: quiet interior room tone, faint distant city sound, no music, no voice.
The day passes into night, the window darkening to city lights and the lamps in the room coming up warm. The camera holds still and nothing in the room moves. Audio: quiet interior room tone, faint distant city sound, no music, no voice.
The scene moves from the hotel suite out to the shopping street below. The camera holds still. Audio: quiet interior room tone giving way to street ambience, no music, no voice.
The near pair is the sweet spot. Nothing physical moves, one property of the scene changes, and the model only has to interpolate light, which it does convincingly enough to sell as a time-lapse.
The mid pair still works and asks more: the window content changes, two lamps switch on, and the whole light direction inverts. Watch the lamps rather than the window, because a light source coming up is where the invention shows.
The far pair is not a transition, it is a dissolve. Two unrelated scenes produce a morph, with the sofa melting into shopfronts, because there is no physical path between a hotel room and a street. That is a real effect if you want it, and it is nothing like a cut. When you need the suite and then the street, generate two clips and cut them.
The distance that matters is physical continuity, not visual similarity. Two stills that look quite different but share a cause, a lamp switching on, a lid coming off, a garment being unfolded, interpolate better than two stills that look alike but have no motion connecting them.
Duration sets the pace
With both ends fixed, duration stops being "how long a clip do I want" and becomes how fast the transition happens, because the model has to arrive at the last frame exactly on time. The same pair at three lengths:
The day passes into night, the window darkening to city lights and the lamps in the room coming up warm. The camera holds still and nothing in the room moves. Audio: quiet interior room tone, faint distant city sound, no music, no voice.
The day passes into night, the window darkening to city lights and the lamps in the room coming up warm. The camera holds still and nothing in the room moves. Audio: quiet interior room tone, faint distant city sound, no music, no voice.
The day passes into night, the window darkening to city lights and the lamps in the room coming up warm. The camera holds still and nothing in the room moves. Audio: quiet interior room tone, faint distant city sound, no music, no voice.
Three seconds reads as a transition effect. Twelve reads as a time-lapse. Neither is wrong, and the same two stills give you both without regenerating anything, which makes duration the cheapest creative control in this mode.
There is a practical limit at each end. Too short and a physical action gets compressed into something that snaps rather than moves. Too long and the model has to fill seconds with invention it was not given any instruction for, which is where drifting appears in the middle of an otherwise clean clip. For a physical action, match the duration to how long the action would actually take. A rigid box lid comes off in about a second, so a six-second reveal wants the prompt to say the movement is unhurried, exactly as the hero prompt does.
duration is rejected when inputs.audio is present, because imported audio sets the length instead. Pinning both frames and supplying a track means the transition is paced by the audio, not by you. Audio-driven generation covers that combination.
A seamless loop from one still
Here is the trick worth knowing. Pass the same image as both the first and the last frame, and the clip is guaranteed to end where it began.
{
"inputs": {
"frameImages": [
{ "image": "https://…/mug.jpg", "frame": "first" },
{ "image": "https://…/mug.jpg", "frame": "last" }
]
}
}That is a perfect loop point, which is normally the hardest thing to get out of a generative video model. The prompt's job changes: it has to describe motion that returns to rest, since anything that ends somewhere else has to be walked back before the final frame.
Steam rises gently from the surface of the coffee and drifts, and the surface of the liquid ripples very slightly, returning to stillness by the end. The camera holds perfectly still and the mug does not move. Audio: quiet room tone, no music, no voice.
- First and last frame

An unbranded matte white ceramic mug of black coffee sitting dead centre on a dark walnut table, shot straight down from directly above, a folded grey linen napkin at the bottom edge of the frame. Even soft overhead lighting, symmetrical composition. Photoreal overhead product photography, vertical framing, no text, no hands.
Loops earn their keep in the places video autoplays and repeats: a listing page, a hero banner, a background panel in an app. Because the seam is exact, the file can be played on repeat with no cut visible, and a five-second clip covers a slot that would otherwise need a much longer render.
The motions that suit this are the ones that naturally cycle or settle. Steam, a curtain in a draught, a plant moving in air, a fabric settling, a light flickering. Anything with a direction to it will fight the last frame, so a rotation, a walk or a hand entering shot are the wrong instructions here.
Pair it with settings.audio: false and you have exactly what a muted autoplay loop needs, since a generated track will not loop cleanly even when the picture does.
Tips
-
Label both frames. An item without
frameis treated as the first frame, so a two-item array with one label is a request for two first frames. -
Change one thing between the ends. Light, or an object's position, or the camera. Two of the three at once produces a lurch, not a transition.
-
Generate the last still from the first. Editing the first frame in your image model keeps the framing, lens and palette identical, which is most of what makes a pair work.
-
Ask for a cause, not a resemblance. Two frames connected by something physically happening interpolate well. Two frames that merely look alike do not.
-
Use duration as the pace control. One pair at 3, 6 and 12 seconds gives you a transition, a beat and a time-lapse. Match it to how long the real action would take.
-
Pass the same still twice for a seamless loop, and write motion that returns to rest. Steam, draught and settling fabric loop. Rotations and walks do not.
-
Turn the audio off on loops. The picture loops exactly and the generated track will not, so a muted loop is the only clean version.
-
Two unrelated stills are a morph, not a cut. If you want a cut, render two clips and cut them in your edit.