Learn how to create AI-generated videos from images using the Weights API. This guide walks you through the process of transforming static images into dynamic video content.

Overview

The Weights API provides video generation capabilities that can animate static images. You provide an input image and a prompt describing the desired motion, and the API creates a video that brings your image to life.

Prerequisites

  • A Weights API account with an API key
  • An image file uploaded to a web-accessible URL
  • Basic knowledge of HTTP requests and JSON
  • The Weights SDK installed (optional but recommended)

Step 1: Set Up Your Environment

First, install the Weights SDK and set up your authentication:
npm install @weights-ai/sdk
import Weights from "@weights-ai/sdk";

const client = new Weights({
  bearerToken: "your-api-key-here",
});

Step 2: Prepare Your Input Image

Before creating a video, you need to upload your image to a web-accessible location. The API requires a publicly accessible URL for the input image.

Image Requirements

  • Format: Common image formats (JPEG, PNG, WebP)
  • Size: Recommended resolution for best results
  • Accessibility: Must be accessible via HTTP/HTTPS URL
  • Content: Clear, high-quality images work best

Example Image Upload

// Example: Upload to a cloud storage service
// This is just an example - you'll need to implement your own upload logic
async function uploadImage(imageFile) {
  // Upload to your preferred service (AWS S3, Cloudinary, etc.)
  const imageUrl = await uploadToCloudStorage(imageFile);
  return imageUrl;
}

const inputImageUrl = await uploadImage("path/to/your/image.jpg");
console.log("Image uploaded to:", inputImageUrl);

Step 3: Create Your First Video

Start by creating a video generation job:
const videoJob = await client.videos.create({
  prompt: "Gentle swaying motion with flowing movement",
  inputImageUrl: "https://example.com/your-image.jpg",
});

console.log(`Video job created with ID: ${videoJob.id}`);

Request Parameters

  • prompt (required): Description of the motion you want to apply to the image
  • inputImageUrl (required): URL of the input image to animate

Step 4: Monitor Video Generation

Video generation is asynchronous and typically takes longer than image generation. Poll the status to track progress:
async function checkVideoStatus(jobId) {
  const job = await client.videos.retrieve(jobId);

  console.log(`Status: ${job.status}`);

  switch (job.status) {
    case "QUEUED":
      console.log("Your video job is waiting in the queue...");
      break;
    case "PROCESSING":
      console.log("Your video is being generated...");
      break;
    case "SUCCEEDED":
      console.log("Video generated successfully!");
      console.log("Download URL:", job.outputUrl);
      break;
    case "ERRORED":
      console.log("Video generation failed. Please try again.");
      break;
  }

  return job;
}

// Check status every 30 seconds (videos take longer than images)
const job = await checkVideoStatus(videoJob.id);

Job Statuses

  • QUEUED: Job is waiting in the processing queue
  • PENDING_WORKER: Job is assigned to a worker
  • PROCESSING: Video is being generated
  • SUCCEEDED: Generation completed successfully
  • ERRORED: Generation failed
  • CANCELED: Job was canceled

Step 5: Retrieve Your Generated Video

Once the status is SUCCEEDED, your video is ready for download:
if (job.status === "SUCCEEDED") {
  console.log("Your video is ready!");
  console.log("Download URL:", job.outputUrl);

  // You can now download or stream the video
  // The URL will be available for a limited time
}

Advanced Video Generation

Different Motion Types

Experiment with various motion prompts:
// Gentle movement
const gentleVideo = await client.videos.create({
  prompt: "Subtle breathing motion with soft waves",
  inputImageUrl: "https://example.com/portrait.jpg",
});

// Dynamic movement
const dynamicVideo = await client.videos.create({
  prompt: "Fast spinning motion with dramatic effects",
  inputImageUrl: "https://example.com/landscape.jpg",
});

// Natural movement
const naturalVideo = await client.videos.create({
  prompt: "Natural swaying like wind through trees",
  inputImageUrl: "https://example.com/forest.jpg",
});

Best Practices

Writing Effective Motion Prompts

  • Be specific: “Gentle left-to-right swaying motion” vs “movement”
  • Describe the type of motion: “swaying”, “spinning”, “floating”, “breathing”
  • Include speed: “slow”, “fast”, “gentle”, “dramatic”
  • Mention natural elements: “like wind”, “like water”, “like fire”

Image Selection Tips

  • High quality: Use clear, high-resolution images
  • Good composition: Images with clear subjects work better
  • Appropriate content: Some image types animate better than others
  • Avoid busy backgrounds: Simple backgrounds often produce better results

Error Handling

try {
  const videoJob = await client.videos.create({
    prompt: "Your motion prompt",
    inputImageUrl: "https://example.com/image.jpg",
  });
} catch (error) {
  if (error.code === "BAD_REQUEST") {
    console.log("Invalid prompt or image URL");
  } else if (error.code === "UNAUTHORIZED") {
    console.log("Please check your API key");
  } else {
    console.log("An error occurred:", error.message);
  }
}

Complete Example

Here’s a complete example that creates a video and waits for completion:
import Weights from "@weights-ai/sdk";

const client = new Weights({
  bearerToken: "your-api-key-here",
});

async function generateVideo(imageUrl, motionPrompt) {
  try {
    // Create the video generation job
    console.log("Creating video generation job...");
    const job = await client.videos.create({
      prompt: motionPrompt,
      inputImageUrl: imageUrl,
    });

    console.log(`Job created with ID: ${job.id}`);

    // Poll for completion
    let completed = false;
    while (!completed) {
      await new Promise((resolve) => setTimeout(resolve, 30000)); // Wait 30 seconds

      const status = await client.videos.retrieve(job.id);
      if(!status){
        throw new Error("Video status not found");
      }
      console.log(`Status: ${status.status}`);

      if (status.status === "SUCCEEDED") {
        console.log("Video generated successfully!");
        console.log("Download URL:", status.outputUrl);
        completed = true;
      } else if (status.status === "ERRORED") {
        console.log("Video generation failed");
        completed = true;
      }
    }
  } catch (error) {
    console.error("Error:", error.message);
  }
}

// Generate a video
generateVideo(
  "https://example.com/your-image.jpg",
  "Gentle breathing motion with soft pulsing"
);

Use Cases

Content Creation

  • Social Media: Create engaging animated content for platforms like Instagram, TikTok
  • Marketing: Animate product images for promotional materials
  • Art: Bring static artwork to life with motion

Creative Projects

  • Portraits: Add subtle movement to portrait photography
  • Landscapes: Animate nature scenes with wind or water effects
  • Abstract Art: Create dynamic abstract animations

Performance Considerations

  • Processing Time: Video generation typically takes 5-15 minutes
  • Queue Position: Jobs are processed in order, so expect some wait time
  • File Size: Generated videos are optimized for web delivery
  • URL Expiration: Download URLs have limited availability

Next Steps

API Reference

For detailed API documentation, see the API Reference section.