createViewManagers(ReactApplicationContext reactContext) {
22 | return Collections.emptyList();
23 | }
24 | }
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | apply plugin: 'com.android.library'
3 |
4 | def safeExtGet(prop, fallback) {
5 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
6 | }
7 |
8 | android {
9 | compileSdkVersion safeExtGet('compileSdkVersion', 29)
10 | buildToolsVersion safeExtGet('buildToolsVersion', "29.0.3")
11 |
12 | defaultConfig {
13 | minSdkVersion safeExtGet('minSdkVersion', 16)
14 | targetSdkVersion safeExtGet('targetSdkVersion', 29)
15 | versionCode 1
16 | versionName "1.0"
17 | ndk {
18 | abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
19 | }
20 | }
21 | lintOptions {
22 | warning 'InvalidPackage'
23 | }
24 | }
25 |
26 | dependencies {
27 | implementation 'com.facebook.react:react-native:+'
28 | implementation 'com.googlecode.mp4parser:isoparser:1.1.21'
29 | }
30 |
31 | allprojects {
32 | repositories {
33 | mavenLocal()
34 | jcenter()
35 | }
36 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-video-manager",
3 | "version": "0.1.2",
4 | "license": "MIT",
5 | "bugs": {
6 | "url": "https://github.com/lklima/react-native-video-manager/issues"
7 | },
8 | "homepage": "https://github.com/lklima/react-native-video-manager#readme",
9 | "description": "Module cross platform to merge multiple videos",
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/lklima/react-native-video-manager"
13 | },
14 | "keywords": [
15 | "react",
16 | "react-native",
17 | "ios",
18 | "android",
19 | "video",
20 | "manager",
21 | "merge",
22 | "videoedit"
23 | ],
24 | "author": "Lucas Lima",
25 | "main": "index.ts",
26 | "scripts": {
27 | "pods": "cd example && pod install"
28 | },
29 | "peerDependencies": {
30 | "react": "*",
31 | "react-native": "*"
32 | },
33 | "devDependencies": {
34 | "@types/jest": "^27.5.1",
35 | "@types/react": "^18.0.9",
36 | "@types/react-native": "^0.67.7",
37 | "@types/react-test-renderer": "^18.0.0",
38 | "typescript": "^4.6.4"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Lucas Lima
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | ## Development workflow
4 |
5 | ### Install dependencies
6 |
7 | Use yarn to install development dependencies.
8 |
9 | ```sh
10 | yarn
11 | ```
12 |
13 | If you don't have expo-cli installed:
14 |
15 | ```sh
16 | npm install -g expo-cli
17 | ```
18 |
19 | Move to the `example` directory and install dependencies there too.
20 |
21 | ```sh
22 | cd example
23 | yarn
24 | ```
25 |
26 | ```sh
27 | cd ios && pod install && cd ..
28 | ```
29 |
30 | ### Example app
31 |
32 | Start the example app to test your changes. You can use one of the following commands from the example root, depending on the platform you want to use.
33 |
34 | From the `example` directory:
35 |
36 | #### iOS
37 |
38 | ```sh
39 | yarn ios
40 | ```
41 |
42 | for running in device
43 |
44 | ```sh
45 | yarn device
46 | ```
47 |
48 | I also recommend opening `example/ios/exmaple.xcworkspace` in Xcode if you need to make changes to native code.
49 |
50 | #### Android
51 |
52 | ```sh
53 | yarn android
54 | ```
55 |
56 | I also recommend opening `example/android` in Android Studio if you need to make changes to native code.
57 |
58 | ### Open a pull request!
59 |
--------------------------------------------------------------------------------
/example/android/app/BUCK:
--------------------------------------------------------------------------------
1 | # To learn about Buck see [Docs](https://buckbuild.com/).
2 | # To run your application with Buck:
3 | # - install Buck
4 | # - `npm start` - to start the packager
5 | # - `cd android`
6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8 | # - `buck install -r android/app` - compile, install and run application
9 | #
10 |
11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
12 |
13 | lib_deps = []
14 |
15 | create_aar_targets(glob(["libs/*.aar"]))
16 |
17 | create_jar_targets(glob(["libs/*.jar"]))
18 |
19 | android_library(
20 | name = "all-libs",
21 | exported_deps = lib_deps,
22 | )
23 |
24 | android_library(
25 | name = "app-code",
26 | srcs = glob([
27 | "src/main/java/**/*.java",
28 | ]),
29 | deps = [
30 | ":all-libs",
31 | ":build_config",
32 | ":res",
33 | ],
34 | )
35 |
36 | android_build_config(
37 | name = "build_config",
38 | package = "com.example",
39 | )
40 |
41 | android_resource(
42 | name = "res",
43 | package = "com.example",
44 | res = "src/main/res",
45 | )
46 |
47 | android_binary(
48 | name = "app",
49 | keystore = "//android/keystores:debug",
50 | manifest = "src/main/AndroidManifest.xml",
51 | package_type = "debug",
52 | deps = [
53 | ":app-code",
54 | ],
55 | )
56 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = "29.0.3"
6 | minSdkVersion = 21
7 | compileSdkVersion = 30
8 | targetSdkVersion = 30
9 | }
10 | repositories {
11 | google()
12 | mavenCentral()
13 | jcenter()
14 | }
15 | dependencies {
16 | classpath("com.android.tools.build:gradle:4.1.0")
17 |
18 | // NOTE: Do not place your application dependencies here; they belong
19 | // in the individual module build.gradle files
20 | }
21 | }
22 |
23 | allprojects {
24 | repositories {
25 | mavenLocal()
26 | maven {
27 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
28 | url(new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../android"))
29 | }
30 | maven {
31 | // Android JSC is installed from npm
32 | url(new File(["node", "--print", "require.resolve('jsc-android/package.json')"].execute(null, rootDir).text.trim(), "../dist"))
33 | }
34 | maven {
35 | // expo-camera bundles a custom com.google.android:cameraview
36 | url "$rootDir/../node_modules/expo-camera/android/maven"
37 | }
38 |
39 | google()
40 | mavenCentral()
41 | jcenter()
42 | maven { url 'https://www.jitpack.io' }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/example/src/Main/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from "react-native";
2 |
3 | export const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | },
7 | camerContent: {
8 | height: "70%",
9 | },
10 | camera: {
11 | flex: 1,
12 | },
13 | buttonContainer: {
14 | flexDirection: "row",
15 | position: "absolute",
16 | bottom: 0,
17 | width: "100%",
18 | alignItems: "center",
19 | justifyContent: "center",
20 | padding: 20,
21 | },
22 | flipButton: {
23 | position: "absolute",
24 | left: 20,
25 | height: 40,
26 | width: 40,
27 | borderRadius: 40,
28 | backgroundColor: "rgba(0, 0, 0, 0.4)",
29 | alignItems: "center",
30 | justifyContent: "center",
31 | },
32 | recButton: {
33 | height: 60,
34 | width: 60,
35 | borderRadius: 30,
36 | borderWidth: 4,
37 | borderColor: "white",
38 | },
39 | text: {
40 | fontSize: 18,
41 | color: "white",
42 | },
43 | tumbContent: {
44 | width: "100%",
45 | height: 70,
46 | backgroundColor: "gray",
47 | },
48 | thumb: {
49 | height: 75,
50 | width: 75,
51 | margin: 8,
52 | borderWidth: 2,
53 | borderColor: "black",
54 | },
55 | mergeButton: {
56 | backgroundColor: "#4caf50",
57 | height: 45,
58 | width: "90%",
59 | borderRadius: 10,
60 | alignItems: "center",
61 | justifyContent: "center",
62 | alignSelf: "center",
63 | marginBottom: 20,
64 | },
65 | mergeButtonText: {
66 | color: "white",
67 | fontSize: 18,
68 | fontWeight: "bold",
69 | },
70 | });
71 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-video-manager
2 |
3 | [](https://www.npmjs.com/package/react-native-video-manager)  
4 |
5 | Module cross platform to merge multiple videos.
6 |
7 | This tool based on [`react-native-video-editor`](https://www.npmjs.com/package/react-native-video-editor), with working example, support to newer React Native versions, and more improvements.
8 |
9 | ## Installation
10 |
11 | ```sh
12 | yarn add react-native-video-manager
13 | ```
14 |
15 | or
16 |
17 | ```sh
18 | npm install react-native-video-manager
19 | ```
20 |
21 | You then need to link the native parts of the library for the platforms you are using.
22 |
23 | - **iOS Platform:**
24 |
25 | `$ npx pod-install`
26 |
27 | - **Android Platform:**
28 |
29 | `no additional steps required`
30 |
31 | ## Usage
32 |
33 | ```js
34 | import { VideoManager } from "react-native-video-manager";
35 |
36 | // ...
37 | const videos = ["file:///video1.mp4", "file:///video2.mp4"];
38 |
39 | try {
40 | const { uri } = await VideoManager.merge(videos);
41 |
42 | console.log("merged video path", uri);
43 | } catch (error) {
44 | console.log(error);
45 | }
46 | // ...
47 | ```
48 |
49 | You can also check a complete example in `/example` folder.
50 |
51 | ## Contributing
52 |
53 | See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
54 |
55 | ## License
56 |
57 | MIT
58 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
2 | require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
3 | require File.join(File.dirname(`node --print "require.resolve('@react-native-community/cli-platform-ios/package.json')"`), "native_modules")
4 |
5 | platform :ios, '12.0'
6 |
7 | require 'json'
8 | podfile_properties = JSON.parse(File.read('./Podfile.properties.json')) rescue {}
9 |
10 | target 'example' do
11 | use_expo_modules!
12 | config = use_native_modules!
13 |
14 | use_react_native!(
15 | :path => config[:reactNativePath],
16 | :hermes_enabled => podfile_properties['expo.jsEngine'] == 'hermes'
17 | )
18 |
19 | # Uncomment to opt-in to using Flipper
20 | #
21 | # if !ENV['CI']
22 | # use_flipper!('Flipper' => '0.75.1', 'Flipper-Folly' => '2.5.3', 'Flipper-RSocket' => '1.3.1')
23 | # end
24 |
25 | post_install do |installer|
26 | react_native_post_install(installer)
27 |
28 | # Workaround `Cycle inside FBReactNativeSpec` error for react-native 0.64
29 | # Reference: https://github.com/software-mansion/react-native-screens/issues/842#issuecomment-812543933
30 | installer.pods_project.targets.each do |target|
31 | if (target.name&.eql?('FBReactNativeSpec'))
32 | target.build_phases.each do |build_phase|
33 | if (build_phase.respond_to?(:name) && build_phase.name.eql?('[CP-User] Generate Specs'))
34 | target.build_phases.move(build_phase, 0)
35 | end
36 | end
37 | end
38 | end
39 | end
40 |
41 | post_integrate do |installer|
42 | begin
43 | expo_patch_react_imports!(installer)
44 | rescue => e
45 | Pod::UI.warn e
46 | end
47 | end
48 |
49 | end
50 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 |
25 | # Automatically convert third-party libraries to use AndroidX
26 | android.enableJetifier=true
27 |
28 | # Version of flipper SDK to use with React Native
29 | FLIPPER_VERSION=0.54.0
30 |
31 | # The hosted JavaScript engine
32 | # Supported values: expo.jsEngine = "hermes" | "jsc"
33 | expo.jsEngine=jsc
34 |
35 | # Enable GIF support in React Native images (~200 B increase)
36 | expo.gif.enabled=true
37 | # Enable webp support in React Native images (~85 KB increase)
38 | expo.webp.enabled=true
39 | # Enable animated webp support (~3.4 MB increase)
40 | # Disabled by default because iOS doesn't support animated webp
41 | expo.webp.animated=false
--------------------------------------------------------------------------------
/example/ios/example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleSignature
18 | ????
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | NSCameraUsageDescription
26 | Allow $(PRODUCT_NAME) to use the camera
27 | NSMicrophoneUsageDescription
28 | Allow $(PRODUCT_NAME) to use the microphone
29 | NSAppTransportSecurity
30 |
31 | NSAllowsArbitraryLoads
32 |
33 | NSExceptionDomains
34 |
35 | localhost
36 |
37 | NSExceptionAllowsInsecureHTTPLoads
38 |
39 |
40 |
41 |
42 | UILaunchStoryboardName
43 | SplashScreen
44 | UIRequiredDeviceCapabilities
45 |
46 | armv7
47 |
48 | UISupportedInterfaceOrientations
49 |
50 | UIInterfaceOrientationPortrait
51 | UIInterfaceOrientationLandscapeLeft
52 | UIInterfaceOrientationLandscapeRight
53 |
54 | UIViewControllerBasedStatusBarAppearance
55 |
56 | UIStatusBarStyle
57 | UIStatusBarStyleDefault
58 |
59 |
60 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import android.os.Build;
4 | import android.os.Bundle;
5 |
6 | import com.facebook.react.ReactActivity;
7 | import com.facebook.react.ReactActivityDelegate;
8 | import com.facebook.react.ReactRootView;
9 |
10 | import expo.modules.ReactActivityDelegateWrapper;
11 |
12 | public class MainActivity extends ReactActivity {
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | // Set the theme to AppTheme BEFORE onCreate to support
16 | // coloring the background, status bar, and navigation bar.
17 | // This is required for expo-splash-screen.
18 | setTheme(R.style.AppTheme);
19 | super.onCreate(null);
20 | }
21 |
22 | /**
23 | * Returns the name of the main component registered from JavaScript.
24 | * This is used to schedule rendering of the component.
25 | */
26 | @Override
27 | protected String getMainComponentName() {
28 | return "main";
29 | }
30 |
31 | @Override
32 | protected ReactActivityDelegate createReactActivityDelegate() {
33 | return new ReactActivityDelegateWrapper(this,
34 | new ReactActivityDelegate(this, getMainComponentName())
35 | );
36 | }
37 |
38 | /**
39 | * Align the back button behavior with Android S
40 | * where moving root activities to background instead of finishing activities.
41 | * @see onBackPressed
42 | */
43 | @Override
44 | public void invokeDefaultOnBackPressed() {
45 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
46 | if (!moveTaskToBack(false)) {
47 | // For non-root activities, use the default implementation to finish them.
48 | super.invokeDefaultOnBackPressed();
49 | }
50 | return;
51 | }
52 |
53 | // Use the default back button implementation on Android S
54 | // because it's doing more than {@link Activity#moveTaskToBack} in fact.
55 | super.invokeDefaultOnBackPressed();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/ios/RNVideoManager.xcodeproj/xcshareddata/xcschemes/RNVideoManager.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
57 |
58 |
59 |
60 |
62 |
63 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto init
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto init
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :init
68 | @rem Get command-line arguments, handling Windows variants
69 |
70 | if not "%OS%" == "Windows_NT" goto win9xME_args
71 |
72 | :win9xME_args
73 | @rem Slurp the command line arguments.
74 | set CMD_LINE_ARGS=
75 | set _SKIP=2
76 |
77 | :win9xME_args_slurp
78 | if "x%~1" == "x" goto execute
79 |
80 | set CMD_LINE_ARGS=%*
81 |
82 | :execute
83 | @rem Setup the command line
84 |
85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
86 |
87 | @rem Execute Gradle
88 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
89 |
90 | :end
91 | @rem End local scope for the variables with windows NT shell
92 | if "%ERRORLEVEL%"=="0" goto mainEnd
93 |
94 | :fail
95 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
96 | rem the _cmd.exe /c_ return code!
97 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
98 | exit /b 1
99 |
100 | :mainEnd
101 | if "%OS%"=="Windows_NT" endlocal
102 |
103 | :omega
104 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/java/com/example/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package com.example;
8 |
9 | import android.content.Context;
10 | import com.facebook.flipper.android.AndroidFlipperClient;
11 | import com.facebook.flipper.android.utils.FlipperUtils;
12 | import com.facebook.flipper.core.FlipperClient;
13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping;
17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
20 | import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
21 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
22 | import com.facebook.react.ReactInstanceManager;
23 | import com.facebook.react.bridge.ReactContext;
24 | import com.facebook.react.modules.network.NetworkingModule;
25 | import okhttp3.OkHttpClient;
26 |
27 | public class ReactNativeFlipper {
28 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
29 | if (FlipperUtils.shouldEnableFlipper(context)) {
30 | final FlipperClient client = AndroidFlipperClient.getInstance(context);
31 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
32 | client.addPlugin(new ReactFlipperPlugin());
33 | client.addPlugin(new DatabasesFlipperPlugin(context));
34 | client.addPlugin(new SharedPreferencesFlipperPlugin(context));
35 | client.addPlugin(CrashReporterPlugin.getInstance());
36 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
37 | NetworkingModule.setCustomClientBuilder(
38 | new NetworkingModule.CustomClientBuilder() {
39 | @Override
40 | public void apply(OkHttpClient.Builder builder) {
41 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
42 | }
43 | });
44 | client.addPlugin(networkFlipperPlugin);
45 | client.start();
46 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
47 | // Hence we run if after all native modules have been initialized
48 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
49 | if (reactContext == null) {
50 | reactInstanceManager.addReactInstanceEventListener(
51 | new ReactInstanceManager.ReactInstanceEventListener() {
52 | @Override
53 | public void onReactContextInitialized(ReactContext reactContext) {
54 | reactInstanceManager.removeReactInstanceEventListener(this);
55 | reactContext.runOnNativeModulesQueueThread(
56 | new Runnable() {
57 | @Override
58 | public void run() {
59 | client.addPlugin(new FrescoFlipperPlugin());
60 | }
61 | });
62 | }
63 | });
64 | } else {
65 | client.addPlugin(new FrescoFlipperPlugin());
66 | }
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/example/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.content.res.Configuration;
6 | import androidx.annotation.NonNull;
7 |
8 | import com.facebook.react.PackageList;
9 | import com.facebook.react.ReactApplication;
10 | import com.facebook.react.ReactInstanceManager;
11 | import com.facebook.react.ReactNativeHost;
12 | import com.facebook.react.ReactPackage;
13 | import com.facebook.soloader.SoLoader;
14 |
15 | import expo.modules.ApplicationLifecycleDispatcher;
16 | import expo.modules.ReactNativeHostWrapper;
17 |
18 | import com.facebook.react.bridge.JSIModulePackage;
19 |
20 | import java.lang.reflect.InvocationTargetException;
21 | import java.util.List;
22 |
23 | public class MainApplication extends Application implements ReactApplication {
24 | private final ReactNativeHost mReactNativeHost = new ReactNativeHostWrapper(
25 | this,
26 | new ReactNativeHost(this) {
27 | @Override
28 | public boolean getUseDeveloperSupport() {
29 | return BuildConfig.DEBUG;
30 | }
31 |
32 | @Override
33 | protected List getPackages() {
34 | @SuppressWarnings("UnnecessaryLocalVariable")
35 | List packages = new PackageList(this).getPackages();
36 | // Packages that cannot be autolinked yet can be added manually here, for example:
37 | // packages.add(new MyReactNativePackage());
38 | // packages.add(new RNVideoManagerPackage());
39 | return packages;
40 | }
41 |
42 | @Override
43 | protected String getJSMainModuleName() {
44 | return "index";
45 | }
46 | });
47 |
48 | @Override
49 | public ReactNativeHost getReactNativeHost() {
50 | return mReactNativeHost;
51 | }
52 |
53 | @Override
54 | public void onCreate() {
55 | super.onCreate();
56 | SoLoader.init(this, /* native exopackage */ false);
57 |
58 | initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
59 | ApplicationLifecycleDispatcher.onApplicationCreate(this);
60 | }
61 |
62 | @Override
63 | public void onConfigurationChanged(@NonNull Configuration newConfig) {
64 | super.onConfigurationChanged(newConfig);
65 | ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
66 | }
67 |
68 | /**
69 | * Loads Flipper in React Native templates. Call this in the onCreate method with something like
70 | * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
71 | *
72 | * @param context
73 | * @param reactInstanceManager
74 | */
75 | private static void initializeFlipper(
76 | Context context, ReactInstanceManager reactInstanceManager) {
77 | if (BuildConfig.DEBUG) {
78 | try {
79 | /*
80 | We use reflection here to pick up the class that initializes Flipper,
81 | since Flipper library is not available in release mode
82 | */
83 | Class> aClass = Class.forName("com.example.ReactNativeFlipper");
84 | aClass
85 | .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
86 | .invoke(null, context, reactInstanceManager);
87 | } catch (ClassNotFoundException e) {
88 | e.printStackTrace();
89 | } catch (NoSuchMethodException e) {
90 | e.printStackTrace();
91 | } catch (IllegalAccessException e) {
92 | e.printStackTrace();
93 | } catch (InvocationTargetException e) {
94 | e.printStackTrace();
95 | }
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/example/ios/example/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 |
3 | #import
4 | #import
5 | #import
6 | #import
7 | #import
8 |
9 | #if defined(FB_SONARKIT_ENABLED) && __has_include()
10 | #import
11 | #import
12 | #import
13 | #import
14 | #import
15 | #import
16 |
17 | static void InitializeFlipper(UIApplication *application) {
18 | FlipperClient *client = [FlipperClient sharedClient];
19 | SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
20 | [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
21 | [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
22 | [client addPlugin:[FlipperKitReactPlugin new]];
23 | [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
24 | [client start];
25 | }
26 | #endif
27 |
28 | @implementation AppDelegate
29 |
30 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
31 | {
32 | #if defined(FB_SONARKIT_ENABLED) && __has_include()
33 | InitializeFlipper(application);
34 | #endif
35 |
36 | RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
37 | RCTRootView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:nil];
38 | rootView.backgroundColor = [UIColor whiteColor];
39 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
40 | UIViewController *rootViewController = [self.reactDelegate createRootViewController];
41 | rootViewController.view = rootView;
42 | self.window.rootViewController = rootViewController;
43 | [self.window makeKeyAndVisible];
44 |
45 | [super application:application didFinishLaunchingWithOptions:launchOptions];
46 |
47 | return YES;
48 | }
49 |
50 | - (NSArray> *)extraModulesForBridge:(RCTBridge *)bridge
51 | {
52 | // If you'd like to export some custom RCTBridgeModules, add them here!
53 | return @[];
54 | }
55 |
56 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
57 | #ifdef DEBUG
58 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
59 | #else
60 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
61 | #endif
62 | }
63 |
64 | // Linking API
65 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options {
66 | return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
67 | }
68 |
69 | // Universal Links
70 | - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler {
71 | BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
72 | return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/example/ios/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
53 |
55 |
61 |
62 |
63 |
64 |
70 |
72 |
78 |
79 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/android/src/main/java/com/lklima/video/manager/RNVideoManagerModule.java:
--------------------------------------------------------------------------------
1 |
2 | package com.lklima.video.manager;
3 |
4 | import com.coremedia.iso.boxes.Container;
5 | import com.facebook.react.bridge.ReactApplicationContext;
6 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
7 | import com.facebook.react.bridge.ReactMethod;
8 | import com.facebook.react.bridge.Promise;
9 |
10 | import android.util.Log;
11 | import com.facebook.react.bridge.ReadableArray;
12 |
13 | import com.googlecode.mp4parser.authoring.Movie;
14 | import com.googlecode.mp4parser.authoring.Track;
15 | import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
16 | import com.googlecode.mp4parser.authoring.tracks.AppendTrack;
17 | import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
18 |
19 | import java.io.FileNotFoundException;
20 | import java.io.IOException;
21 | import java.io.RandomAccessFile;
22 | import java.nio.channels.FileChannel;
23 | import java.util.ArrayList;
24 | import java.util.LinkedList;
25 | import java.util.List;
26 |
27 | public class RNVideoManagerModule extends ReactContextBaseJavaModule {
28 |
29 | private final ReactApplicationContext reactContext;
30 |
31 | public RNVideoManagerModule(ReactApplicationContext reactContext) {
32 | super(reactContext);
33 | this.reactContext = reactContext;
34 | }
35 |
36 | @ReactMethod
37 | public void merge(ReadableArray videoFiles, Promise promise) {
38 |
39 | List inMovies = new ArrayList();
40 |
41 | for (int i = 0; i < videoFiles.size(); i++) {
42 | String videoUrl = videoFiles.getString(i).replaceFirst("file://", "");
43 |
44 | try {
45 | inMovies.add(MovieCreator.build(videoUrl));
46 | } catch (IOException e) {
47 | promise.reject(e.getMessage());
48 | e.printStackTrace();
49 | }
50 | }
51 |
52 | List