> ## Documentation Index
> Fetch the complete documentation index at: https://docs.imperial.gay/llms.txt
> Use this file to discover all available pages before exploring further.

# Video Support

> How Imperial handles video uploads with automatic thumbnail generation

## Video Hosting Made Easy

Imperial supports video uploads with automatic processing, thumbnail generation, and optimized CDN delivery. Upload videos just like images - no special configuration needed.

<Info>
  Videos can be uploaded via the [Dashboard](https://app.imperial.gay) or through the [Upload API](/api-reference/endpoint/create).
</Info>

## Supported Video Formats

<CardGroup cols={2}>
  <Card title="MP4" icon="file-video">
    **Most Common**

    * Codec: H.264, H.265
    * Best browser support
    * Efficient compression
  </Card>

  <Card title="WebM" icon="file-video">
    **Web Optimized**

    * Codec: VP8, VP9, AV1
    * Open source
    * Great for web
  </Card>

  <Card title="MOV" icon="file-video">
    **Apple Format**

    * Codec: ProRes, H.264
    * High quality
    * Large file sizes
  </Card>

  <Card title="AVI" icon="file-video">
    **Legacy Format**

    * Various codecs
    * Wide compatibility
    * Less efficient
  </Card>
</CardGroup>

## Automatic Thumbnail Generation

Every video uploaded to Imperial automatically generates a thumbnail for faster gallery loading and video previews.

### How It Works

<Steps>
  <Step title="Video Upload">
    You upload a video file through the dashboard or API
  </Step>

  <Step title="Frame Extraction">
    Imperial uses FFmpeg to extract a frame at the 1-second mark
  </Step>

  <Step title="Optimization">
    The frame is resized and compressed to JPEG format
  </Step>

  <Step title="CDN Upload">
    Both video and thumbnail are uploaded to R2 and cached globally
  </Step>

  <Step title="Ready to Use">
    Thumbnail URL is included in the API response
  </Step>
</Steps>

### Example Response

```json theme={null}
{
  "_id": "67d8f9a1b2c3d4e5f6789013",
  "url": "https://origin.imperial.gay/uploads/user-id/video.mp4",
  "thumbnailUrl": "https://origin.imperial.gay/uploads/user-id/thumbs/thumb.jpg",
  "mimeType": "video/mp4",
  "fileSize": 15728640,
  "createdAt": "2026-01-07T12:35:00.123Z"
}
```

<Tip>
  Thumbnails are cached for **90 days** on the CDN for instant loading in galleries.
</Tip>

## Technical Implementation

### FFmpeg Processing

Imperial uses **FFmpeg**, the industry-standard video processing tool:

```javascript theme={null}
// Simplified version of thumbnail generation
async function generateVideoThumbnail(videoBuffer, timeSeconds = 1) {
  return new Promise((resolve, reject) => {
    const command = ffmpeg()
      .input(videoBuffer)
      .seekInput(timeSeconds)           // Jump to 1 second
      .frames(1)                        // Extract 1 frame
      .size('640x?')                    // Scale to 640px width (maintain aspect)
      .format('image2')                 // Output as image
      .outputOptions([
        '-q:v 2',                       // High quality JPEG
        '-update 1'                     // Single frame output
      ])
      .on('end', () => resolve(buffer))
      .on('error', reject);
    
    command.run();
  });
}
```

### Processing Pipeline

```
Video Upload (video.mp4)
    ↓
FFmpeg Frame Extraction
    ├─ Seek to 1 second
    ├─ Extract frame
    └─ Output as JPEG
    ↓
Sharp Optimization
    ├─ Resize to 640px width
    ├─ Compress to 80% quality
    └─ Strip metadata
    ↓
R2 Upload
    ├─ Video: /uploads/user-id/video.mp4
    └─ Thumbnail: /uploads/user-id/thumbs/thumb.jpg
    ↓
Cloudflare CDN Cache
    ├─ Video: Long-term cache
    └─ Thumbnail: Extended cache (90 days)
```

## Video Streaming

### Range Request Support

Imperial's CDN supports **HTTP range requests**, enabling:

<CardGroup cols={2}>
  <Card title="Seek/Skip" icon="forward">
    Users can jump to any point in the video
  </Card>

  <Card title="Resume Playback" icon="play">
    Continue watching after interruption
  </Card>

  <Card title="Partial Downloads" icon="download">
    Download only the needed portion
  </Card>

  <Card title="Bandwidth Savings" icon="chart-line">
    Don't load entire video upfront
  </Card>
</CardGroup>

### How Range Requests Work

```bash theme={null}
# Client requests first 1MB
curl -H "Range: bytes=0-1048575" \
  https://origin.imperial.gay/uploads/user-id/video.mp4

# Response
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1048575/15728640
Content-Length: 1048576

# Client can then request next chunk
curl -H "Range: bytes=1048576-2097151" \
  https://origin.imperial.gay/uploads/user-id/video.mp4
```

## Playback Optimization

### Browser Compatibility

Videos are delivered with optimal settings for all major browsers:

| Browser | Preferred Format        | Fallback |
| ------- | ----------------------- | -------- |
| Chrome  | MP4 (H.264), WebM (VP9) | MP4      |
| Firefox | MP4 (H.264), WebM (VP9) | MP4      |
| Safari  | MP4 (H.264)             | MP4      |
| Edge    | MP4 (H.264), WebM (VP9) | MP4      |

<Info>
  **MP4 with H.264** has the best compatibility across all devices and browsers.
</Info>

### Mobile Optimization

Special handling for mobile devices:

<Tabs>
  <Tab title="Mobile Networks">
    **Adaptive Loading**:

    * Start with thumbnail display
    * Load video only when played
    * Support for lower quality on slow connections
  </Tab>

  <Tab title="Battery Saving">
    **Efficient Playback**:

    * Hardware-accelerated decoding
    * Pause when tab is backgrounded
    * Respect battery saver modes
  </Tab>

  <Tab title="Data Saving">
    **Bandwidth Control**:

    * Resume from where left off
    * Cancel downloads if paused
    * Respect data saver settings
  </Tab>
</Tabs>

## Storage Considerations

### File Size Guidelines

Videos can be significantly larger than images:

| Quality | Resolution | Duration | Approx Size |
| ------- | ---------- | -------- | ----------- |
| Low     | 480p       | 1 min    | 5-10 MB     |
| Medium  | 720p       | 1 min    | 15-25 MB    |
| High    | 1080p      | 1 min    | 40-80 MB    |
| Ultra   | 4K         | 1 min    | 150-300 MB  |

<Warning>
  Video files count toward your storage limit. A single 4K video can use as much space as thousands of images.
</Warning>

### Compression Recommendations

Unlike images, Imperial **doesn't compress videos** automatically. Compress before uploading:

<AccordionGroup>
  <Accordion title="FFmpeg (Command Line)">
    ```bash theme={null}
    # Compress to H.264 at 720p
    ffmpeg -i input.mp4 \
      -c:v libx264 \
      -preset slow \
      -crf 23 \
      -vf scale=1280:720 \
      -c:a aac -b:a 128k \
      output.mp4
    ```

    * `-crf 23`: Quality (18-28, lower = better)
    * `-preset slow`: Slower encoding, better compression
    * `scale=1280:720`: Resize to 720p
  </Accordion>

  <Accordion title="HandBrake (GUI)">
    **Desktop application** for easy video compression:

    1. Load your video
    2. Select "Web" preset
    3. Choose quality (RF 20-24)
    4. Click "Start"

    Download: [https://handbrake.fr](https://handbrake.fr)
  </Accordion>

  <Accordion title="CloudConvert (Online)">
    **Web-based** video converter:

    1. Upload video
    2. Convert to MP4
    3. Set quality/resolution
    4. Download result

    Visit: [https://cloudconvert.com](https://cloudconvert.com)
  </Accordion>
</AccordionGroup>

## API Integration

### Upload Video

```bash theme={null}
curl -X POST https://api.imperial.gay/images/upload \
  -H "Authorization: Bearer imperial_live_xxxxxxxxxxxxx" \
  -F "file=@video.mp4"
```

### Response with Thumbnail

```json theme={null}
{
  "_id": "67d8f9a1b2c3d4e5f6789013",
  "url": "https://origin.imperial.gay/uploads/user-id/67d8f9a1b2c3d4e5f6789013-video.mp4",
  "thumbnailUrl": "https://origin.imperial.gay/uploads/user-id/thumbs/67d8f9a1b2c3d4e5f6789013-thumb.jpg",
  "filename": "67d8f9a1b2c3d4e5f6789013-video.mp4",
  "originalFilename": "video.mp4",
  "fileSize": 15728640,
  "mimeType": "video/mp4",
  "compressed": false,
  "createdAt": "2026-01-07T12:35:00.123Z"
}
```

### Embed in HTML

```html theme={null}
<!-- Simple video player -->
<video controls poster="https://origin.imperial.gay/.../thumb.jpg">
  <source src="https://origin.imperial.gay/.../video.mp4" type="video/mp4">
  Your browser doesn't support video playback.
</video>

<!-- With thumbnail fallback -->
<div class="video-container">
  <img src="https://origin.imperial.gay/.../thumb.jpg" 
       alt="Video thumbnail"
       class="thumbnail">
  <video controls>
    <source src="https://origin.imperial.gay/.../video.mp4" type="video/mp4">
  </video>
</div>
```

## Performance Metrics

### Thumbnail Generation Time

| Video Size | Resolution | Generation Time |
| ---------- | ---------- | --------------- |
| 10 MB      | 1080p      | 1-2 seconds     |
| 50 MB      | 1080p      | 2-4 seconds     |
| 100 MB     | 4K         | 4-6 seconds     |
| 500 MB     | 4K         | 10-15 seconds   |

<Info>
  Thumbnail generation happens asynchronously. The video is immediately available even if thumbnail generation is still processing.
</Info>

### CDN Delivery Performance

First load (uncached):

```
Request → Cloudflare Edge
    ↓ (cache miss)
    Fetch from R2: 200-500ms
    ↓
    Cache at edge
    ↓
    Stream to user: 1-5s (depends on size/bandwidth)
```

Subsequent loads (cached):

```
Request → Cloudflare Edge
    ↓ (cache hit)
    Stream from edge cache: 0.1-1s
```

## Limitations

<Warning>
  **Current Limitations:**

  * No transcoding (upload optimized videos)
  * No adaptive bitrate streaming
  * No live streaming support
  * Maximum file size limited by storage tier
</Warning>

### Future Features (Coming Soon)

* ✨ Multiple quality options (auto-generated 720p/480p)
* ✨ Adaptive bitrate streaming (HLS/DASH)
* ✨ Custom thumbnail selection (choose frame)
* ✨ Video analytics (views, watch time)

## Best Practices

<AccordionGroup>
  <Accordion title="Optimize Before Upload">
    * Compress videos with FFmpeg or HandBrake
    * Use H.264 codec for best compatibility
    * Target 720p or 1080p for web use
    * Use reasonable bitrates (2-8 Mbps for 1080p)
  </Accordion>

  <Accordion title="Choose Right Format">
    * **MP4 (H.264)**: Best for general use
    * **WebM (VP9)**: Good for web-only
    * Avoid uncompressed formats (AVI, MOV)
  </Accordion>

  <Accordion title="Consider File Size">
    * Keep videos under 100 MB when possible
    * Split longer videos into segments
    * Use thumbnails effectively in galleries
  </Accordion>

  <Accordion title="Test Playback">
    * Verify on mobile and desktop
    * Check loading times
    * Ensure thumbnails load quickly
  </Accordion>
</AccordionGroup>

## Troubleshooting

### Thumbnail Not Generating

Possible causes:

* Video codec not supported by FFmpeg
* Video file corrupted
* Video too short (\< 1 second)
* Processing timeout (very large files)

**Solution**: Re-upload or try a different format (MP4 with H.264).

### Video Won't Play

Possible causes:

* Browser doesn't support codec
* File size too large for device
* Network issues

**Solution**: Use MP4 with H.264 for best compatibility.

### Slow Loading

Possible causes:

* Video not optimized (high bitrate)
* User on slow connection
* Cold start (not cached yet)

**Solution**: Compress video before upload, or wait for CDN cache to warm up.

## Get Started

Ready to upload videos?

<Card title="Upload Your First Video" icon="rocket" href="/quickstart">
  Try video hosting with automatic thumbnails
</Card>
