npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rn-av-binder

v1.0.1

Published

On-device image + audio → MP4 composition for React Native. AVFoundation (iOS) and MediaCodec/MediaMuxer (Android). New Architecture compatible.

Downloads

292

Readme

rn-av-binder

On-device image + audio → MP4 composition for React Native — no FFmpeg, no third-party media libraries. Uses AVFoundation on iOS and MediaCodec / MediaMuxer / MediaExtractor on Android. Built as an Expo Module for the New Architecture (Fabric + JSI).

Motivation

ffmpeg-kit was retired in April 2025, leaving React Native apps without a maintained, fully on-device way to turn a still image plus an audio track into a playable video. rn-av-binder is the pure-native replacement for the common "audiogram" use case: it encodes a single static image as a 2-frame H.264 video and muxes the original audio in unmodified (passthrough, no re-encode), so the output duration matches the source audio and the operation is fast and lossless on the audio side.

Installation

yarn add rn-av-binder
npx expo run:ios   # or eas build

Add the plugin to your app.json, then rebuild the native project:

{
  "expo": {
    "plugins": ["rn-av-binder"]
  }
}

Native linking itself is automatic via Expo Modules autolinking; the plugin entry exists so the package is registered in your config and to allow future native config tweaks.

API

import { createVideo } from "rn-av-binder";

createVideo(options, onProgress?): Promise<CreateVideoResult>;

CreateVideoOptions

| Field | Type | Required | Description | | ----------- | -------- | -------- | ------------------------------------------------------------------ | | imageUri | string | yes | file:// URI to a JPEG or PNG image | | audioUri | string | yes | file:// URI to an AAC, MP3, or M4A audio file | | outputUri | string | no | file:// URI for the MP4. Defaults to <cacheDir>/image_audio_<timestamp>.mp4 |

CreateVideoResult

| Field | Type | Description | | ------------ | -------- | -------------------------------------- | | uri | string | file:// URI of the created MP4 | | durationMs | number | Duration of the output video, in ms |

ProgressEvent

| Field | Type | Description | | ---------- | -------- | ------------------------------------ | | progress | number | Encoding progress from 0.0 to 1.0 |

The optional onProgress callback receives { progress } and fires at 0.0, 0.5, and 1.0.

Usage

import * as ImagePicker from "expo-image-picker";
import * as DocumentPicker from "expo-document-picker";
import { createVideo } from "rn-av-binder";

async function makeVideo() {
  const image = await ImagePicker.launchImageLibraryAsync({ mediaTypes: "Images" });
  const audio = await DocumentPicker.getDocumentAsync({ type: "audio/*" });
  if (image.canceled || audio.canceled) return;

  const result = await createVideo(
    { imageUri: image.assets[0].uri, audioUri: audio.assets[0].uri },
    ({ progress }) => console.log(`${Math.round(progress * 100)}%`),
  );

  console.log(result.uri, `${(result.durationMs / 1000).toFixed(1)}s`);
}

Platform requirements

  • iOS 15.0+
  • Android API 26+ (minSdkVersion 26)
  • Expo SDK 52+
  • React Native 0.76+
  • New Architecture required (newArchEnabled: true)

Running the example app

The repo includes a standalone example under example/ that installs the package via "rn-av-binder": "file:.." — exactly what a consumer does after yarn add.

# from the package root
yarn install
yarn build

cd example
yarn install
npx expo run:ios      # requires Xcode + iOS 15 simulator/device
npx expo run:android  # requires Android Studio + API 26 emulator/device

Pick an image and an audio file, tap Create Video, watch the progress bar, and the encoded MP4 plays inline on completion.

Publishing checklist

  1. yarn build completes with no TypeScript errors; build/index.js and build/index.d.ts exist.
  2. npm pack --dry-run includes build/, ios/, android/, expo-module.config.json, rn-av-binder.podspec, app.plugin.js — and excludes example/.
  3. npm login (authenticate).
  4. npm publish (runs prepareyarn build automatically).

Known limitations

  • Single static image only — no slideshow, no transitions.
  • No video-to-video processing; input must be one image + one audio file.
  • Audio is passed through unchanged; the container must support the source audio codec (MP4 supports AAC/M4A; some exotic codecs may need transcoding, which this library does not do).
  • On the iOS Simulator, camera-roll access can be limited — a physical device may be required for picking images.