react-native-compressor icon indicating copy to clipboard operation
react-native-compressor copied to clipboard

[Unhandled promise rejection: TypeError: null is not an object (evaluating 'NativeVideoCompressor.compress')]

Open DFRZ7 opened this issue 3 years ago • 17 comments

Current behavior

Hi, when trying to compress a video in my Expo Managed App, I'm getting:

[Unhandled promise rejection: TypeError: null is not an object (evaluating 'NativeVideoCompressor.compress')] at node_modules/react-native-compressor/src/Video/index.tsx:162:48 in compress at node_modules/react-native-compressor/src/Video/index.tsx:119:12 in compress at helpers.js:6:25 in CompressVideo at helpers.js:4:17 in CompressVideo at App.js:40:24 in requestMultiplePermissions

Expected behavior

I would expect a new object based on the video which would be compressed, but at the time, getting just null.

Platform

  • [X] Android
  • [] iOS, no. For iOS, I'm getting another error which is:

Invariant Violation: Native module cannot be null. at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException at node_modules/react-native/Libraries/Core/ExceptionsManager.js:172:19 in handleException at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError at node_modules/@react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError at node_modules/metro-runtime/src/polyfills/require.js:204:6 in guardedLoadModule at http://192.168.1.65:19000/index.bundle?platform=ios&dev=true&hot=false&minify=false:121655:3 in global code

Invariant Violation: "main" has not been registered. This can happen if:

  • Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
  • A module failed to load due to an error and AppRegistry.registerComponent wasn't called. at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException at node_modules/react-native/Libraries/Core/ExceptionsManager.js:172:19 in handleException at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError at node_modules/@react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError

Not sure what that is all about, so trying to work on that one.

React Native Version:

"react-native": "0.64.3",

React Native Compressor Version

"react-native-compressor": "^1.5.1"

Reproducible Steps And Demo:

I created a new app with expo init. Ran > expo install react-native-compressor Validated that this was present on the app.json:

{ "name": "my app", "plugins": ["react-native-compressor"] }

And ran: expo prebuild

Here is the code of the test app:

App.js

import { StatusBar } from "expo-status-bar"; import { StyleSheet, Text, View, Button } from "react-native"; import * as MediaLibrary from "expo-media-library"; import React, { useEffect, useRef, useState } from "react"; import * as FileSystem from "expo-file-system"; import { Video, AVPlaybackStatus } from "expo-av"; import { color } from "react-native/Libraries/Components/View/ReactNativeStyleAttributes"; import helpers from "./helpers";

export default function App() { const [hasMediaLibraryPermission, setHasMediaLibraryPermission] = useState(null); const [obtainedStoreMedia, setObtainedStoreMedia] = useState([]); const video = React.useRef(null); const [status, setStatus] = React.useState({}); const [fileSize, setFileSize] = useState(""); const [compressedFileSize, setCompressedFileSize] = useState("");

useEffect(() => { requestMultiplePermissions(); }, []);

const requestMultiplePermissions = async () => { const mediaLibraryStatus = await MediaLibrary.requestPermissionsAsync(); setHasMediaLibraryPermission(mediaLibraryStatus.status === "granted");

//Grabs the first 1000 media items from the user's local storage.
if (mediaLibraryStatus.status === "granted") {
  const getStoreMedia = await MediaLibrary.getAssetsAsync({
    first: 5,
    //mediaType: [MediaLibrary.MediaType.photo, MediaLibrary.MediaType.video],
    mediaType: [MediaLibrary.MediaType.video],
    sortBy: [MediaLibrary.SortBy.modificationTime],
  });

  let library = "assets";
  let currentStoreMedia = getStoreMedia[library];

  setObtainedStoreMedia(currentStoreMedia[0].uri);
  console.log(await helpers.CompressVideo(currentStoreMedia[0].uri));

  let fileSize = await FileSystem.getInfoAsync(currentStoreMedia[0].uri);
  let fileSizeToInt = parseInt(fileSize.size);
  let fileSizeToMB = fileSizeToInt * 0.000001;
  let truncatedFileSize = fileSizeToMB.toFixed(2);

  setFileSize(truncatedFileSize);

  //setCompressedFileSize(await helpers.CompressVideo());
}

};

return ( <View style={styles.container}> <Text style={{ color: "white" }}>COMPRESS TEST APP</Text> <StatusBar style="auto" /> <Video ref={video} style={{ height: 390, width: 240, borderWidth: 2, borderColor: "black", }} source={{ uri: obtainedStoreMedia, }} useNativeControls={true} resizeMode="contain" isLooping onPlaybackStatusUpdate={(status) => setStatus(() => status)} /> <Text style={{ color: "white" }}> {" "} {"FILE SIZE: " + fileSize + " MB"}{" "} </Text> <Text style={{ color: "yellow" }}> {" "} {"COMPRESSED FILE SIZE: " + compressedFileSize + " MB"}{" "} </Text> </View> ); }

const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "black", alignItems: "center", justifyContent: "center", }, });

helpers.js

import { Video } from "react-native-compressor";

const helpers = { CompressVideo: async function (uri) { console.log(uri); const result = await Video.compress( uri, { compressionMethod: "auto", }, (progress) => { if (backgroundMode) { console.log("Compression Progress: ", progress); } else { setCompressingProgress(progress); } } );

return result;

}, };

export default helpers;

Of course if there is anything else I can add here for testing and all, do let me know. Thank you for all the help!

DFRZ7 avatar Feb 13 '22 20:02 DFRZ7

👋 @DFRZ7 Thanks for opening your issue here! If you find this package useful hit the star🌟!

github-actions[bot] avatar Feb 13 '22 20:02 github-actions[bot]

I have the same issue here. Tested on iOS + Expo SDK44 and have the same error of "Invariant Violation: Native module cannot be null." and "Invariant Violation: "main" has not been registered." The error message will appear immediately once "import { Video } from "react-native-compressor";" is sated in the script even compression is not started.

react-native-compressor was installed via expo install.

I am using Windows 10 and therefore pod is not applicable to me. I don't know whether this is the reason.

WWbuhtig avatar Feb 14 '22 03:02 WWbuhtig

@DFRZ7 @WWbuhtig duplicate issue https://github.com/Shobbak/react-native-compressor/issues/86 . can you see this comment https://github.com/Shobbak/react-native-compressor/issues/86#issuecomment-1026709570?

numandev1 avatar Feb 14 '22 08:02 numandev1

@nomi9995 Thank you for that, the link: https://github.com/Shobbak/react-native-compressor/issues/86 was perfect in regards the iOS detail, nonetheless, getting a similiar issue in which if I add the import of the module, I will get:

Invariant Violation: Native module cannot be null. at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException at node_modules/react-native/Libraries/Core/ExceptionsManager.js:172:19 in handleException at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError at node_modules/@react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError at node_modules/metro-runtime/src/polyfills/require.js:204:6 in guardedLoadModule at http://192.168.1.65:19000/index.bundle?platform=ios&dev=true&hot=false&minify=false:121654:3 in global code

Invariant Violation: "main" has not been registered. This can happen if:

  • Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
  • A module failed to load due to an error and AppRegistry.registerComponent wasn't called. at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException at node_modules/react-native/Libraries/Core/ExceptionsManager.js:172:19 in handleException at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError at node_modules/@react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError

Tried:

  • yarn add react-native-compressor@rnlessthan65 (up to here I could open the app, but commenting the import, so definately a step forward)

-cd ios -pod install -remove your yarn.lock or package-lock.json -remove node_modules -run yarn or npm install

As for Android:

[Unhandled promise rejection: TypeError: null is not an object (evaluating 'NativeVideoCompressor.compress')] at node_modules/react-native-compressor/src/Video/index.tsx:156:48 in compress at node_modules/react-native-compressor/src/Video/index.tsx:113:12 in compress at helpers.js:6:25 in CompressVideo at helpers.js:4:17 in CompressVideo at App.js:40:24 in requestMultiplePermissions

DFRZ7 avatar Feb 16 '22 04:02 DFRZ7

@DFRZ7 IOS is working on your side? did you follow these steps? Add the Compressor plugin to your Expo config (app.json, app.config.json or app.config.js):

{
  "name": "my app",
  "plugins": ["react-native-compressor"]
}

Finally, compile the mods:

expo prebuild

To apply the changes, build a new binary with EAS:

eas build

https://github.com/Shobbak/react-native-compressor#managed-expo

numandev1 avatar Feb 16 '22 05:02 numandev1

agree with @nomi9995 This error (at least with the same message) can occurred if you still use the local expo server and Expo Go app instead the new process via EAS

pihomeserver avatar Feb 16 '22 08:02 pihomeserver

@pihomeserver @nomi9995 Thanks for the clarification. It is possible to use the new process via EAS to build the app, but Expo Go app is also needed for testing (where the error occurred).

WWbuhtig avatar Feb 17 '22 08:02 WWbuhtig

Ah. Not sure then how to do as for now i use the EAS build workflow even for testing and live development so i don't use Expo Go anymore. I have 2 native plugins embedded to that's the only way i found to develop/test/deploy using them

pihomeserver avatar Feb 17 '22 09:02 pihomeserver

@pihomeserver @nomi9995 I see. Thanks, So the issue is more on the Expo side.

I found the solution to provide fallback as below: https://docs.expo.dev/bare/using-expo-client/#use-conditional-inline-requires-to-provide-fallbacks so at least no error would be shown.

WWbuhtig avatar Feb 18 '22 06:02 WWbuhtig

@WWbuhtig thank you so much. 🎉

numandev1 avatar Feb 18 '22 06:02 numandev1

@pihomeserver thank you so much. 🎉

numandev1 avatar Feb 18 '22 06:02 numandev1

@WWbuhtig Thank you, that detail is without a doubt extremely useful. Nonetheless, my worry at the time, is that the module does load, but getting the following on Android:

[Unhandled promise rejection: TypeError: null is not an object (evaluating 'NativeVideoCompressor.compress')] at node_modules/react-native-compressor/src/Video/index.tsx:156:48 in compress at node_modules/react-native-compressor/src/Video/index.tsx:113:12 in compress at helpers.js:6:25 in CompressVideo at helpers.js:4:17 in CompressVideo at App.js:40:24 in requestMultiplePermissions

Nonetheless, this does help with the following error on iOS if not mistaken:

A module failed to load due to an error and AppRegistry.registerComponent wasn't called. at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException at node_modules/react-native/Libraries/Core/ExceptionsManager.js:172:19 in handleException at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError at node_modules/@react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError

Now, @pihomeserver you mentioned that doing this in EAS has helped you, any specific documentation I could follow? I understand basically the idea is that EAS would allow us in a way the capability to run native modules in Expo? And thank you all. I was also thinking about even zipping the files, but also getting null based on native modules.

And thank you all!

DFRZ7 avatar Mar 05 '22 18:03 DFRZ7

@DFRZ7 I followed a youtube tutoriel and web pages. Test and fail approach ;-) If i remember the full approach i removed all native plugins and make my app work with EAS pipeline. For info, the local build option that should be faster fails 100% of time so use the pipeline linked to expo. Once it worked then i added native plugins

pihomeserver avatar Mar 06 '22 13:03 pihomeserver

@pihomeserver thank you for that, by any chance do you have any of those references you used so I could possibly validate? And yeah, without a doubt, will continue testing to see how this can become a possibility to use of course, but as you mentioned:

  1. Create a standalone app.
  2. Work with EAS pipeline.
  3. Once this is stable, add the native plugins, in this case the compressor component.

thank you again!

DFRZ7 avatar Mar 19 '22 15:03 DFRZ7

@DFRZ7 Here is the one i used provided here: https://youtu.be/id0Im72UN6w

pihomeserver avatar Mar 19 '22 16:03 pihomeserver

@pihomeserver Thank you so much, will have a look at this and if anything update you with the results here.

DFRZ7 avatar Mar 19 '22 18:03 DFRZ7

Hey team, just wanted to update you all, but confirmed that on EAS is completely working for Android. I'm still working to get my build and test up with iOS, but will update this thread so we can close all out. Thank you again for everything!

DFRZ7 avatar Apr 17 '22 20:04 DFRZ7

This issue is stale because it has been open 365 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Apr 18 '23 01:04 github-actions[bot]

This issue was closed because it has been stalled for 7 days with no activity.

github-actions[bot] avatar Apr 26 '23 01:04 github-actions[bot]