New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

react-native-video-trim

Package Overview
Dependencies
Maintainers
1
Versions
82
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-native-video-trim

Video trimmer for your React Native app

latest
Source
npmnpm
Version
7.0.1
Version published
Maintainers
1
Created
Source

Table of Contents

React Native Video Trim

📱 Professional video trimmer for React Native apps

✅ iOS & Android✅ New & Old Architecture✅ Expo Compatible

Overview

A powerful, easy-to-use video and audio trimming library for React Native applications.

✨ Key Features

  • 📹 Video & Audio Support - Trim both video and audio files
  • 🔄 Flip, Rotate & Crop - Built-in video transforms with undo/redo support
  • 🎯 Precise Trimming - Optional frame-accurate cuts via hardware-accelerated re-encoding
  • 🌐 Local & Remote Files - Support for local storage and HTTPS URLs
  • 💾 Multiple Save Options - Photos, Documents, or Share to other apps
  • ✅ File Validation - Built-in validation for media files
  • 🗂️ File Management - List, clean up, and delete specific files
  • 🔄 Universal Architecture - Works with both New and Old React Native architectures

🎛️ Core Capabilities

FeatureDescription
TrimmingVideo/audio trimming with visual timeline controls
TransformsHorizontal flip, 90° rotation, and freeform crop with undo/redo
Precise TrimmingFrame-accurate cuts using hardware re-encoding (opt-in)
ValidationCheck if files are valid video/audio before processing
Save OptionsPhotos, Documents, Share sheet integration
File ManagementComplete file lifecycle management
CustomizationExtensive UI and behavior customization

Installation

npm install react-native-video-trim
# or
yarn add react-native-video-trim

Platform Setup

📱 iOS Setup (React Native CLI)
npx pod-install ios

Permissions Required:

  • For saving to Photos: Add NSPhotoLibraryUsageDescription to Info.plist
🤖 Android Setup (React Native CLI)

For New Architecture:

cd android && ./gradlew generateCodegenArtifactsFromSchema

Permissions Required:

  • For saving to Photos: Add to AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

For Share Sheet functionality, add to AndroidManifest.xml:

<application>
  <!-- your other configs -->
  
  <provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
      android:name="android.support.FILE_PROVIDER_PATHS"
      android:resource="@xml/file_paths" />
  </provider>
</application>

Create android/app/src/main/res/xml/file_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
  <files-path name="internal_files" path="." />
  <external-path name="external_files" path="." />
</paths>
🔧 Expo Setup
npx expo prebuild

Then rebuild your app. Note: Expo Go may not work due to native dependencies - use development builds or expo run:ios/expo run:android.

Quick Start

Get up and running in 3 simple steps:

import { showEditor } from 'react-native-video-trim';

// 1. Basic usage - open video editor
showEditor(videoUrl);

// 2. With duration limit
showEditor(videoUrl, {
  maxDuration: 20,
});

// 3. With save options
showEditor(videoUrl, {
  maxDuration: 30,
  saveToPhoto: true,
  openShareSheetOnFinish: true,
});

Complete Example with File Picker

import { showEditor } from 'react-native-video-trim';
import { launchImageLibrary } from 'react-native-image-picker';

const trimVideo = () => {
  // Pick a video
  launchImageLibrary({ mediaType: 'video' }, (response) => {
    if (response.assets && response.assets[0]) {
      const videoUri = response.assets[0].uri;
      
      // Open editor
      showEditor(videoUri, {
        maxDuration: 60, // 60 seconds max
        saveToPhoto: true,
      });
    }
  });
};

💡 More Examples: Check the example folder for complete implementation details with event listeners for both New and Old architectures.

API Reference

showEditor()

Opens the video trimmer interface.

showEditor(videoPath: string, config?: EditorConfig): void

Parameters:

  • videoPath (string): Path to video file (local or remote HTTPS URL)
  • config (EditorConfig, optional): Configuration options (see Configuration Options)

Example:

showEditor('/path/to/video.mp4', {
  maxDuration: 30,
  saveToPhoto: true,
});

trim()

Programmatically trim a video without showing the UI.

trim(url: string, options: TrimOptions): Promise<TrimResult>

Returns: Promise resolving to the TrimResult interface

Example:

const outputPath = await trim('/path/to/video.mp4', {
  startTime: 5000,  // 5 seconds
  endTime: 25000,   // 25 seconds
});

File Management

MethodDescriptionReturns
isValidFile(videoPath)Check if file is valid video/audioPromise<boolean>
listFiles()List all generated output filesPromise<string[]>
cleanFiles()Delete all generated filesPromise<number>
deleteFile(filePath)Delete specific filePromise<boolean>
closeEditor()Close the editor interfacevoid

Examples:

// Validate file before processing
const isValid = await isValidFile('/path/to/video.mp4');
if (!isValid) {
  console.log('Invalid video file');
  return;
}

// Clean up generated files
const deletedCount = await cleanFiles();
console.log(`Deleted ${deletedCount} files`);

Configuration Options

All configuration options are optional. Here are the most commonly used ones:

Basic Options

OptionTypeDefaultDescription
type'video' | 'audio''video'Media type to trim
outputExtstring'mp4'Output file extension
maxDurationnumbervideo durationMaximum duration in milliseconds
minDurationnumber1000Minimum duration in milliseconds
autoplaybooleanfalseAuto-play media on load
jumpToPositionOnLoadnumber-Initial position in milliseconds

Save & Share Options

OptionTypeDefaultDescription
saveToPhotobooleanfalseSave to photo gallery (requires permissions)
openDocumentsOnFinishbooleanfalseOpen document picker when done
openShareSheetOnFinishbooleanfalseOpen share sheet when done
removeAfterSavedToPhotobooleanfalseDelete file after saving to photos
removeAfterFailedToSavePhotobooleanfalseDelete file if saving to photos fails
removeAfterSavedToDocumentsbooleanfalseDelete file after saving to documents
removeAfterFailedToSaveDocumentsbooleanfalseDelete file if saving to documents fails
removeAfterSharedbooleanfalseDelete file after sharing (iOS only)
removeAfterFailedToSharebooleanfalseDelete file if sharing fails (iOS only)

UI Customization

OptionTypeDefaultDescription
cancelButtonTextstring"Cancel"Cancel button text
saveButtonTextstring"Save"Save button text
trimmingTextstring"Trimming video..."Progress dialog text
headerTextstring-Header text
headerTextSizenumber16Header text size
headerTextColorstring-Header text color
trimmerColorstring-Trimmer bar color
handleIconColorstring-Trimmer left/right handles color
fullScreenModalIOSbooleanfalseUse fullscreen modal on iOS

Dialog Options

Cancel Dialog
OptionTypeDefaultDescription
enableCancelDialogbooleantrueShow confirmation dialog on cancel
cancelDialogTitlestring"Warning!"Cancel dialog title
cancelDialogMessagestring"Are you sure want to cancel?"Cancel dialog message
cancelDialogCancelTextstring"Close"Cancel dialog cancel button text
cancelDialogConfirmTextstring"Proceed"Cancel dialog confirm button text
Save Dialog
OptionTypeDefaultDescription
enableSaveDialogbooleantrueShow confirmation dialog on save
saveDialogTitlestring"Confirmation!"Save dialog title
saveDialogMessagestring"Are you sure want to save?"Save dialog message
saveDialogCancelTextstring"Close"Save dialog cancel button text
saveDialogConfirmTextstring"Proceed"Save dialog confirm button text
Trimming Cancel Dialog
OptionTypeDefaultDescription
enableCancelTrimmingbooleantrueEnable cancel during trimming
cancelTrimmingButtonTextstring"Cancel"Cancel trimming button text
enableCancelTrimmingDialogbooleantrueShow cancel trimming confirmation
cancelTrimmingDialogTitlestring"Warning!"Cancel trimming dialog title
cancelTrimmingDialogMessagestring"Are you sure want to cancel trimming?"Cancel trimming dialog message
cancelTrimmingDialogCancelTextstring"Close"Cancel trimming dialog cancel button
cancelTrimmingDialogConfirmTextstring"Proceed"Cancel trimming dialog confirm button
Error Dialog
OptionTypeDefaultDescription
alertOnFailToLoadbooleantrueShow alert dialog on load failure
alertOnFailTitlestring"Error"Error dialog title
alertOnFailMessagestring"Fail to load media..."Error dialog message
alertOnFailCloseTextstring"Close"Error dialog close button text

Advanced Options

OptionTypeDefaultDescription
enableHapticFeedbackbooleantrueEnable haptic feedback
closeWhenFinishbooleantrueClose editor when done
enablePreciseTrimmingbooleanfalseRe-encode for frame-accurate cuts (slower, see Precise Frame Trimming)
changeStatusBarColorOnOpenbooleanfalseChange status bar color (Android only)
zoomOnWaitingDurationnumber5000Duration for zoom-on-waiting feature in milliseconds (default: 5000)

Example Configuration

showEditor(videoPath, {
  // Basic settings
  maxDuration: 60000,
  minDuration: 3000,
  
  // Save options
  saveToPhoto: true,
  openShareSheetOnFinish: true,
  removeAfterSavedToPhoto: true,
  
  // UI customization
  headerText: "Trim Your Video",
  cancelButtonText: "Back",
  saveButtonText: "Done",
  trimmerColor: "#007AFF",
  
  // Behavior
  autoplay: true,
  enableCancelTrimming: true,
});

Platform Setup

Android SDK Customization

You can override SDK versions in android/build.gradle:

buildscript {
    ext {
        VideoTrim_kotlinVersion = '2.0.21'
        VideoTrim_minSdkVersion = 24
        VideoTrim_targetSdkVersion = 34
        VideoTrim_compileSdkVersion = 35
        VideoTrim_ndkVersion = '27.1.12297006'
    }
}

Advanced Features

Audio Trimming

For audio-only trimming, specify the media type and output format:

showEditor(audioUrl, {
  type: 'audio',        // Enable audio mode
  outputExt: 'wav',     // Output format (mp3, wav, m4a, etc.)
  maxDuration: 30000,   // 30 seconds max
});

Remote Files (HTTPS)

To trim remote files, you need the HTTPS-enabled version of FFmpeg:

Android:

// android/build.gradle
buildscript {
    ext {
        VideoTrim_ffmpeg_package = 'https'
        // Optional: VideoTrim_ffmpeg_version = '6.0.1'
    }
}

iOS:

FFMPEGKIT_PACKAGE=https FFMPEG_KIT_PACKAGE_VERSION=6.0 pod install

Usage:

showEditor('https://example.com/video.mp4', {
  maxDuration: 60000,
});

Video Transforms (Flip, Rotate, Crop)

The editor includes built-in transform controls — horizontal flip, 90° left rotation, and freeform crop — with full undo/redo support. These appear as toolbar buttons in the editor UI on both iOS and Android.

When any transform is applied, FFmpeg automatically re-encodes the video using the platform's hardware encoder (h264_videotoolbox on iOS, h264_mediacodec on Android) at the source bitrate to preserve quality. No additional configuration is needed.

Precise Frame Trimming

By default, trimming uses FFmpeg's stream copy (-c copy), which is very fast but can only cut at keyframes. The actual start/end points may drift by several seconds from what the user selected.

Enable enablePreciseTrimming for frame-accurate cuts:

// Editor mode
showEditor(videoUrl, {
  enablePreciseTrimming: true,
});

// Headless mode
const result = await trim(videoUrl, {
  startTime: 5000,
  endTime: 15000,
  enablePreciseTrimming: true,
});
enablePreciseTrimming: false (default)enablePreciseTrimming: true
SpeedVery fast (stream copy)Slower (hardware re-encode)
AccuracyKeyframe-aligned (may drift 1-5s)Frame-accurate
QualityLossless (original bitstream)Near-lossless (matched bitrate)

Note: When transforms (flip/rotate/crop) are applied, re-encoding already happens regardless of this flag, so precise trimming comes for free in that case.

Trimming Progress & Cancellation

Users can cancel trimming while in progress:

showEditor(videoUrl, {
  enableCancelTrimming: true,
  cancelTrimmingButtonText: "Stop",
  trimmingText: "Processing video...",
});

Error Handling

Handle loading errors gracefully:

showEditor(videoUrl, {
  alertOnFailToLoad: true,
  alertOnFailTitle: "Oops!",
  alertOnFailMessage: "Cannot load this video file",
  alertOnFailCloseText: "OK",
});

Examples

Complete Implementation (New Architecture)

import React, { useEffect, useRef } from 'react';
import { TouchableOpacity, Text, View } from 'react-native';
import { showEditor, isValidFile, type Spec } from 'react-native-video-trim';
import { launchImageLibrary } from 'react-native-image-picker';

export default function VideoTrimmer() {
  const listeners = useRef({});

  useEffect(() => {
    // Set up event listeners
    listeners.current.onFinishTrimming = (NativeVideoTrim as Spec)
      .onFinishTrimming(({ outputPath, startTime, endTime, duration }) => {
        console.log('Trimming completed:', {
          outputPath,
          startTime,
          endTime,
          duration
        });
      });

    listeners.current.onError = (NativeVideoTrim as Spec)
      .onError(({ message, errorCode }) => {
        console.error('Trimming error:', message, errorCode);
      });

    return () => {
      // Cleanup listeners
      Object.values(listeners.current).forEach(listener => 
        listener?.remove()
      );
    };
  }, []);

  const selectAndTrimVideo = async () => {
    const result = await launchImageLibrary({
      mediaType: 'video',
      quality: 1,
    });

    if (result.assets?.[0]?.uri) {
      const videoUri = result.assets[0].uri;
      
      // Validate file first
      const isValid = await isValidFile(videoUri);
      if (!isValid) {
        console.log('Invalid video file');
        return;
      }

      // Open editor
      showEditor(videoUri, {
        maxDuration: 60000,        // 1 minute max
        saveToPhoto: true,         // Save to gallery
        openShareSheetOnFinish: true,
        headerText: "Trim Video",
        trimmerColor: "#007AFF",
      });
    }
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <TouchableOpacity 
        onPress={selectAndTrimVideo}
        style={{ 
          backgroundColor: '#007AFF', 
          padding: 15, 
          borderRadius: 8 
        }}
      >
        <Text style={{ color: 'white', fontSize: 16 }}>
          Select & Trim Video
        </Text>
      </TouchableOpacity>
    </View>
  );
}

Old Architecture Implementation

import React, { useEffect } from 'react';
import { NativeEventEmitter, NativeModules } from 'react-native';
import { showEditor } from 'react-native-video-trim';

export default function VideoTrimmer() {
  useEffect(() => {
    const eventEmitter = new NativeEventEmitter(NativeModules.VideoTrim);
    
    const subscription = eventEmitter.addListener('VideoTrim', (event) => {
      switch (event.name) {
        case 'onFinishTrimming':
          console.log('Video trimmed:', event.outputPath);
          break;
        case 'onError':
          console.error('Trimming failed:', event.message);
          break;
        // Handle other events...
      }
    });

    return () => subscription.remove();
  }, []);

  // Rest of implementation...
}

Troubleshooting

Common Issues

Android Build Errors:

  • Ensure file_paths.xml exists for share functionality
  • Check SDK versions match your project requirements
  • Verify permissions in AndroidManifest.xml

iOS Build Errors:

  • Run pod install after installation
  • Check Info.plist permissions for photo access
  • Use development builds with Expo (not Expo Go)

Runtime Issues:

  • Validate files with isValidFile() before processing
  • Use HTTPS version for remote files
  • Check network connectivity for remote files
  • Ensure proper permissions for save operations

Performance Tips

  • Use trim() for batch processing without UI
  • Clean up generated files regularly with cleanFiles()
  • Consider file compression for large videos

Credits

Keywords

react-native

FAQs

Package last updated on 12 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts