Instructions to use Viggle/Meridian with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use Viggle/Meridian with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("Viggle/Meridian", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
Local studio API
← Meridian · Studio and deployment · Method
The FastAPI service exposes the same preparation and rendering operations used by the studio. This is a development API for a trusted, single-GPU deployment—not an authenticated multi-user service. Requests are plain JSON except for multipart upload. All source indices refer to the normalized 24 fps clip, not the original upload's timestamps.
Request flow
/upload or /sample → /prepare → /warp → inspect → /render → /job/{job} → /take/{job}/{name}
/prepare must populate the source-span cache before /warp or /render. Keep the same clip,
start, and span_end across those calls. If that cache entry is evicted or the service restarts,
prepare again. Do not change requests while assuming a previously inspected preview still applies.
Shared fields
| Field | Meaning |
|---|---|
clip |
ID returned by /upload or /sample. |
start |
First source frame of the prepared span, inclusive. |
span_end |
Last source frame of that span, inclusive. Must satisfy 0 <= start < span_end < clip.frames. |
frames |
Output length. Use one of 73, 90, 107, 124, 141, 158, 175, 243 for generation. |
pivot |
Optional [u, v] in normalized source-image fractions; default [0.5, 0.5]. Sets the depth-scale neighborhood. |
pivot_frame |
Source frame at which to measure pivot depth; set it explicitly, normally to start. |
seed |
Generation seed, default 1234. |
path |
List of at least two camera keys. |
The current API's per-endpoint validation is limited; unsupported output lengths may fail only when loading conditioning assets. Validate requests before submitting expensive GPU work. Choose a continuous source span: the browser avoids detected cuts, but the API does not enforce that policy.
Camera keys
| Field | Meaning |
|---|---|
pos |
[x, y, z] position in the coordinate frame of the source camera at start, in units of zm. |
look |
Look-at point in the same frame and units. |
src |
Absolute source-frame index, within the prepared span. |
t |
Output-frame index. First key is 0, last is frames - 1; intermediate values strictly increase. |
ease |
Optional boolean, default false. Eases camera position/look-at motion in the segment leaving this key. |
focal |
Optional positive focal multiplier, default 1, relative to that source frame's estimated lens. |
Axes are x right, y down, z forward. Source indices must be non-decreasing. Position and look-at
points follow slope-limited cubic Hermite/Catmull-Rom interpolation; source indices and focal
multipliers interpolate linearly. Source indices are rounded to integers. Orientation is derived
from the look-at direction with zero roll. Equal adjacent src values create a hold.
Minimal walkthrough
Start the service, then upload a continuous clip containing at least 73 normalized frames:
curl -sS -F 'file=@clip.mp4' http://127.0.0.1:8412/upload
Copy the response's clip value into the following JSON and save it as take.json. This example
slides the camera right by 0.15 zm while looking toward a point one depth unit ahead of the initial
camera. For subject-specific framing, use the piv returned by /prepare as your look-at reference.
{
"clip": "CLIP_ID_FROM_UPLOAD",
"start": 0,
"span_end": 72,
"frames": 73,
"pivot": [0.5, 0.5],
"pivot_frame": 0,
"seed": 1234,
"path": [
{"pos": [0, 0, 0], "look": [0, 0, 1], "src": 0, "t": 0, "ease": true, "focal": 1},
{"pos": [0.15, 0, 0], "look": [0, 0, 1], "src": 72, "t": 72, "ease": false, "focal": 1}
]
}
Prepare the geometry, then produce a preview. /prepare ignores the extra path fields:
curl -sS -H 'Content-Type: application/json' --data-binary @take.json \
http://127.0.0.1:8412/prepare
curl -sS -H 'Content-Type: application/json' --data-binary @take.json \
http://127.0.0.1:8412/warp
Open the returned truth and holes URLs relative to the service origin, and inspect ahead,
moved, and speed. Generation is a separate, expensive step:
curl -sS -H 'Content-Type: application/json' --data-binary @take.json \
http://127.0.0.1:8412/render
Copy the returned job ID into the commands below. Poll until done is true, and check that there is
no error before downloading; failed jobs also set done: true.
curl -sS http://127.0.0.1:8412/job/JOB_ID_FROM_RENDER
curl -f -o out.mp4 http://127.0.0.1:8412/take/JOB_ID_FROM_RENDER/out.mp4
/render does not enforce the browser's clearance or camera-change gates and does not require that
/warp was called first. This walkthrough includes preview inspection intentionally. A returned job
ID means the background task was started, not that input validation or generation succeeded.
Endpoints
Paths below are relative to the service origin. “Shared fields” refers to the table above; not every endpoint consumes every field.
| Endpoint | Request | Response |
|---|---|---|
GET / |
— | Studio HTML. |
GET /samples |
— | Array of available sample MP4 filenames. |
POST /upload |
Multipart file. |
{clip, frames, w, h, name, cuts, seconds, lengths}. |
POST /sample |
{name} from /samples. |
Same clip metadata as upload. |
POST /prepare |
clip, start, span_end; optional pivot, pivot_frame. |
{box, canvas, cond_canvas, ms, src_poses, piv, zm}. |
POST /cloud |
Shared fields plus absolute source frame, optional stride (default 5). |
{n, zm, pts, rgb}; flattened triples in path coordinates. |
POST /warp1 |
Shared fields plus src, pos, look; optional focal. |
One geometry-reference JPEG at conditioning resolution. |
POST /warp |
Shared fields plus path; optional lite. |
Gauges, cameras, source mapping, and preview URLs. lite: true omits the hole/sketch previews. |
POST /render |
Shared fields plus path. |
{job}; rendering continues in a background thread. |
GET /job/{job} |
— | Status including stage, pct, done, payload; t, error, or gauges when available. |
GET /frame/{clip}/{i}.jpg |
Source index in the URL. | JPEG of the normalized source frame. |
GET /warpfile/{clip}/{name} |
Use a URL returned by /warp. |
Preview file. |
GET /take/{job}/{name} |
Completed job ID and filename. | out.mp4, source.mp4, render.mp4, grid.mp4, or last.png. |
lengths in upload metadata is the studio's four-option length menu, not an exhaustive list of
asset-supported lengths. src_poses[i] in /prepare corresponds to absolute source frame
start + i; each entry includes pos, look, roll, and normalized lens values k.
Job t is elapsed time since submission, including queue wait. It first appears when processing
starts and updates at stage transitions, not continuously on polling. It is not a pure render-time
measurement.
Warp response
truth: grey-hole reference MP4 at conditioning resolution.holes: magenta-hole diagnostic MP4, unlessliteis true.sketch: output-resolution geometric rasterization, unlessliteis true; not the final conditioning-resolution reference.canvas,cond_canvas:[width, height]for the target and references.tmap: selected source index for every output frame.cams: per-output-frame position/look-at description;pivandzmdescribe the pivot/scale.speed: source-frame rate per key segment; zero is a hold, one preserves the input pace.coverage: mean geometric coverage at the rasterization resolution, not a calibrated quality score.ahead,near,behind,coll,moved: geometric diagnostics. See Preview checks.ms: elapsed time for the warp endpoint, including preview encoding.
turned and zoomed are computed by the browser from keys; they are not fields returned by /warp.
Operational boundaries
One process serializes GPU work through a lock. The API has no cancellation, durable queue, session restoration, authentication, or automatic file retention policy. Clip and geometry caches can evict entries while files remain on disk. Do not assume an old ID remains usable after a restart or eviction.
Assertions and runtime failures may surface as HTTP errors rather than structured validation
responses. Render failures can arrive asynchronously through /job/{job}. The automatically served
FastAPI schema does not describe these JSON payloads fully because the handlers read request bodies
directly; use this guide alongside service/app.py.
For service flags, cache behavior, and deployment precautions, see Studio.