FreeImageToVideo (FreeImageToVideo v0.1.0)

Copy Markdown View Source

Official Elixir SDK for Free Image to Video. Free image to video AI with no daily cap: start with no sign-up, keep going on a free account. Every video comes with sound and no watermark.

{:ok, url} = FreeImageToVideo.generate_video("a paper lantern drifting over a night river")
{:ok, url} = FreeImageToVideo.generate_video("the camera slowly orbits the statue",
               image_url: "https://example.com/statue.jpg", options: %{"duration" => 6})
{:ok, left} = FreeImageToVideo.credits()

Pass api_key: or set FREEIMAGETOVIDEO_API_KEY; create a key at https://freeimagetovideo.ai/settings/apikeys.

Failures are {:error, reason, message} where reason is :auth, :quota, :plan, :busy, :rejected, :generation, :timeout or :api.

Uses only :httpc from OTP and the standard JSON module; no dependencies.

Summary

Functions

The request body for POST /api/ai/generate.

Maps an HTTP status and envelope to the reason that says what to do next.

Credits left on the account.

Generates one clip with sound and returns the URL of the finished MP4.

Reads one answer: {:ok, data} on code 0, else the classified error.

Returns the run as /api/ai/query reports it: a map with "id", "status" ("pending", "processing", "success", "failed" or "canceled"), "videos", "errorMessage", "failureKind", "queued" and "queueEta".

Submits a run and returns its task id without waiting. Same options as generate_video/2.

Polls a submitted run until it finishes and returns its video URL.

Types

error()

@type error() :: {:error, reason(), String.t()}

reason()

@type reason() ::
  :auth | :quota | :plan | :busy | :rejected | :generation | :timeout | :api

Functions

body(prompt, opts \\ [])

@spec body(String.t(), keyword()) :: map()

The request body for POST /api/ai/generate.

classify(status, env)

@spec classify(integer(), map()) :: reason()

Maps an HTTP status and envelope to the reason that says what to do next.

credits(opts \\ [])

@spec credits(keyword()) :: {:ok, integer()} | error()

Credits left on the account.

generate_video(prompt, opts \\ [])

@spec generate_video(String.t(), keyword()) :: {:ok, String.t()} | error()

Generates one clip with sound and returns the URL of the finished MP4.

Options: :image_url (a public https image; it becomes the first frame), :options (map sent as the request's options: "duration" 4/5/6/8/10/15, "resolution" 480p/768p, "aspect_ratio" 16:9/9:16/1:1), :api_key, :poll_ms (10000), :timeout_ms (30 minutes), :base_url.

parse_envelope(status, raw)

@spec parse_envelope(integer(), binary()) :: {:ok, term()} | error()

Reads one answer: {:ok, data} on code 0, else the classified error.

Refusals usually arrive as HTTP 200 with a non-zero code, so the status alone reads a refusal as success.

status(task_id, opts \\ [])

@spec status(String.t(), keyword()) :: {:ok, map()} | error()

Returns the run as /api/ai/query reports it: a map with "id", "status" ("pending", "processing", "success", "failed" or "canceled"), "videos", "errorMessage", "failureKind", "queued" and "queueEta".

submit(prompt, opts \\ [])

@spec submit(String.t(), keyword()) :: {:ok, String.t()} | error()

Submits a run and returns its task id without waiting. Same options as generate_video/2.

wait(task_id, opts \\ [])

@spec wait(String.t(), keyword()) :: {:ok, String.t()} | error()

Polls a submitted run until it finishes and returns its video URL.