New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@bsky.app/video-compressor

Package Overview
Dependencies
Maintainers
4
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bsky.app/video-compressor

Hardware-accelerated video compression for React Native and Expo. iOS + Android use VideoToolbox / MediaCodec; web uses WebCodecs via mediabunny.

latest
Source
npmnpm
Version
0.3.1
Version published
Weekly downloads
9.2K
-27.28%
Maintainers
4
Weekly downloads
 
Created
Source

@bsky.app/video-compressor

Video compression for React Native and Expo across iOS, Android, and web. iOS uses AVAssetReader/AVAssetWriter + VideoToolbox. Android uses MediaCodec + MediaMuxer. Web uses WebCodecs through mediabunny.

Installation

npm install @bsky.app/video-compressor

Usage

import {compress, probe} from '@bsky.app/video-compressor'

const meta = await probe(uri)

const controller = new AbortController()
const result = await compress(
  uri,
  {
    targetBitrate: 3_000_000, // 0 = let the encoder pick
    maxSize: 1920, // long-edge cap in px
    codec: 'auto', // 'auto' | 'h264' | 'hevc'
    frameRateCap: 30,
  },
  {
    onProgress: p => console.log(p), // 0..1
    signal: controller.signal,
  },
)

probe(uri) returns a VideoMetadata object — width, height, duration, bitrate, codec, frame rate, rotation, etc. compress returns the output uri, file size, mimeType, dimensions, duration, and the codec actually used.

Cancellation is wired through AbortSignal. Calling abort() mid-run cancels the underlying native session and rejects the promise with an AbortError.

Platform behavior

PlatformBackend
iOSAVAssetReader/Writer + VideoToolbox
AndroidMediaCodec + MediaMuxer (GL color-space convert)
WebWebCodecs via mediabunny. Falls back avc → hevc → vp9 → vp8 by browser support; container switches MP4 ↔ WebM accordingly.

compress() can also return the input unchanged. Set passthroughGif: false to force-encode GIFs (default skips them), or set passthroughBelowBytes: 25_000_000 to skip files under a size threshold. On web, missing WebCodecs is also a passthrough. The result's passthroughReason tells you which path it took.

Input format support

Covered by the fixture corpus in example/assets/fixtures (see example/scripts/generate-fixtures.sh). Both example apps have a "Run all fixtures" button that runs the full corpus through compress and shows ✅/❌ per fixture, so support claims can be re-verified after any change.

InputiOSAndroidWeb
H.264 MP4 (incl. 4K, portrait)✅✅✅
HEVC MOV✅✅✅ ¹
HEVC HDR (HLG) MOV✅ tone-mapped SDR✅ tone-mapped SDR✅ ¹ tone-mapped SDR
VP9 WebM❌✅✅
H.264 AVI❌❌❌

¹ Needs browser HEVC decode support (Safari; Chrome with hardware decode).

Example app

A small Expo app demonstrating the module — and benchmarking it against react-native-compressor — lives in example/. See example/README.md for run instructions and the optional bench/compare.sh ffprobe-based comparison script. A Vite app exercising the web backend lives in web-example/.

Keywords

react-native

FAQs

Package last updated on 29 Oct 2026

Related posts