WebM to MP4 Converter
Pricing
from $39.00 / 1,000 video converteds
WebM to MP4 Converter
Convert WebM video files to MP4 format using FFmpeg. Fast, reliable transcoding with support for batch URLs and custom output settings.
Pricing
from $39.00 / 1,000 video converteds
Rating
0.0
(0)
Developer
junipr
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Convert WebM video files to MP4 format using FFmpeg. Accepts WebM URLs or Apify Key-Value Store keys, transcodes using H.264 (or H.265) video codec with AAC audio, and outputs MP4 files with direct download links. Supports configurable resolution, bitrate, quality presets, frame rate, and audio settings. Handles capped batches of up to 3 videos per run with explicit file-size and duration limits.
WebM is increasingly common — browsers use it natively via the MediaRecorder API, it's the default for screen recordings in Chrome and Firefox, and many scraping pipelines encounter it. The problem is that most downstream tools, social platforms, and video players prefer MP4. This actor closes that gap with zero configuration required.
Why Use This Actor
There is no other dedicated WebM-to-MP4 conversion actor on the Apify Store. Users currently rely on desktop tools that require installation (HandBrake, FFmpeg CLI), online converters with file size limits, or build their own FFmpeg Docker pipelines. This actor handles the capped pipeline — download, transcode, upload to KV Store, return download URL — with a single API call.
Cost Comparison
| Service | Price per 1,000 conversions | File size limit | Batch processing |
|---|---|---|---|
| This actor | $39.00 | 50MB default, 100MB max | Up to 3/run |
| CloudConvert | ~$8.00 | 1GB (free: 25MB) | 25/job |
| Zamzar | ~$15.00 | 50MB (free) | 5 at a time |
| Convertio | ~$10.00 | 100MB (free) | 10 at a time |
No account or API key required beyond Apify — the actor uses the Apify Key-Value Store for output automatically. FFmpeg runs locally inside the actor, so your video data never passes through a third-party conversion service.
Output files are web-optimized by default: the MP4 moov atom is placed at the beginning of the file (faststart mode), which allows browsers to begin playback before the entire file has loaded.
How to Use
Zero-Config (Quick Start)
The actor works with no configuration. Default settings produce a web-compatible H.264 MP4 with AAC audio:
{"videos": [{ "url": "https://example.com/recording.webm" }]}
After the run completes, the dataset contains a record with outputUrl — a direct download link for the converted MP4 from the Apify Key-Value Store.
Convert from KV Store
If you have a WebM file already stored in the actor's Key-Value Store (e.g., uploaded via the Apify API), reference it by key:
{"videos": [{ "kvStoreKey": "my-recording.webm" }]}
Quality Configuration
{"videos": [{ "url": "https://example.com/recording.webm" }],"videoCodec": "h264","preset": "slow","crf": 18,"maxWidth": 1920,"audioBitrate": "192k","fastStart": true}
Calling via Apify API
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });const run = await client.actor('junipr/webm-to-mp4').call({videos: [{ url: 'https://example.com/lecture.webm' }],videoCodec: 'h264',preset: 'balanced',crf: 23,});const dataset = await client.dataset(run.defaultDatasetId).listItems();const result = dataset.items[0];console.log('Download URL:', result.outputUrl);
Downloading Converted Files
Each dataset item contains an outputUrl with a direct download link:
curl -L "https://api.apify.com/v2/key-value-stores/{storeId}/records/converted_myvideo.mp4" \-H "Authorization: Bearer YOUR_API_TOKEN" \-o myvideo.mp4
Input Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
videos | array | (sample URL) | List of { url } or { kvStoreKey } objects. Max 3. |
videoCodec | string | "h264" | Video codec: h264 or h265 |
preset | string | "balanced" | Speed/quality tradeoff: ultrafast, fast, balanced, slow, veryslow |
crf | integer | 23 | Quality: 0 (lossless) to 51 (worst). 18–28 is typical range. |
maxBitrate | string | null | Cap bitrate: "2M", "5M". Null = CRF-only. |
resolution | string | null | Force resolution: "1920x1080", "1280x720" |
maxWidth | integer | null | Scale down if wider than this (preserves aspect ratio) |
maxHeight | integer | null | Scale down if taller than this (preserves aspect ratio) |
fps | integer | null | Output frame rate (1–120). Null = same as input. |
audioCodec | string | "aac" | Audio: aac, mp3, or none (strip audio) |
audioBitrate | string | "128k" | Audio bitrate: 64k, 128k, 192k, 320k |
audioSampleRate | integer | null | Sample rate in Hz. Null = same as input. |
volume | number | 1.0 | Volume multiplier: 0.5 = half, 2.0 = double |
outputPrefix | string | "converted_" | Prefix for output KV Store keys |
fastStart | boolean | true | Move moov atom to start for web streaming |
maxConcurrency | integer | 1 | Concurrent conversions (1–3) |
downloadTimeout | integer | 60000 | Per-video download timeout in ms |
conversionTimeout | integer | 300000 | Per-video FFmpeg timeout in ms |
maxFileSizeMb | number | 50 | Maximum source file size per video, capped at 100MB |
maxDurationSeconds | number | 300 | Maximum source duration per video, capped at 600 seconds |
Common Configurations
Quick convert (defaults — best compatibility):
{ "videos": [{ "url": "..." }] }
Web optimized (streaming-ready, 720p max):
{ "videos": [{ "url": "..." }], "videoCodec": "h264", "crf": 23, "maxHeight": 720, "fastStart": true }
High quality (archive, large files):
{ "videos": [{ "url": "..." }], "videoCodec": "h264", "crf": 18, "preset": "slow" }
Maximum compression (smallest files, slowest):
{ "videos": [{ "url": "..." }], "videoCodec": "h265", "crf": 28, "preset": "veryslow" }
Output Format
Each converted video produces one dataset item:
{"sourceUrl": "https://example.com/recording.webm","sourceKvKey": null,"outputKvKey": "converted_recording.mp4","outputUrl": "https://api.apify.com/v2/key-value-stores/{storeId}/records/converted_recording.mp4","inputFormat": "webm","inputCodec": "vp9","inputDurationSeconds": 42.5,"inputWidth": 1920,"inputHeight": 1080,"inputSizeBytes": 15728640,"outputDurationSeconds": 42.5,"outputWidth": 1920,"outputHeight": 1080,"outputSizeBytes": 8388608,"outputVideoCodec": "h264","outputAudioCodec": "aac","outputFps": 30,"compressionRatio": 0.53,"conversionTimeMs": 12340,"convertedAt": "2026-03-11T10:30:00.000Z","errors": []}
A compressionRatio below 1.0 means the output is smaller than the input. Values above 1.0 can occur with lossless CRF settings or very short clips where codec overhead dominates.
The Key-Value Store also contains an OUTPUT record with a run summary including totals, averages, and the codec configuration used.
Tips and Advanced Usage
Choosing Between H.264 and H.265
Use H.264 (default) for: web playback, social media uploads, sharing, anything that needs to play in browsers or on mobile devices. It is supported on 99%+ of devices.
Use H.265 for: archiving, internal storage, and delivery to controlled playback environments (iOS apps with hardware H.265 support, smart TVs). H.265 files are typically 30–50% smaller at equivalent quality, but most web browsers do not support H.265 natively.
Understanding CRF
CRF (Constant Rate Factor) controls quality, not file size directly. A CRF of 18 produces very high quality files that are noticeably larger than CRF 23. For most use cases:
- CRF 18–20: High quality (visually lossless)
- CRF 23: Default, good balance of quality and size
- CRF 26–28: Acceptable quality, significantly smaller files
- CRF 0: True lossless — output may be larger than input; not recommended for web
Optimal Settings by Use Case
| Use Case | Codec | CRF | Preset | Notes |
|---|---|---|---|---|
| Web streaming | h264 | 23 | balanced | Add fastStart: true (default) |
| Social media | h264 | 20 | fast | Check platform max resolution |
| Mobile app | h264 | 23 | balanced | maxWidth: 1280 for bandwidth |
| Archive | h265 | 22 | slow | Smaller long-term storage |
| Fast processing | h264 | 25 | ultrafast | Trade quality for speed |
Batch Processing
To convert a large video library, split into runs of 3 videos. Use maxConcurrency: 2 only on short, small videos. For longer videos, keep maxConcurrency: 1 to avoid memory pressure.
Pricing
This actor uses Pay-Per-Event (PPE) pricing: $39.00 per 1,000 videos converted ($0.039 per video).
Pricing includes all platform compute costs — no hidden fees.
PPE charges are attempted only after input validation, download, size checks, duration checks, and media probing pass. Invalid URLs, SSRF-blocked URLs, missing KV keys, oversized files, over-duration files, and invalid media are not charged or pushed to the default dataset. If the Apify PPE budget is exhausted, the actor stops before conversion and writes a diagnostic record to the key-value store instead of the default dataset.
| Scenario | Videos | Estimated Cost |
|---|---|---|
| Single conversion | 1 | $0.039 |
| Browser recording batch | 20 | $0.39 |
| Screen recording library | 200 | $3.90 |
| Video dataset | 2,000 | $39.00 |
| Large-scale conversion | 10,000 | $195.00 |
FAQ
What is the maximum file size I can convert?
The default max source size is 50MB per video and the hard cap is 100MB per video. The default duration cap is 300 seconds and the hard cap is 600 seconds. Split larger files before running the actor.
Can I convert other formats besides WebM?
Yes. FFmpeg detects the actual input format regardless of file extension. MP4, AVI, MKV, MOV, FLV, and other common formats will convert successfully. The actor logs the detected input format in the dataset item.
What is the difference between H.264 and H.265?
H.264 (AVC) is the current standard: universally compatible, supported on virtually all browsers, devices, and platforms. H.265 (HEVC) is the next generation: produces 30–50% smaller files at equivalent quality, but requires hardware decoding support on the playback device and is not natively supported by most web browsers. Choose H.264 unless you have specific reasons to use H.265.
What CRF value should I use?
For most web use cases, the default CRF 23 is a good starting point. If you need higher quality (for example, a source video with a lot of fine detail), try CRF 18–20. If file size is the priority, try CRF 26–28. Avoid CRF 0 (lossless) unless you specifically need lossless output — the file sizes are enormous.
Does conversion reduce video quality?
All lossy encoding introduces some quality reduction. At CRF 23 with H.264, the quality loss is imperceptible for most content. At CRF 18, the output is visually lossless for most viewers. Converting from WebM VP8/VP9 to H.264 with a reasonable CRF setting produces excellent results.
Can I convert audio-only WebM files?
Yes. If the WebM file contains only an audio stream (e.g., Opus audio from a browser recording with no video), the actor will convert it to an MP4 audio container. The output dimensions will be 0x0 and the video codec fields will be empty.
How long does conversion take?
Conversion time depends on video length, resolution, and preset. For a 30-second 1080p clip with the default "balanced" preset, expect 5–15 seconds. A 5-minute 1080p clip typically takes 30–90 seconds. The "ultrafast" preset can reduce conversion time by 3–5x at the cost of larger output files.
Are subtitles preserved during conversion?
No. WebM subtitle streams and chapter markers are not preserved during conversion to MP4. If subtitle preservation is required, extract subtitles separately before conversion.
Related actors: Video Download Link Crawler