A tiny, Expo Modules–based library that bundles together a few media-related helpers:
- 🎬 Video → Audio extractor – extract the audio track from a local video file on-device (iOS for now)
- 🖼️ Video → Thumbnails – generate one or many thumbnail images from a local video file (iOS for now)
# then install with npm
npm install @understudios/react-native-mediapack
# or with Yarn
yarn add @understudios/react-native-mediapack
# or with pnpm
pnpm add @understudios/react-native-mediapackBecause the module is written with the Expo Modules API, no extra native steps are required – it is autolinked on iOS/Android and works out-of-the-box with bare React-Native and managed Expo projects.
import React from 'react';
import { Button, View } from 'react-native';
import {
Video,
} from '@understudios/react-native-mediapack';
export default function Example() {
const extract = async () => {
try {
// Supports plain file paths or "file://" URIs
const { outputUri } = await new Video().extractAudio('/path/to/video.mp4');
console.log('Audio saved at →', outputUri);
} catch (err: any) {
if (err?.code === 'ERR_FILE_NOT_FOUND') {
console.warn('Given video file does not exist');
} else {
console.error(err);
}
}
};
return (
<View style={{ flex: 1, padding: 24 }}>
<Button title="Extract audio" onPress={extract} />
</View>
);
}Extract the audio track from a local video file.
const { outputUri } = await new Video().extractAudio('/path/to/video.mp4');Returns Promise<{ outputUri: string }> – the temporary path to the extracted m4a file.
| code | message | when |
|---|---|---|
ERR_FILE_NOT_FOUND |
"No file exists at given path" | The given file path/URI does not exist |
ERR_EXPORT_SESSION |
"Failed to create export session" | AVFoundation export session could not be set up |
ERR_EXPORT_FAILED |
AVFoundation error | Export failed |
ERR_EXPORT_CANCELLED |
"Export cancelled" | User/system cancelled the export |
ERR_UNKNOWN |
"Unknown export error" | Fallback for any other case |
Currently implemented on iOS only. PRs for Android are welcome! ✌️
Generate thumbnail images from a local video file.
// generateThumbnail(uri, timestampMs, quality)
// - timestampMs: timestamp in milliseconds (1500 = 1.5s)
// - quality: JPEG quality between 0 and 1 (0.8 = 80%)
const { outputUri } = await new Video().generateThumbnail('/path/to/video.mp4', 1500, 0.8);
// Multiple thumbnails (same order as input timestamps)
const { outputUris } = await new Video().generateThumbnails('/path/to/video.mp4', [0, 1000, 2500], 0.8);Returns
generateThumbnail(...):Promise<{ outputUri: string }>– the temporary path to the generatedjpgthumbnail.generateThumbnails(...):Promise<{ outputUris: string[] }>– temporary paths to the generatedjpgthumbnails (same order as input).
| code | message | when |
|---|---|---|
ERR_FILE_NOT_FOUND |
"No file exists at given path" | The given file path/URI does not exist |
ERR_INVALID_TIMESTAMP |
Timestamp must be a finite number / must be >= 0 | Invalid timestamp input |
ERR_INVALID_QUALITY |
"Quality must be between 0 and 1" | Invalid quality input |
ERR_THUMBNAIL_FAILED |
AVFoundation error (or "Failed to generate thumbnail") | Single thumbnail generation failed |
ERR_THUMBNAIL_ENCODE_FAILED |
"Failed to encode thumbnail image" | Failed to encode/write the thumbnail |
ERR_THUMBNAILS_FAILED |
AVFoundation error (or "Failed to generate thumbnails") | Batch thumbnail generation failed |
ERR_UNSUPPORTED_IOS_VERSION |
"Generating thumbnails requires iOS 16.0+" | Called on an unsupported iOS version |
Implemented on iOS only (requires iOS 16+), using
AVAssetImageGenerator.image(at:)andAVAssetImageGenerator.images(for:).
- Fork / clone the repo
npm installin both root and theexampledirectory- Run the example –
cd example && npm run ios/npm run android - Make your changes and submit a PR 🚀
Please make sure to run npm run lint and npm run test (if applicable) before opening a pull request.
MIT © 2025 Jan Jiráň / Under Studios