# `Gemini.APIs.Videos`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/videos.ex#L1)

API for video generation using Google's Veo models.

Veo is Google's advanced text-to-video generation model that creates high-quality
videos from text descriptions. Video generation is a long-running operation that
can take several minutes to complete.

Video generation is available through both Vertex AI and the Gemini API
(for supported Veo models).

## Supported Models

- `veo-2.0-generate-001` - Veo 2.0 video generation model (recommended)
- `veo-3.1-generate-preview` - Veo 3.1 preview
- `veo-3.1-fast-generate-preview` - Veo 3.1 Fast preview
- `veo-3.0-generate-001` - Veo 3.0 stable
- `veo-3.0-fast-generate-001` - Veo 3.0 Fast stable

## Video Generation Workflow

Video generation is asynchronous and follows a long-running operation pattern:

1. **Initiate**: Start video generation with `generate/3`
2. **Poll**: Check operation status with `get_operation/2`
3. **Wait**: Use `wait_for_completion/2` for automatic polling
4. **Download**: Retrieve generated videos from GCS URIs

## Examples

    # Start video generation
    {:ok, operation} = Gemini.APIs.Videos.generate(
      "A cat playing piano in a cozy living room",
      %VideoGenerationConfig{
        duration_seconds: 8,
        aspect_ratio: "16:9"
      }
    )

    # Wait for completion (automatic polling)
    {:ok, completed_op} = Gemini.APIs.Videos.wait_for_completion(
      operation.name,
      poll_interval: 10_000,  # Check every 10 seconds
      timeout: 300_000        # Wait up to 5 minutes
    )

    # Extract video URIs
    {:ok, videos} = Gemini.Types.Generation.Video.extract_videos(completed_op)
    video_uri = hd(videos).video_uri

    # Manual polling
    {:ok, op} = Gemini.APIs.Videos.get_operation(operation.name)
    if op.done do
      {:ok, videos} = Gemini.Types.Generation.Video.extract_videos(op)
    end

## Performance Considerations

- Video generation typically takes 2-5 minutes per video
- Longer videos (8s) take more time than shorter videos (4s)
- Higher resolution/FPS increases generation time
- Use webhook callbacks for production systems instead of polling

## Configuration Options

See `Gemini.Types.Generation.Video` for all available configuration options.

# `api_result`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/videos.ex#L79)

```elixir
@type api_result(t) :: {:ok, t} | {:error, term()}
```

# `generation_opts`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/videos.ex#L80)

```elixir
@type generation_opts() :: [
  model: String.t(),
  project_id: String.t(),
  location: String.t()
]
```

# `wait_opts`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/videos.ex#L86)

```elixir
@type wait_opts() :: [
  poll_interval: pos_integer(),
  timeout: pos_integer(),
  on_progress: (Gemini.Types.Operation.t() -&gt; any())
]
```

# `cancel`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/videos.ex#L279)

```elixir
@spec cancel(
  String.t(),
  keyword()
) :: :ok | {:error, term()}
```

Cancel a running video generation operation.

## Parameters

- `operation_name` - Operation name to cancel
- `opts` - Additional options

## Returns

- `:ok` - Operation cancelled successfully
- `{:error, term()}` - Error if cancellation fails

## Examples

    {:ok, operation} = Gemini.APIs.Videos.generate("A cat playing piano")

    # Cancel if taking too long
    :ok = Gemini.APIs.Videos.cancel(operation.name)

# `generate`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/videos.ex#L149)

```elixir
@spec generate(
  String.t(),
  Gemini.Types.Generation.Video.VideoGenerationConfig.t(),
  generation_opts()
) ::
  api_result(Gemini.Types.Operation.t())
```

Generate a video from a text prompt.

This starts a long-running operation. Use `get_operation/2` or `wait_for_completion/2`
to check the status and retrieve the generated video.

## Parameters

- `prompt` - Text description of the video to generate
- `config` - VideoGenerationConfig struct (default: %VideoGenerationConfig{})
- `opts` - Additional options:
  - `:model` - Model to use (default: "veo-2.0-generate-001")
  - `:project_id` - Vertex AI project ID (default: from config)
  - `:location` - Vertex AI location (default: "us-central1")

## Returns

- `{:ok, Operation.t()}` - Long-running operation
- `{:error, term()}` - Error if generation fails to start

## Examples

    # Simple generation
    {:ok, operation} = Gemini.APIs.Videos.generate(
      "A cat playing piano"
    )

    # With configuration
    config = %VideoGenerationConfig{
      number_of_videos: 2,
      duration_seconds: 8,
      aspect_ratio: "16:9",
      fps: 30
    }
    {:ok, operation} = Gemini.APIs.Videos.generate(
      "Cinematic shot of a futuristic city",
      config
    )

    # Custom location
    {:ok, operation} = Gemini.APIs.Videos.generate(
      "Aerial view of mountains",
      config,
      location: "europe-west4"
    )

# `get_operation`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/videos.ex#L199)

```elixir
@spec get_operation(
  String.t(),
  keyword()
) :: api_result(Gemini.Types.Operation.t())
```

Get the current status of a video generation operation.

## Parameters

- `operation_name` - Operation name from `generate/3` response
- `opts` - Additional options

## Returns

- `{:ok, Operation.t()}` - Current operation status
- `{:error, term()}` - Error if operation cannot be retrieved

## Examples

    {:ok, operation} = Gemini.APIs.Videos.generate("A cat playing piano")

    # Later, check status
    {:ok, current_op} = Gemini.APIs.Videos.get_operation(operation.name)

    cond do
      current_op.done and is_nil(current_op.error) ->
        {:ok, videos} = Video.extract_videos(current_op)
        IO.puts("Video ready: #{hd(videos).video_uri}")

      current_op.done ->
        IO.puts("Failed: #{current_op.error.message}")

      true ->
        IO.puts("Still generating...")
    end

# `list_operations`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/videos.ex#L307)

```elixir
@spec list_operations(keyword()) ::
  api_result(Gemini.Types.ListOperationsResponse.t())
```

List video generation operations.

## Parameters

- `opts` - List options:
  - `:page_size` - Number of operations per page
  - `:page_token` - Token for pagination
  - `:filter` - Filter string (e.g., "done=true")

## Returns

- `{:ok, ListOperationsResponse.t()}` - List of operations
- `{:error, term()}` - Error if listing fails

## Examples

    # List all video operations
    {:ok, response} = Gemini.APIs.Videos.list_operations()

    # List only completed operations
    {:ok, response} = Gemini.APIs.Videos.list_operations(filter: "done=true")

# `wait_for_completion`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/videos.ex#L246)

```elixir
@spec wait_for_completion(String.t(), wait_opts()) ::
  api_result(Gemini.Types.Operation.t())
```

Wait for a video generation operation to complete with automatic polling.

This function polls the operation status at regular intervals until it completes
or times out. Useful for synchronous workflows.

## Parameters

- `operation_name` - Operation name from `generate/3` response
- `opts` - Wait options:
  - `:poll_interval` - Milliseconds between polls (default: 10,000)
  - `:timeout` - Maximum time to wait in milliseconds (default: 300,000)
  - `:on_progress` - Callback function called on each poll with Operation.t()

## Returns

- `{:ok, Operation.t()}` - Completed operation
- `{:error, :timeout}` - Operation did not complete within timeout
- `{:error, term()}` - Other errors

## Examples

    {:ok, operation} = Gemini.APIs.Videos.generate("A cat playing piano")

    # Wait with defaults (5 minutes)
    {:ok, completed} = Gemini.APIs.Videos.wait_for_completion(operation.name)

    # Custom polling and timeout
    {:ok, completed} = Gemini.APIs.Videos.wait_for_completion(
      operation.name,
      poll_interval: 5_000,   # Poll every 5 seconds
      timeout: 600_000,       # Wait up to 10 minutes
      on_progress: fn op ->
        if progress = Gemini.Types.Operation.get_progress(op) do
          IO.puts("Progress: #{progress}%")
        end
      end
    )

    # Extract videos
    {:ok, videos} = Video.extract_videos(completed)

# `wrap_operation`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/videos.ex#L325)

```elixir
@spec wrap_operation(Gemini.Types.Operation.t()) ::
  Gemini.Types.Generation.Video.VideoOperation.t()
```

Wrap an operation with video-specific metadata.

Adds video generation progress tracking and estimation.

## Examples

    {:ok, op} = Gemini.APIs.Videos.get_operation(operation_name)
    video_op = Gemini.APIs.Videos.wrap_operation(op)

    IO.puts("Progress: #{video_op.progress_percent}%")
    IO.puts("ETA: #{video_op.estimated_completion_time}")

---

*Consult [api-reference.md](api-reference.md) for complete listing*
