# Video Compressor for Websites – Smaller MP4, Plays Instantly (`mauberme/video-for-web`) Actor

Heavy videos slow down websites. Paste video links and get a lighter MP4 (and optional WebM) resized to 360-1080p that starts playing immediately, plus a cover image. Never makes a video bigger than the original. Free during launch.

- **URL**: https://apify.com/mauberme/video-for-web.md
- **Developed by:** [Mauberme](https://apify.com/mauberme) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Video Compressor for Websites – Smaller MP4, Plays Instantly

**What is it for?** Heavy videos make websites slow and eat mobile data. Paste links to your videos and get a **lighter copy made for the web**: resized to the height you choose, set up to **start playing instantly** instead of downloading first, plus a **cover image** to show before it plays. If the original is already efficient, it is only optimised, never made bigger.

Compress and resize videos for your website in one run. Give it a list of **public video URLs**
(MP4, MOV, MKV, WebM, AVI… anything ffmpeg reads) and get back **web-ready MP4 files (H.264 + AAC,
`faststart`)**, optional **WebM (VP9 + Opus)** versions and a **JPEG poster frame** for the
`<video poster>` attribute, all downloadable from public links. Great for shrinking 4K phone or
camera footage to 1080p/720p, preparing hero/background videos (muted), or batch-converting a
video library before uploading it to a CMS or CDN.

### What it does

- Downloads each video (http/https only, size-limited, internal network addresses blocked).
- Reads duration and resolution with `ffprobe`.
- Resizes down to your **maximum height** (360, 480, 720 or 1080 px), keeping the aspect ratio.
  **It never upscales**: a 480p source stays 480p.
- Encodes **MP4 H.264** (`yuv420p`, High profile, CRF quality) with **`-movflags +faststart`**, so
  playback starts before the whole file is downloaded — the #1 fix for slow web videos.
- Optionally encodes **WebM VP9** (smaller files for modern browsers).
- Keeps audio as AAC 128 kbps stereo, or **removes audio** for silent autoplay/background videos.
- Extracts a **poster image** (JPEG) at the second you choose.

### Input example

```json
{
  "videos": [
    "https://download.samplelib.com/mp4/sample-5s.mp4",
    "https://example.com/uploads/product-demo-4k.mov"
  ],
  "maxHeight": 1080,
  "formats": ["mp4", "webm"],
  "crf": 23,
  "audio": "keep",
  "poster": true,
  "posterAt": 1,
  "maxDurationSeconds": 600,
  "maxFileSizeMb": 500
}
```

| Field | Default | Notes |
|---|---|---|
| `videos` | — | Public URLs, up to 100 per run |
| `maxHeight` | `1080` | `360`, `480`, `720` or `1080`. Never upscales |
| `formats` | `["mp4"]` | `mp4` and/or `webm` |
| `crf` | `23` | 18 (best) – 35 (smallest). WebM uses CRF + 10 on the VP9 scale |
| `audio` | `keep` | `remove` for muted hero/background videos |
| `poster` / `posterAt` | `true` / `1` | Poster frame second (clamped to the video length) |
| `maxDurationSeconds` | `600` | Longer videos are **rejected with an error**, never trimmed. Hard cap 1800 |
| `maxFileSizeMb` | `500` | Download size cap. Hard cap 2000 |

### Output example

One dataset row per video **and** format:

```json
{
  "sourceUrl": "https://download.samplelib.com/mp4/sample-5s.mp4",
  "format": "mp4",
  "width": 854,
  "height": 480,
  "durationSeconds": 5.76,
  "inputBytes": 2848208,
  "outputBytes": 1643265,
  "compressionRatio": 1.73,
  "videoUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/001-sample-5s.mp4",
  "posterUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/001-sample-5s-poster.jpg",
  "error": null
}
```

`compressionRatio` = input bytes / output bytes (2.0 means the new file is half the size).
If a video fails (download error, not a video, too long…) you get a row with `error` filled in and
the run continues with the next video. The files live in the run's default key-value store.

Embed the result:

```html
<video controls playsinline preload="metadata" poster="POSTER_URL">
  <source src="WEBM_URL" type="video/webm">
  <source src="MP4_URL" type="video/mp4">
</video>
```

### Pricing

**Free during launch.** This Actor has no usage fee of its own: you only pay Apify's standard platform usage for your runs (on the free Apify plan that is covered by your monthly credit). A pay-per-result price may be introduced later; Apify notifies users in advance of any price change.

### Limits

- Up to 100 videos per run, processed one after another.
- Max duration per video: `maxDurationSeconds` (default 10 min, hard cap 30 min).
- Max input size: `maxFileSizeMb` (default 500 MB, hard cap 2 GB). Downloads time out after 15 min.
- Only public `http`/`https` URLs. Private/internal network addresses are refused.
  No login, cookies or YouTube/social-media page URLs — use a direct file URL.
- Output is capped at 1080p; the Actor never upscales.
- Only the first video and first audio track are kept; subtitles, chapters and metadata are dropped.
- Recommended memory: 4096 MB (default). More memory = more CPU = faster encodes (same price).
  Long WebM encodes are slow: raise the run timeout for big batches.

# Actor input Schema

## `videos` (type: `array`):

Public http(s) URLs of the videos to compress (MP4, MOV, MKV, WebM, AVI… anything ffmpeg can read). Up to 100 per run.

## `maxHeight` (type: `integer`):

Output height cap: 360, 480, 720 or 1080. Videos smaller than this keep their size (never upscaled). Aspect ratio is preserved.

## `formats` (type: `array`):

mp4 = H.264 + AAC with faststart (plays everywhere). webm = VP9 + Opus (smaller, modern browsers). Each format is billed separately.

## `crf` (type: `integer`):

Constant Rate Factor for H.264: lower = better quality and bigger files. 23 is a good web default; 18 is near-lossless; 28 is small. WebM uses CRF + 10 on the VP9 scale.

## `audio` (type: `string`):

keep = AAC 128 kbps stereo (Opus 96 kbps in WebM). remove = silent video, e.g. for background/hero videos.

## `poster` (type: `boolean`):

Extract a JPEG frame to use as the <video poster> attribute.

## `posterAt` (type: `integer`):

Second of the video used for the poster frame. Clamped to the video length.

## `maxDurationSeconds` (type: `integer`):

Longer videos are rejected with an error row (never trimmed silently). Hard cap: 1800 s (30 min).

## `maxFileSizeMb` (type: `integer`):

Downloads bigger than this are aborted. Hard cap: 2000 MB.

## Actor input object example

```json
{
  "videos": [
    "https://download.samplelib.com/mp4/sample-5s.mp4"
  ],
  "maxHeight": 1080,
  "formats": [
    "mp4"
  ],
  "crf": 23,
  "audio": "keep",
  "poster": true,
  "posterAt": 1,
  "maxDurationSeconds": 600,
  "maxFileSizeMb": 500
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `files` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "videos": [
        "https://download.samplelib.com/mp4/sample-5s.mp4"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mauberme/video-for-web").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "videos": ["https://download.samplelib.com/mp4/sample-5s.mp4"] }

# Run the Actor and wait for it to finish
run = client.actor("mauberme/video-for-web").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videos": [
    "https://download.samplelib.com/mp4/sample-5s.mp4"
  ]
}' |
apify call mauberme/video-for-web --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mauberme/video-for-web"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/twc9Y7nXVj6U6FVDQ/builds/NwvhnJAzfvu6WZHpC/openapi.json
