Skip to content

Releases

v0.1.9

Choose a tag to compare

@YKLovePython YKLovePython released this 07 Nov 12:24
e0201b1

iPhone HDR clips stop looking grey, and an impossible target is refused before the encode instead of after it.

  • HDR sources (iPhone HLG, HDR10/PQ) are converted to SDR BT.709 inside the same encode. Before, the output kept HDR tags on 8-bit pixels, so iPhone videos looked washed out after compression
  • Quality checks tone-map the reference frame too, so VMAF and SSIM measure compression loss instead of the HDR-to-SDR transfer curve
  • A target below the minimum bitrate for the video's duration now fails before encoding and reports the smallest achievable size, instead of spending an encode that cannot fit. --force still runs it
  • When a two-pass encode lands more than 0.5% over target, halfsize re-encodes once with a corrected bitrate instead of handing back an oversized file
  • --for email now targets 18 MB, because base64 makes a 20 MB attachment a 26.7 MB message that bounces at Gmail's 25 MB limit. New --for outlook targets 15 MB for the 20 MB message cap, and --for gmail is an explicit alias for the 18 MB one

Install

npx halfsize@0.1.9 video.mp4 --to 20mb

Full changelog: https://github.com/YKLovePython/halfsize/blob/main/CHANGELOG.md

v0.1.8

Choose a tag to compare

@YKLovePython YKLovePython released this 06 Nov 16:26

Failure modes, mostly. The kind that leave you with a file you think is fine.

  • A failed, cancelled, or interrupted encode no longer leaves a half-written video at the output path. It writes a hidden .part file next to the destination and only renames it once FFmpeg exits cleanly
  • Ctrl+C stops the running FFmpeg instead of leaving it behind, and prints cancelled with exit code 130
  • The local web app has a Cancel button, and closing the tab stops the encode after a ten-second grace period instead of letting FFmpeg run to completion
  • The web app can switch the player between the original and the compressed file, and warns when the browser cannot decode H.265
  • The web app retires the oldest uploads past the tenth, so a tab left open all day does not fill the temp directory
  • Replacing an output that another program has open now fails with a clear message and keeps the finished file, instead of deleting it
  • The version now comes from package.json alone. scripts/bump-site.mjs syncs the site and READMEs, and a test fails if they drift
  • The local app refuses a text file, an image, or an empty file with a readable message, instead of accepting it and failing later with a path to ffprobe
  • Uploaded file names are reduced to a bare file name, so nothing like ../../evil.mp4 can reach the download header
  • Malformed request bodies return 400 instead of 500, and impossible byte ranges return 416 instead of a broken stream
  • Both the CLI and the web app now say when tracks are dropped: extra audio tracks, subtitles, surround audio downmixed to stereo, and frame rates above 60 fps
  • --out refuses to overwrite the input file, and --crf, --preset, --codec, and --port are validated before encoding starts
  • Low-frame-rate sources are left alone. A 5 fps timelapse used to be forced up to 10 fps, which duplicated frames and inflated the bitrate the planner assumed

Install

npx halfsize@0.1.8 video.mp4 --to 20mb

Full changelog: https://github.com/YKLovePython/halfsize/blob/main/CHANGELOG.md

halfsize 0.1.7

Choose a tag to compare

@YKLovePython YKLovePython released this 06 Nov 04:49

0.1.7

Install reliability, based on a failure reproduced on a TLS-inspecting network.

  • ffmpeg-static and ffprobe-static are now optional dependencies. If the FFmpeg download is blocked, npm install and npx halfsize still succeed and the CLI explains how to fix the binary
  • The missing-FFmpeg message now covers the npmmirror binary mirror, NODE_OPTIONS=--use-system-ca for TLS-inspecting proxies and antivirus, a system FFmpeg, and a custom path
  • --doctor stays usable when the bundled binary is absent, so a failed download can be diagnosed before the first compression
  • README install notes (English and Chinese) document the TLS certificate case

Install

npx halfsize@0.1.7 video.mp4 --for discord

Or install it globally:

npm install -g halfsize

MIT.

halfsize 0.1.6

Choose a tag to compare

@YKLovePython YKLovePython released this 06 Nov 04:34

0.1.6

First-run friction, mostly.

  • A missing FFmpeg now shows three concrete fixes: reinstall with the bundled binary, use a system FFmpeg, or point at your own build, with the npmmirror binary mirror for slow networks
  • --doctor reports Node, both binary paths, where FFmpeg came from, and whether libvmaf is available, so a first run can be diagnosed in one command
  • --web checks FFmpeg before starting instead of failing on the first upload
  • After a successful compression, the CLI (TTY only) and the local web app show one quiet repository link. HALFSIZE_NO_PROMO=1 hides it
  • README install notes cover the first npx wait, global install, and stale cache

Install

npx halfsize@0.1.6 video.mp4 --for discord

Or install it globally:

npm install -g halfsize

MIT.

halfsize 0.1.5

Choose a tag to compare

@YKLovePython YKLovePython released this 05 Nov 12:44

0.1.5

Discord and WeChat both moved to 20 MB, so the presets did too.

  • --for discord now targets 20 MB (Discord's free cap since August 2026)
  • --for wechat now targets 20 MB
  • Web app presets and copy match the current caps
  • README ships a measured quality table for 20 / 16 / 10 / 5 MB
  • New per-platform guides: https://YKLovePython.github.io/halfsize/

Install

npx halfsize@0.1.5 video.mp4 --for discord

Or install it globally:

npm install -g halfsize

MIT.

halfsize 0.1.4

Choose a tag to compare

@YKLovePython YKLovePython released this 04 Nov 07:46

Batch mode, platform presets, and a fix for audio/stream handling.

New

  • halfsize a.mp4 b.mp4 c.mp4 --to 10mb compresses several files in one command
  • --for discord|whatsapp|wechat|email|twitter uses the platform's upload cap
  • --no-audio drops the soundtrack and spends the bits on video

Fixed

  • Streams are mapped explicitly, so cover art or extra tracks cannot be picked by mistake
  • Mono audio stays mono instead of being silently upmixed to stereo
  • --out is rejected for batches instead of overwriting the same file

Install

npx halfsize video.mp4 --to 25mb
npx halfsize video.mp4 --for discord

halfsize 0.1.3

Choose a tag to compare

@YKLovePython YKLovePython released this 03 Nov 17:50

Two-pass encoding now reports honest progress, and the local app takes a custom port.

Changes

  • The progress bar covers both encoding passes and shows pass 1/2 / 第 1/2 遍
  • New --port <n> flag for halfsize --web (default 4174)
  • Pass logs are cleaned up even when an encode fails

Install

npx halfsize video.mp4 --to 25mb

halfsize 0.1.2

Choose a tag to compare

@YKLovePython YKLovePython released this 03 Nov 17:43

Fit any video into any size limit, locally, and prove the quality survived.

What it does

  • Exact target size via two-pass ABR, with a resolution ladder that protects perceived quality
  • Measures SSIM on three samples and VMAF at the midpoint, then prints a plain-language verdict
  • Local web app with drag and drop, presets for 25/10/20/5 MB, and a share card
  • Zero uploads, zero accounts, zero telemetry

Fixes in this release

  • Force CFR so two-pass encodes of Matroska/VFR sources stay on target
  • --version no longer falls through to the help screen
  • Warn when an HDR source would lose its color
  • Always emit MP4 from the CLI, even for MKV/AVI sources

Install

npx halfsize video.mp4 --to 25mb