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

react-native-video-lab

v0.2.0

Published

React Native Video Lab

Readme

react-native-video-lab

Small, fast, native helpers for common video edits in React Native:

✂️ Trim a clip by time range

➕ Merge multiple clips into one

🔊 Add/replace audio track on a video

🎨 Apply filters (Sepia, Monochrome, Invert)

Works with file URLs (file:///...) and Android content:// URIs.

Video Lab Example

Installation

npm install react-native-video-lab
# iOS
cd ios && pod install && cd ..

Quick start

import {
  trim,
  merge,
  addAudio,
  applyFilter,
  type Filter,
} from 'react-native-video-lab';

// TRIM (seconds)
const out1 = await trim(videoUri, /* start */ 1.0, /* end */ 9.5);

// MERGE
const out2 = await merge([videoUri1, videoUri2, videoUri3]);

// ADD / REPLACE AUDIO
// mode: 'replace' (replace original) | 'mix' (keep original + overlay) — see notes below
const out3 = await addAudio(videoUri, audioUri, 'replace');

// FILTER
const filter: Filter = 'sepia'; // 'sepia' | 'mono' | 'invert'
const out4 = await applyFilter(videoUri, filter);

All methods return a local file URI string (e.g. file:///.../xxxx.mp4) you can pass to <Video /> players or upload.

API

trim(path: string, startSec: number, endSec: number): Promise<string>

Cuts the segment [startSec, endSec] from path and returns a new mp4.

merge(paths: string[]): Promise<string>

Concatenates clips in order. Video and audio tracks are appended sequentially.

Tip: For mixed orientations/codecs, re-encode clips before merging to keep playback solid across devices.

addAudio(videoPath: string, audioPath: string, mode: 'replace' | 'mix'): Promise<string>

  • replace: replace the video's original audio with the provided audio (trimmed to video duration).
  • mix: keep original audio and mix the new audio underneath (if mixing isn't available on your platform, it will fall back to replace).

Audio formats: Prefer AAC (.m4a) for maximum device compatibility.

applyFilter(path: string, filter: Filter): Promise<string>

Applies a color effect and re-encodes the video.

export type Filter = 'sepia' | 'mono' | 'invert';
  • iOS: Core Image / AVFoundation
  • Android: MediaCodec + OpenGL (OES texture) pipeline

Usage examples

With a picker

You can use any picker that returns a URI. For example:

import { launchImageLibrary } from 'react-native-image-picker';
import { trim, applyFilter } from 'react-native-video-lab';

const pickVideo = async () => {
  const res = await launchImageLibrary({ mediaType: 'video' });
  const uri = res.assets?.[0]?.uri;
  if (!uri) return;

  const trimmed = await trim(uri, 0, 5);
  const filtered = await applyFilter(trimmed, 'mono');
  // use `filtered` with your player
};

With Android content:// URIs

You can pass the content:// string directly; the module resolves it internally. No need to copy to a temp file yourself.

Platform notes

iOS

Add descriptions to your Info.plist if you access the Photo Library:

  • NSPhotoLibraryUsageDescription

AVFoundation handles rotation metadata—playback respects the original orientation.

Android

Permissions (Android 13+ / 33+):

<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

(Android 12 and below):

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Recommended codecs:

  • Video output: H.264/AVC in MP4 container
  • Audio input: AAC (audio/mp4a-latm). MP3 may work but AAC is safest.

Even dimensions: some hardware encoders require even width x height. The module enforces this; odd sizes are rounded down by 1px if needed.

DocumentsUI / Pickers: If you see ActivityNotFoundException when picking audio, install a file manager/Docs app or use a maintained picker package.

Troubleshooting

IllegalArgumentException during filter/encode

Ensure the device has an H.264 encoder and your input dimensions are > 0 and even. Using extremely large frames can cause hardware encoders to reject configuration.

Audio added but output duration equals audio length

The module clamps audio to video duration. If you still see mismatches, confirm the input videoPath has a valid duration and isn't a stream with zero durationUs.

Malformed sample table (stbl) when playing the output

This usually means the input was malformed or a prior tool wrote a broken MP4. Re-encode the input first, then run the edit.

Can't open content://...

Make sure the URI is valid and accessible (not revoked). If you obtained the URI from a picker, don't persist it across app restarts without taking persistable permissions.

Roadmap

  • Volume controls & fade in/out for addAudio('mix')
  • More filters (brightness/contrast, LUTs)
  • Text & image overlays
  • Transcode helpers (resize, bitrate, fps)

Contributing

PRs that add small, well-tested native helpers are very welcome!

License

MIT


Made with create-react-native-library