# How OpenMAIC Handles Media Generation: Images, Video, and Provider Architecture

> Discover how OpenMAIC generates images and video using a provider-agnostic system, ensuring secure and unified media creation for classroom automation.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: internals
- Published: 2026-08-31

---

**OpenMAIC generates images and video through a provider-agnostic registry system that dispatches requests to unified generation functions, with specialized handling for classroom automation and built-in security validation.**

OpenMAIC (maintained by THU-MAIC) implements a layered, extensible architecture for visual media generation that abstracts multiple third-party providers behind a consistent TypeScript interface. Whether generating AI images for slide decks or creating video content for interactive lessons, the system centralizes configuration, normalizes capabilities across providers, and enforces strict security controls. This article explores the complete flow from HTTP API endpoints down to server-side classroom pipelines.

## Provider Registry Architecture

OpenMAIC maintains static provider registries that declare supported capabilities and constraints for each image and video service.

### Image Providers

The **`IMAGE_PROVIDERS`** map in [`lib/media/image-providers.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/media/image-providers.ts) (lines 33-61) defines each supported image provider—including Seedream, OpenAI, and MiniMax—along with required API keys, default base URLs, available models, and constraints such as supported aspect ratios and resolutions. This registry enables the system to validate requests before dispatching to concrete adapters.

### Video Providers

Similarly, **`VIDEO_PROVIDERS`** in [`lib/media/video-providers.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/media/video-providers.ts) (lines 22-53) catalogs video generation services with additional metadata for maximum duration limits and resolution tiers. The registry pattern ensures that new providers can be added without modifying downstream consumption code.

## Unified Generation Interface

Rather than implementing provider-specific logic in API routes, OpenMAIC exposes two primary dispatcher functions that handle adapter selection internally.

### Image Generation Dispatch

The **`generateImage(config, options)`** function (implemented in [`lib/media/image-providers.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/media/image-providers.ts), lines 91-115) receives a configuration object containing the provider ID, API key, and model selection. It uses a `switch` statement to route the request to the appropriate adapter (e.g., Seedream, OpenAI, or MiniMax) and returns a standardized result object containing either a remote URL or base64-encoded binary data.

```typescript
import { generateImage, IMAGE_PROVIDERS } from '@/lib/media/image-providers';

const cfg = {
  providerId: 'openai-image' as const,
  apiKey: process.env.OPENAI_API_KEY!,
  baseUrl: undefined,
  model: 'gpt-image-2',
};

const opts = { 
  prompt: 'A futuristic cityscape at sunset', 
  aspectRatio: '16:9' 
};

const result = await generateImage(cfg, opts);
// result.url → remote image URL OR result.base64 → inline PNG data

```

### Video Generation and Option Normalization

Video generation follows a parallel pattern through **`generateVideo(config, options)`** in [`lib/media/video-providers.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/media/video-providers.ts) (lines 91-106), but includes an additional validation layer. Before dispatching to the provider adapter, **`normalizeVideoOptions()`** (lines 54-88) validates and coerces the requested duration, aspect ratio, and resolution to the first supported value if the client-supplied parameters are missing or incompatible with the selected provider's capabilities.

## HTTP API Endpoints

OpenMAIC exposes media generation through RESTful endpoints that handle provider resolution, authentication, and parameter preprocessing.

### Image Generation Endpoint

The image endpoint at `POST /api/generate/image` (implemented in [`app/api/generate/image/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/generate/image/route.ts)) performs the following sequence:

1. Resolves the provider ID from request headers, falling back to server-configured defaults (lines 19-20)
2. Validates the API key against server-side configuration (lines 47-61)
3. Optionally derives pixel dimensions from aspect ratio strings (lines 78-84)
4. Invokes `generateImage()` with the resolved configuration

### Video Generation Endpoint

The video endpoint at `POST /api/generate/video` ([`app/api/generate/video/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/generate/video/route.ts)) follows a similar flow but incorporates option normalization:

1. Resolves provider, API key, and model from headers or server config (lines 47-61)
2. Calls `normalizeVideoOptions()` to validate duration, aspect ratio, and resolution constraints (lines 96-100)
3. Executes `generateVideo()` with normalized parameters

```bash
curl -X POST https://your-maic-host/api/generate/video \
  -H "Content-Type: application/json" \
  -H "x-video-provider: minimax-video" \
  -d '{
        "prompt": "A dragon flying over mountains",
        "duration": 6,
        "aspectRatio": "16:9",
        "resolution": "720p"
      }'

```

## Server-Side Classroom Media Pipeline

For automated content generation within educational contexts, OpenMAIC implements **`generateMediaForClassroom()`** in [`lib/server/classroom-media-generation.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/server/classroom-media-generation.ts) (lines 84-138). This function iterates over media generation requests embedded in scene outlines and manages the complete lifecycle:

- **Provider Selection**: Picks the first enabled image or video provider, respecting server-wide "disabled" flags (lines 84-102)
- **Configuration Resolution**: Retrieves API keys and models from server configuration via [`lib/server/provider-config.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/server/provider-config.ts)
- **Execution**: Calls `generateImage()` or `generateVideo()` with appropriate parameters
- **Asset Management**: Downloads the resulting binary (base64 or URL) and persists it to the classroom's `media/` directory (lines 112-138)
- **URL Mapping**: Returns a map of element IDs to public serving URLs, enabling client-side replacement of placeholder references

This pipeline powers automated slide deck generation and interactive lesson media without requiring manual file uploads.

## Security and Governance Layer

Throughout the media generation stack, OpenMAIC enforces several protective mechanisms according to the source code in `THU-MAIC/OpenMAIC`:

- **Server Precedence**: Force-disabled providers in server configuration cannot be overridden by client headers, ensuring administrative control over available services
- **API Key Validation**: Managed providers (server-controlled) ignore client-supplied keys, while unmanaged providers require valid key validation before dispatch
- **SSRF Protection**: User-supplied base URLs undergo validation via `validateUrlForSSRF()` implemented in [`lib/server/ssrf-guard.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/server/ssrf-guard.ts) before any outbound requests in production environments
- **Content Safety**: Responses containing "SensitiveContent" errors are caught and returned as specific API error codes, preventing the propagation of policy-violating media

## Summary

- OpenMAIC uses static provider registries (`IMAGE_PROVIDERS` and `VIDEO_PROVIDERS`) to declare capabilities and constraints for each supported generation service
- Unified dispatcher functions `generateImage()` and `generateVideo()` abstract provider-specific implementations behind consistent TypeScript interfaces
- Video generation includes `normalizeVideoOptions()` to enforce duration, resolution, and aspect ratio constraints before dispatch
- HTTP endpoints at `/api/generate/image` and `/api/generate/video` handle authentication, provider resolution, and parameter preprocessing
- The `generateMediaForClassroom()` pipeline automates media creation for educational content, managing download, storage, and URL generation
- Security layers enforce server-side provider control, API key validation, SSRF protection, and content safety filtering throughout the stack

## Frequently Asked Questions

### How does OpenMAIC handle unsupported video resolutions or aspect ratios?

OpenMAIC automatically normalizes video parameters through the `normalizeVideoOptions()` function in [`lib/media/video-providers.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/media/video-providers.ts). If a client requests a duration, aspect ratio, or resolution that the selected provider does not support, the function coerces the value to the first supported option in the provider's capability list before dispatching the generation request.

### Can I use my own API key for media generation in OpenMAIC?

It depends on the provider configuration. For unmanaged providers, OpenMAIC accepts client-supplied API keys via request headers, validated in the route handlers. However, managed providers configured at the server level ignore client-supplied keys and use the server-configured credentials instead, ensuring centralized billing and access control.

### Where does OpenMAIC store generated media files for classroom content?

When processing classroom scenes, `generateMediaForClassroom()` in [`lib/server/classroom-media-generation.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/server/classroom-media-generation.ts) downloads the generated binary data (whether returned as base64 or remote URL) and writes files to the classroom's designated `media/` directory. The function then returns public serving URLs mapped to element IDs, allowing the frontend to render the assets without direct access to the generation APIs.

### What prevents SSRF attacks when specifying custom base URLs for providers?

OpenMAIC implements SSRF protection through `validateUrlForSSRF()` in [`lib/server/ssrf-guard.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/server/ssrf-guard.ts). This function validates user-supplied base URLs before they are used for outbound requests, particularly in production environments, preventing the system from making requests to internal network addresses or restricted IP ranges.