MuseMVP
MuseMVP Docs
AI

Video and Voice

Asynchronous video on Queues, speech synthesis, prices, limits, the task APIs and provider keys.

Before you start

Video and voice run through the bundled provider adapter, so live mode needs DASHSCOPE_API_KEY as a Worker secret (see AI overview). Without the key, live mode hides these models and the studios explain why. Mock mode serves playable sample media with no key.

Video

SettingValue
Length2 to 10 seconds
Resolution and price480P: 6, 720P: 12, 1080P: 23 credits per second
Ratios16:9, 9:16, 1:1, 4:3, 3:4
InputText, or text plus a first frame from the library (image-to-video renders 1:1)
AudioGenerated with the clip unless audio is false

A 5-second 720P clip reserves 60 credits.

How a video task runs

  1. /app/video sends POST /api/ai/videos. The server prices resolution × seconds and reserves the credits with the task and its outbox message.
  2. The queue consumer leases the task and the adapter submits the provider job. Its id is stored on the task.
  3. The lease is released and a delayed message (JOBS.send(..., { delaySeconds })) checks again later. Nothing waits inside a request, and people can close the tab.
  4. When the job finishes, the MP4 is copied into R2 and served from /api/ai/assets/{id}/content with range requests, so the player can seek.
  5. A job still unfinished 30 minutes after its first claim fails and returns its credits. The five-minute cron also reclaims expired leases.
{
  "requestId": "0b8d5e2a-7f3c-4c1d-9a6e-2f4b8c1d3e5a",
  "model": "your-video-model-key",
  "prompt": "Steam rises from the coffee, the camera slowly pushes in",
  "resolution": "720P",
  "ratio": "16:9",
  "seconds": 5,
  "audio": true,
  "firstFrame": "optional-library-asset-id"
}

The prompt is up to 2,000 characters. The model key comes from VIDEO_MODELS in packages/ai/src/video.ts.

Voice

SettingValue
VoicesSeven curated voices: Chinese narration, news, documentary and expressive styles, plus one English voice
ScriptUp to 2,000 characters per clip
Price2 credits per 1,000 characters, rounded up, so every clip costs at least 1 credit
OutputMP3 in the library, playable and downloadable

POST /api/ai/speech takes requestId, model, voice and text. The task is reserved, leased from JOBS, synthesized by the adapter and written to R2 like every other output. Voice keys and labels live in SPEECH_MODELS in packages/ai/src/speech.ts.

Shared behavior

  • Both endpoints return 201 with the task and refuse with 402, 429 or 503 like the image studio.
  • GET /api/ai/tasks/{id} reports progress; POST /api/ai/tasks/{id}/cancel cancels a queued task and returns its credits.
  • Provider content refusals return credits while ai.refundOnContentRefusal is true.
  • Each task's estimated upstream cost counts toward ai.dailyBudgetUsd.

Troubleshooting

  • Model missing in live mode: the provider key is not set for this environment.
  • Stuck in rendering: check that the queue consumer is deployed, the JOBS binding exists and the cron trigger runs. The task fails with a refund after 30 minutes.
  • Video does not seek: load it through /api/ai/assets/{id}/content, which answers range requests, not through a copied URL.

On this page