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

rns-mediapicker

v3.0.0

Published

High-performance React Native module for picking media on Android and iOS.

Readme

🎵 / 🖼️ / 🎥 rns-mediapicker

A high-performance native media picker for React Native and Expo.
Supports audio, image, video, .adp project files from camera or library, automatic JPEG compression, EXIF-safe dimensions, and iterative quality targeting.


🚀 Installation

Choose any method:

yarn add rns-mediapicker
npm install rns-mediapicker
npx expo install rns-mediapicker

⚙️ Expo Configuration

Add the plugin to your app.json or app.config.js.
This automatically configures:

  • iOS permissions (Info.plist)
  • iOS .adp custom UTType declaration
  • Android intent queries
  • Android FileProvider
{
  "expo": {
    "plugins": ["rns-mediapicker"]
  }
}

🧑‍💻 Usage

Pick from library (image or video)

import MediaPicker from 'rns-mediapicker';

const result = await MediaPicker.pick(
  false,    // useCamera
  'both',   // mediaType
  'back',   // env
  0         // targetKB — 0 means no compression
);

console.log(result.uri);    // file:///...
console.log(result.type);   // 'image' | 'video' | 'audio' | 'adp'
console.log(result.width);  // number (0 for audio/adp)
console.log(result.height); // number (0 for audio/adp)
console.log(result.size);   // KB (images only — field is absent for video/audio/adp)
console.log(result.isVideo);
console.log(result.isAudio);

Open camera

// Photo with back camera
const result = await MediaPicker.pick(true, 'image', 'back', 0);

// Video with front camera
const result = await MediaPicker.pick(true, 'video', 'front', 0);

Pick audio

const result = await MediaPicker.pick(false, 'audio', 'back', 0);

console.log(result.uri);     // file:///...
console.log(result.type);    // 'audio'
console.log(result.isAudio); // true

Pick with image compression (targetKB)

Compresses the image iteratively until it fits within the target size.
Quality steps down by 10% per iteration (from 100% → minimum 10%).

// Pick an image and compress to max 200KB
const result = await MediaPicker.pick(false, 'image', 'back', 200);

console.log(result.size); // Actual size in KB after compression
console.log(result.uri);  // Compressed JPEG file URI

targetKB = 0 disables compression and returns the full-quality image.


Pick a .adp project file

.adp is a custom Audipella project file format. This opens the file browser
filtered to .adp files only (iOS) or a general file browser (Android).

const result = await MediaPicker.pick(false, 'adp', 'back', 0);

console.log(result.uri);  // file:///...path/to/file.adp
console.log(result.type); // 'adp'

Error handling

try {
  const result = await MediaPicker.pick(false, 'image', 'back', 0);
} catch (error) {
  switch (error.code) {
    case 'E_CANCELLED':
      console.log('User cancelled');
      break;
    case 'E_PERMISSION_DENIED':
      console.log('Permission denied');
      break;
    case 'E_CAMERA_UNAVAILABLE':
      console.log('Camera not available on this device');
      break;
    case 'E_PROCESS':
      console.log('Failed to process media:', error.message);
      break;
    default:
      console.error('Picker error:', error.message);
  }
}

🧩 API Reference

pick(useCamera, mediaType, env, targetKB)

| Parameter | Type | Default | Description | |-------------|----------|------------|-------------| | useCamera | boolean | — | true opens the camera, false opens the file/media picker | | mediaType | string | — | 'image', 'video', 'both', 'audio', or 'adp' | | env | string | 'back' | 'front' or 'back' — camera only, best-effort on Android | | targetKB | number | 0 | Max image size in KB. 0 = no compression. Images only |

All four parameters must be passed. Use 0 for targetKB to disable compression, and 'back' for env when camera direction is not relevant.


📦 Response Object

{
  uri: string;       // Local file URI (file://...)
  width: number;     // Width in pixels (0 for audio and adp)
  height: number;    // Height in pixels (0 for audio and adp)
  size?: number;     // File size in KB — present for images only, absent for video/audio/adp
  type: 'image' | 'video' | 'audio' | 'adp';
  isVideo: boolean;
  isAudio: boolean;
}

🗂️ Media Type Reference

| mediaType | Opens | Returns | |-------------|-------|---------| | 'image' | Photo library / camera | type: 'image' | | 'video' | Video library / camera | type: 'video' | | 'both' | Photo + video library / camera | type: 'image' or 'video' | | 'audio' | File browser (audio files) | type: 'audio' | | 'adp' | File browser (.adp files on iOS; all files on Android) | type: 'adp' |


🚨 Error Codes

| Code | Description | |------|-------------| | E_CANCELLED | User dismissed the picker or cancelled | | E_PERMISSION_DENIED | Camera or storage permission denied | | E_NOT_PERMISSION_AWARE | Android activity does not implement PermissionAwareActivity | | E_CAMERA_UNAVAILABLE | Device has no camera (iOS) | | E_NO_ACTIVITY | Android activity not found | | E_NO_URI | No media URI returned from picker | | E_PROCESS | Failed to decode, compress, or copy the file | | E_AUDIO_COPY | Failed to copy audio/adp file to temp location | | E_VIDEO_COPY | Failed to copy video file to temp location | | E_IMAGE_WRITE | Failed to encode or write image to disk | | E_LOAD | Failed to load media from PHPicker (iOS) |


✨ Features

  • 🖼️ Image / 🎥 Video / 🎵 Audio / 📁 .adp project file support
  • 📷 Camera and 📁 Library selection
  • 🎬 Camera video capture (Android & iOS)
  • 🗜️ Iterative JPEG compression with targetKB target
  • 🔄 EXIF-safe rotation and accurate dimensions
  • 📂 Scoped-storage safe temporary files
  • 🤖 Android 11+ intent queries handled automatically
  • 🔐 Android FileProvider preconfigured
  • 🍎 iOS swipe-to-dismiss cancellation handling
  • 🍎 iOS .adp UTType auto-registered via Expo plugin
  • 🧹 Clean promise lifecycle (no leaks)

📝 Notes

  • All returned files are copied into the app's temporary cache directory
  • Audio files preserve their original encoding and extension
  • .adp files are copied as-is — no processing applied
  • targetKB compression only applies to images, not video or audio
  • The size field is only present in the response for images; it is absent (not 0) for video, audio, and adp results
  • Front camera selection is best-effort on Android
  • On Android, .adp picker opens a general file browser since Android has no built-in MIME type for .adp; the file is identified by its extension after selection
  • No external native dependencies required

📄 License

MIT