New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

video-bitrate-calculator

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

video-bitrate-calculator

Work out the video bitrate that fits a target file size — or a platform's upload limit. Zero dependencies, browser and Node.

latest
Source
npmnpm
Version
1.0.0
Version published
Weekly downloads
4
-50%
Maintainers
1
Weekly downloads
 
Created
Source

video-bitrate-calculator

What bitrate fits your file size? The arithmetic behind every "how do I get this clip under 10 MB" question, as a zero-dependency library and a CLI.

npx video-bitrate-calculator discord 90s
Discord (free) · 1.5 min clip  10 MB limit

  ✓ video   642 kbps
    audio   128 kbps
    lands   ~8.46 MB  (target 9 MB)

  ! At 642 kbps, 1080p has more pixels than bits. Scale to 360p — same file
    size, visibly cleaner.

  ffmpeg -i input.mp4 -c:v libx264 -b:v 642k -maxrate 931k -bufsize 1284k \
    -preset veryfast -vf scale=-2:360 -c:a aac -b:a 128k -movflags +faststart output.mp4

The whole idea

size = bitrate × duration

That is it. Resolution, codec and preset matter only because they change what bitrate you can get away with. So if you know the size you need and the length of the clip, the bitrate is not a guess — it's division:

video_kbps = target_MB × 0.94 × 8192 / seconds − audio_kbps
  • 8192 because 1 MB = 1024 × 8 kilobits.
  • 0.94 is safety margin, and it's the part people skip. Encoders hit a bitrate target on average, not exactly, so aiming at 100% of a hard limit lands over it often enough to matter — and a file that misses by 40 KB is as rejected as one that misses by 40 MB. The margin also absorbs the MB-vs-MiB ambiguity: a service that says "25 MB" may mean 25,000,000 bytes or 26,214,400, and it rarely tells you which.

Install

npm install video-bitrate-calculator

Or don't — the CLI runs straight from npx, and the library is three files with no dependencies.

Library

import { bitrateForTargetSize, planFor, maxDurationSec } from "video-bitrate-calculator";

// "I need this 90-second clip under 8 MB."
bitrateForTargetSize({ targetMB: 8, durationSec: 90 });
// → { videoKbps: 556, audioKbps: 128, totalKbps: 684, feasible: true, warnings: [] }

// "Just tell me what to do for Discord."
planFor("discord", { durationSec: 90, height: 1080 });
// → { platform: 'Discord (free)', limitMB: 10, targetMB: 9, videoKbps: 642,
//     estimatedMB: 8.46, feasible: true, alreadyFits: false,
//     warnings: [...], ffmpegArgs: ['-i', 'input.mp4', ...] }

// "How long a 1080p clip even fits in 9 MB?"
maxDurationSec({ targetMB: 9, height: 1080 }); // → 13.5 seconds

API

FunctionAnswers
bitrateForTargetSize({ targetMB, durationSec, audioKbps?, safety? })What bitrate produces this size?
estimateSizeMB({ videoKbps, durationSec, audioKbps? })What size does this bitrate produce?
maxDurationSec({ targetMB, height?, quality? })How much footage fits, at watchable quality?
recommendedVideoKbps(height, quality?)What bitrate does 1080p want, ignoring limits?
suggestHeight(videoKbps, sourceHeight)This bitrate can carry which resolution?
planFor(platformId, { durationSec, height?, sourceMB?, keepAudio? })Everything, for one platform.
ffmpegArgs({ videoKbps, audioKbps?, height? })A command I can paste.
parseDuration("2m30s" | "1:30" | 90)Seconds.
PLATFORMS, getPlatform(id)The limits table.

Every function is pure, throws RangeError on nonsense input rather than returning NaN, and works unchanged in the browser.

It tells you when you're about to waste your time

The warnings array is the part that took the most care. It covers the three ways this calculation goes wrong in practice:

// You are asking for something arithmetic cannot give you
bitrateForTargetSize({ targetMB: 1, durationSec: 3600 });
// → feasible: false
// → ["1 MB over 60 min leaves -126 kbps for video, which is below the 100 kbps
//    floor. Trim the clip, drop the audio, or accept a bigger file.", ...]

// You are spending the budget on the wrong track
bitrateForTargetSize({ targetMB: 6, durationSec: 200 }).warnings;
// → ["Audio is eating 55% of the budget. Drop it (audioKbps: 0) or cut it to
//    64 kbps if it is speech.",
//    "103 kbps will look blocky above 480p. Downscale the video rather than
//    spending the bitrate on pixels nobody can see."]

// You should not be compressing at all
planFor("gmail", { durationSec: 30, sourceMB: 4 }).warnings;
// → ["Already 4 MB, under the 24 MB target. Re-encoding would only cost you
//    quality. Send it as-is."]

That last one matters more than the rest of the library: the correct answer to "how do I compress this" is often "you don't".

CLI

video-bitrate-calculator <platform> <duration> [options]
video-bitrate-calculator --size <MB> --duration <duration>
video-bitrate-calculator --list
Option
--size, -s <MB>Target size instead of a platform preset
--duration, -d <t>90 · 90s · 1:30 · 2m30s · 1:02:03
--height <px>Source frame height (default 1080)
--source <MB>Current file size, so it can tell you when to do nothing
--no-audioStrip audio and spend the bitrate on video
--audio <kbps>Audio bitrate (default 128)
--jsonMachine-readable output
--listEvery platform limit

The limits

Aim for the target, not the limit.

PlatformLimitTarget1080p fits720p fits
Discord (free)10 MB9 MB14s24s
GitHub issue / PR10 MB9 MB14s24s
WhatsApp16 MB15 MB23s39s
Outlook20 MB19 MB29s50s
Gmail25 MB24 MB36s1.1 min
Messenger25 MB24 MB36s1.1 min
Twitter / X512 MB, 2:2048 MB1.2 min2.1 min
Reddit1 GB, 15 min95 MB2.4 min4.2 min
Slack1 GB95 MB2.4 min4.2 min
Telegram2 GB95 MB2.4 min4.2 min

These numbers move. Every entry in src/platforms.js carries a checked date. If one is stale or wrong, a PR correcting it is the most useful thing you can send.

Things worth knowing

Dropping audio buys you 128 kbps. On a three-minute clip that's ~2.8 MB back — a third of a Discord upload. Free win on screen recordings with no voiceover.

Bitrate, not resolution, controls size. Downscaling helps only because it lowers the bitrate you need to look sharp. suggestHeight() exists because the reverse mistake is so common: spending 400 kbps on 1080p gives you 1080 lines of mush, and the same bits at 480p look fine.

The receiving server's limit wins. Corporate mail commonly stops at 10 MB, not Gmail's 25. If a message bounces, re-compress to 10 before debugging anything else.

H.265 and AV1 need roughly half the bitrate for the same quality — but only help if the other end can decode them. The baseBitrateKbps figures here assume H.264, because H.264 is what plays everywhere.

Development

npm test         # node:test, no framework
npm run types    # emit .d.ts from the JSDoc
npm run check    # both

19 tests, no test framework, no build step for the library itself. The round-trip test is the important one: for every combination of target size and duration, the bitrate this produces must yield a file under the target — and not wastefully under it.

Built while working on videocompress.dev, a video compressor that runs entirely in the browser — the file never leaves your machine. This library is the size math from it, extracted and made standalone.

License

MIT

Keywords

video

FAQs

Package last updated on 30 Aug 2026

Related posts