{"id":4655,"url":"https://github.com/shahen94/react-native-video-processing","last_synced_at":"2025-05-14T20:08:12.207Z","repository":{"id":38176048,"uuid":"73619890","full_name":"shahen94/react-native-video-processing","owner":"shahen94","description":"Native Video editing/trimming/compressing  :movie_camera: library for React-Native","archived":false,"fork":false,"pushed_at":"2024-04-15T12:44:07.000Z","size":65060,"stargazers_count":1251,"open_issues_count":131,"forks_count":326,"subscribers_count":28,"default_branch":"master","last_synced_at":"2024-10-29T15:34:13.367Z","etag":null,"topics":["android","android-video-editor","ios","ios-video-editor","java","javascript","processing","react","react-native","swift","video","xcode"],"latest_commit_sha":null,"homepage":"https://shahen94.github.io/react-native-video-processing/","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shahen94.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-11-13T14:10:21.000Z","updated_at":"2024-10-28T16:36:27.000Z","dependencies_parsed_at":"2023-02-09T08:46:58.765Z","dependency_job_id":"ad51b434-bf8b-4b0c-babb-8b0cf94f874b","html_url":"https://github.com/shahen94/react-native-video-processing","commit_stats":{"total_commits":204,"total_committers":33,"mean_commits":6.181818181818182,"dds":0.6764705882352942,"last_synced_commit":"0847101c11ace83b375c6d02db1cfa9e345bca2c"},"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahen94%2Freact-native-video-processing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahen94%2Freact-native-video-processing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahen94%2Freact-native-video-processing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahen94%2Freact-native-video-processing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shahen94","download_url":"https://codeload.github.com/shahen94/react-native-video-processing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248717243,"owners_count":21150388,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-video-editor","ios","ios-video-editor","java","javascript","processing","react","react-native","swift","video","xcode"],"created_at":"2024-01-05T20:17:19.215Z","updated_at":"2025-04-13T12:48:05.699Z","avatar_url":"https://github.com/shahen94.png","language":"Objective-C","funding_links":["https://www.buymeacoffee.com/FnENSxi"],"categories":["Components","\u003ca name=\"Image-\u0026-Audio-\u0026-Video-\u0026-Docs:-Native-Modules\"\u003eImage, Audio, Video \u0026 Docs: Native Modules\u003c/a\u003e","动画","Objective-C"],"sub_categories":["Media","多媒体"],"readme":"## react-native-video-processing\n\n [![Build Status](https://travis-ci.org/shahen94/react-native-video-processing.svg?branch=master)](https://travis-ci.org/shahen94/react-native-video-processing) [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=plastic)](https://github.com/semantic-release/semantic-release) [![npm version](https://badge.fury.io/js/react-native-video-processing.svg)](https://badge.fury.io/js/react-native-video-processing) ![npm package](https://img.shields.io/npm/dm/react-native-video-processing.svg)\n\n### Getting Started\n```sh\nnpm install react-native-video-processing --save\n```\n```sh\nyarn add react-native-video-processing\n```\n### You can check test by running\n`$ npm test` or `$ yarn test`\n\n### Installation\n**Note: For RN 0.4x use 1.0 version, for RN 0.3x use 0.16**\n\n#### [Android]\n- Open up `android/app/src/main/java/[...]/MainApplication.java`\n\n- Add `import com.shahenlibrary.RNVideoProcessingPackage;` to the imports at the top of the file\n\n- Add new  `new RNVideoProcessingPackage()`  to the list returned by the getPackages() method\n\n- Append the following lines to `android/settings.gradle`:\n```\ninclude ':react-native-video-processing'\nproject(':react-native-video-processing').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video-processing/android')\n```\n\n- Insert the following lines inside the dependencies block in `android/app/build.gradle`:\n```\n    compile project(':react-native-video-processing')\n```\n\n- Add the following lines to `AndroidManifest.xml`:\n```\n   \u003cuses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" /\u003e\n   \u003cuses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/\u003e\n```\n\n#### [iOS]\n\n1. In Xcode, right click your Xcode project and create `New Group` called `RNVideoProcessing`.\n\n2. Go to `node_modules/react-native-video-processing/ios/RNVideoProcessing` and drag the `.swift` files under the group you just created. Press `Create folder references` option if not pressed.\n\n3. Repeat steps 1 \u0026 2 for the subdirectories `RNVideoTrimmer`, `RNTrimmerView`, and `ICGVideoTrimmer` and all the files underneath them. Make sure you keep the folders hierarchy the same.\n\n4. Go to `node_modules/react-native-video-processing/ios/GPUImage/framework` and drag `GPUImage.xcodeproj` to your project's root directory in Xcode.\n\n   ![Project Structure](readme_assets/project-structure.png)\n\n5. Under your project's `Build Phases`, make sure the `.swift` files you added appear under `Compile Sources`.\n\n6. Under your project's `General` tab, add the following frameworks to  `Linked Frameworks and Libraries` :\n  \n  - CoreMedia\n  - CoreVideo\n  - OpenGLES\n  - AVFoundation\n  - QuartzCore\n  - MobileCoreServices\n  - GPUImage\n\n7. Add `GPUImage.frameworkiOS` to `Embedded Binaries`.\n\n8. Navigate to your project's bridging header file  *\u003cProjectName-Bridging-Header.h\u003e* and add `#import \"RNVideoProcessing.h\"`.\n\n9.  Clean and run your project.\n\n*Check the following video for more setup reference.*\n\n[![Setup](https://img.youtube.com/vi/HRjgeT6NQJM/0.jpg)](https://youtu.be/HRjgeT6NQJM)\n\n## Update ffmpeg binaries\n1. Clone [mobile-ffmpeg](https://github.com/tanersener/mobile-ffmpeg)\n2. Setup project, see [Prerequisites](https://github.com/tanersener/mobile-ffmpeg#51-prerequisites) in README.\n3. Modify `build/android-ffmpeg.sh` so it generates binaries ([more info](https://github.com/tanersener/mobile-ffmpeg/issues/30#issuecomment-425964213))\n    1. Delete --disable-programs line\n    2. Change --disable-static line to --enable-static\n    3. Delete --enable-shared line\n4. Compile binaries: `./android.sh --lts --disable-arm-v7a-neon --enable-x264 --enable-gpl --speed`. The command might finish with `failed`. That's okay because we modified the build script. Make sure every build outputs: `ffmpeg: ok`.\n5. Find `ffmpeg` binaries in `prebuilt/[android-arm|android-arm64|android-x86|android-x86_64]/ffmpeg/bin/ffmpeg`\n6. Copy and rename binaries to `android/src/main/jniLibs/[armeabi-v7a|arm64-v8a|x86|x86_64]/libffmpeg.so`. Make sure you rename the binaries from `ffmpeg` to `libffmpeg.so`!\n\n## Example Usage\n\n```javascript\nimport React, { Component } from 'react';\nimport { View } from 'react-native';\nimport { VideoPlayer, Trimmer } from 'react-native-video-processing';\n\nclass App extends Component {\n    trimVideo() {\n        const options = {\n            startTime: 0,\n            endTime: 15,\n            quality: VideoPlayer.Constants.quality.QUALITY_1280x720, // iOS only\n            saveToCameraRoll: true, // default is false // iOS only\n            saveWithCurrentDate: true, // default is false // iOS only\n        };\n        this.videoPlayerRef.trim(options)\n            .then((newSource) =\u003e console.log(newSource))\n            .catch(console.warn);\n    }\n\n    compressVideo() {\n        const options = {\n            width: 720,\n            height: 1280,\n            bitrateMultiplier: 3,\n            saveToCameraRoll: true, // default is false, iOS only\n            saveWithCurrentDate: true, // default is false, iOS only\n            minimumBitrate: 300000,\n            removeAudio: true, // default is false\n        };\n        this.videoPlayerRef.compress(options)\n            .then((newSource) =\u003e console.log(newSource))\n            .catch(console.warn);\n    }\n\n    getPreviewImageForSecond(second) {\n        const maximumSize = { width: 640, height: 1024 }; // default is { width: 1080, height: 1080 } iOS only\n        this.videoPlayerRef.getPreviewForSecond(second, maximumSize) // maximumSize is iOS only\n        .then((base64String) =\u003e console.log('This is BASE64 of image', base64String))\n        .catch(console.warn);\n    }\n\n    getVideoInfo() {\n        this.videoPlayerRef.getVideoInfo()\n        .then((info) =\u003e console.log(info))\n        .catch(console.warn);\n    }\n\n    render() {\n        return (\n            \u003cView style={{ flex: 1 }}\u003e\n                \u003cVideoPlayer\n                    ref={ref =\u003e this.videoPlayerRef = ref}\n                    startTime={30}  // seconds\n                    endTime={120}   // seconds\n                    play={true}     // default false\n                    replay={true}   // should player play video again if it's ended\n                    rotate={true}   // use this prop to rotate video if it captured in landscape mode iOS only\n                    source={'file:///sdcard/DCIM/....'}\n                    playerWidth={300} // iOS only\n                    playerHeight={500} // iOS only\n                    style={{ backgroundColor: 'black' }}\n                    resizeMode={VideoPlayer.Constants.resizeMode.CONTAIN}\n                    onChange={({ nativeEvent }) =\u003e console.log({ nativeEvent })} // get Current time on every second\n                /\u003e\n                \u003cTrimmer\n                    source={'file:///sdcard/DCIM/....'}\n                    height={100}\n                    width={300}\n                    onTrackerMove={(e) =\u003e console.log(e.currentTime)} // iOS only\n                    currentTime={this.video.currentTime} // use this prop to set tracker position iOS only\n                    themeColor={'white'} // iOS only\n                    thumbWidth={30} // iOS only\n                    trackerColor={'green'} // iOS only\n                    onChange={(e) =\u003e console.log(e.startTime, e.endTime)}\n                /\u003e\n            \u003c/View\u003e\n        );\n    }\n}\n```\nOr you can use `ProcessingManager` without mounting `VideoPlayer` component:\n```javascript\nimport React, { Component } from 'react';\nimport { View } from 'react-native';\nimport { ProcessingManager } from 'react-native-video-processing';\nexport class App extends Component {\n  componentWillMount() {\n    const { source } = this.props;\n    ProcessingManager.getVideoInfo(source)\n      .then(({ duration, size, frameRate, bitrate }) =\u003e console.log(duration, size, frameRate, bitrate));\n  \n    // on iOS it's possible to trim remote files by using remote file as source\n    ProcessingManager.trim(source, options) // like VideoPlayer trim options\n          .then((data) =\u003e console.log(data));\n\n    ProcessingManager.compress(source, options) // like VideoPlayer compress options\n              .then((data) =\u003e console.log(data));\n\n    ProcessingManager.reverse(source) // reverses the source video \n              .then((data) =\u003e console.log(data)); // returns the new file source\n\n    ProcessingManager.boomerang(source) // creates a \"boomerang\" of the surce video (plays forward then plays backwards)\n              .then((data) =\u003e console.log(data)); // returns the new file source\n\n    const maximumSize = { width: 100, height: 200 };\n    ProcessingManager.getPreviewForSecond(source, forSecond, maximumSize)\n      .then((data) =\u003e console.log(data))\n  }\n  render() {\n    return \u003cView /\u003e;\n  }\n}\n```\n\n##\nIf this project was helpful to you, please \u003chtml\u003e\n \u003ca href=\"https://www.buymeacoffee.com/FnENSxi\" target=\"_blank\"\u003e\u003cimg src=\"https://bmc-cdn.nyc3.digitaloceanspaces.com/BMC-button-images/custom_images/yellow_img.png\" alt=\"Buy Me A Coffee\" style=\"height: auto !important;width: auto;\" \u003e\u003c/a\u003e\n \u003c/html\u003e\n\n## Contributing\n\n1. Please follow the eslint style guide.\n2. Please commit with `$ npm run commit`\n\n## Roadmap\n1.  [ ] Use FFMpeg instead of MP4Parser\n2.  [ ] Add ability to add GLSL filters\n3.  [x] Android should be able to compress video\n4.  [x] More processing options\n5.  [ ] Create native trimmer component for Android\n6.  [x] Provide Standalone API\n7.  [ ] Describe API methods with parameters in README\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshahen94%2Freact-native-video-processing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshahen94%2Freact-native-video-processing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshahen94%2Freact-native-video-processing/lists"}