@louiscapelle/react-native-video-editing
v1.0.2
Published
A React Native module for mixing audio with video, perfect for adding background music to videos while preserving original audio. Works on iOS and Android. Built with Expo modules.
Maintainers
Readme
react-native-video-editing
A powerful React Native module for mixing audio with video. Perfect for adding background music to videos while preserving the original audio track. Built with Expo modules for seamless integration.
Features
- 🎵 Mix audio with video - Add background music while keeping original audio
- 📥 Remote audio download - Automatically downloads audio from URLs
- ⏱️ Smart audio trimming - Automatically trims audio to match video duration
- 🎬 High-quality output - Exports mixed videos in MP4 format
- 🧹 Auto cleanup - Automatically removes temporary files
- 🔄 Cross-platform - Currently supports iOS (Android coming soon)
- 📦 Expo compatible - Built with Expo modules for easy autolinking
Installation
For Expo managed projects
npx expo install @louiscapelle/react-native-video-editingFor bare React Native projects
npm install @louiscapelle/react-native-video-editing
# or
yarn add @louiscapelle/react-native-video-editingThen run:
npx pod-installUsage
import ReactNativeVideoEditing from '@louiscapelle/react-native-video-editing';
import * as ImagePicker from 'expo-image-picker';
// Pick a video
const pickVideo = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['videos'],
allowsEditing: false,
quality: 1,
});
if (!result.canceled && result.assets[0]) {
return result.assets[0].uri;
}
};
// Mix video with audio
const mixVideo = async () => {
try {
const videoUri = await pickVideo();
const audioUri = 'https://example.com/audio.mp3';
const result = await ReactNativeVideoEditing.mixVideoWithAudio(
videoUri,
audioUri,
'my-mixed-video.mp4' // optional custom filename
);
console.log('Success!', result.outputPath);
// Output: /path/to/documents/my-mixed-video.mp4
} catch (error) {
console.error('Failed to mix video:', error);
}
};API Reference
mixVideoWithAudio(videoUri, audioUri, outputFileName?)
Mixes audio with a video file while preserving the original video audio.
Parameters:
videoUri(string, required): Local file URI of the video (e.g.,file:///path/to/video.mp4)audioUri(string, required): URL or local file URI of the audio (supports remote URLs likehttps://example.com/audio.mp3)outputFileName(string, optional): Custom filename for the output video (defaults tomixed_video_[timestamp].mp4)
Returns:
Promise that resolves to:
{
success: boolean;
outputPath: string; // Absolute path to the mixed video file
}Behavior:
- Downloads remote audio files automatically
- Mixes the new audio with the original video audio (both tracks are audible)
- Trims audio to match video duration if audio is longer
- Exports as MP4 format with highest quality settings
- Automatically cleans up downloaded audio files
- Saves output to the device's documents directory
Example:
const result = await ReactNativeVideoEditing.mixVideoWithAudio(
'file:///var/mobile/Containers/Data/Application/.../video.mov',
'https://example.com/background-music.mp3',
'final-video'
);
console.log(result);
// {
// success: true,
// outputPath: '/var/mobile/Containers/Data/Application/.../Documents/final-video.mp4'
// }Error Handling
The module throws errors with descriptive messages. Always wrap calls in try-catch blocks:
try {
const result = await ReactNativeVideoEditing.mixVideoWithAudio(
videoUri,
audioUri
);
} catch (error) {
if (error.message.includes('VIDEO_MIXING_ERROR')) {
// Handle mixing errors
console.error('Failed to mix video:', error.message);
}
}Common error codes:
Invalid audio URL- The audio URL is malformedFailed to download audio file- Network error or invalid remote audio URLRemote video URLs are not supported- Video must be a local fileVideo file has no video track- Invalid or corrupted video fileAudio file has no audio track- Invalid or corrupted audio fileExport failed- Video export process failed
Platform Support
| Platform | Status | |----------|--------| | iOS | ✅ Fully Supported | | Android | ✅ Fully Supported | | Web | ❌ Not supported |
Requirements
- iOS: iOS 13.0 or later
- Android: API level 24 (Android 7.0) or later
- React Native: 0.70.0 or later
- Expo SDK: 47 or later
Permissions
iOS
The module requires access to the photo library to read videos. Add the following to your Info.plist:
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library to select videos for editing</string>Or if using Expo, add to your app.json:
{
"expo": {
"ios": {
"infoPlist": {
"NSPhotoLibraryUsageDescription": "We need access to your photo library to select videos for editing"
}
}
}
}Android
The module requires READ_EXTERNAL_STORAGE permission to access videos. Add to your AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />For Android 13+ (API 33+), also add:
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />Or if using Expo, add to your app.json:
{
"expo": {
"android": {
"permissions": [
"READ_EXTERNAL_STORAGE",
"READ_MEDIA_VIDEO",
"READ_MEDIA_AUDIO",
"INTERNET"
]
}
}
}Note: The module automatically requests runtime permissions when using expo-image-picker.
Example App
Check out the /example folder in this repository for a complete working example with:
- Video picker using expo-image-picker
- Audio URL input
- Loading states
- Error handling
- Output path display
To run the example:
cd example
npm install
# For iOS
npx expo run:ios
# For Android
npx expo run:androidPublishing to NPM
If you want to publish your own fork:
- Update
package.jsonwith your details - Build the module:
npm run build - Login to NPM:
npm login - Publish:
npm publish
How Autolinking Works
This module uses Expo autolinking, which means:
- ✅ No manual linking required
- ✅ Automatically builds native code when running
expo prebuild - ✅ Works seamlessly with
expo run:iosandexpo run:android - ✅ Compatible with EAS Build
- ✅ Native modules automatically discovered and linked
When you add this package to your project:
npx expo install @louiscapelle/react-native-video-editingThen run your app:
npx expo run:ios # Automatically compiles the Swift native moduleNo additional configuration needed!
Technical Details
iOS Implementation
The iOS implementation uses:
- AVFoundation framework for video/audio processing
- AVMutableComposition for combining video and audio tracks
- AVAssetExportSession for high-quality MP4 export
- URLSession for downloading remote audio files
- Expo Modules API for seamless React Native integration
Android Implementation
The Android implementation uses:
- MediaExtractor for extracting video and audio tracks
- MediaCodec for encoding/decoding audio streams
- MediaMuxer for combining video and audio into MP4
- URLConnection for downloading remote audio files
- Expo Modules API for seamless React Native integration
Both platforms preserve the original video audio and add the new audio track, creating a true mix rather than a replacement.
Note: The Android implementation uses a simplified audio mixing approach. For production apps requiring advanced audio mixing (volume control, effects, etc.), consider using FFmpeg-based solutions.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT
Author
Louis CAPELLE - @LouisCapelle
Support
For issues and questions, please open an issue on GitHub.
