1

I am new to react-native and I need to build an react-native module for the purpose of using TensorFlow Lite to STT and TTS.

I created the react-native module with the create-react-native-library library.

Here is the command for create the react-native module npx create-react-native-library

Here is the structure of the project generated by the create-react-native-library project structure

And in the ./src/index.tsx I write the function like this

export function loadTflite(path: string): Promise<void> {
  return SttTtsReactNative.loadTflite(path)
}

In the ./android/src/main/java/projectName/sttttsReactNativeModule.java I implemented the function loadTflite declared in the src/index.tsx.

Here is the code

@ReactModule(name = SttTtsReactNativeModule.NAME)
public class SttTtsReactNativeModule extends ReactContextBaseJavaModule {
  public static final String NAME = "SttTtsReactNative";
  private final ReactApplicationContext context;

  public SttTtsReactNativeModule(ReactApplicationContext reactContext) {
    super(reactContext);
    context = reactContext;
  }

  @Override
  @NonNull
  public String getName() {
    return NAME;
  }

  @ReactMethod
  public void loadTflite(String path, Promise promise) {
    try {
      AssetManager assetManager = context.getAssets();
      assetManager.openFd(path);
      promise.resolve(0);
    }catch(Exception ex) {
      ex.printStackTrace();
      Log.e("Tflite loading Error", ex.getMessage());
      promise.reject("Tflite loading Error", ex.toString());
    }
  }
}

After all of this I write a test in the ./example/src/App.tsx Here is the code

import { multiply, loadTflite } from 'stt-tts-react-native';
export default function App() {
  const [result, setResult] = React.useState<string | undefined>();

  React.useEffect(() => {
      loadTflite('./models/deepSpeech.tflite').then((rs) => {
        setResult("success")
      }).catch((e) => {
        console.error(`Failed to load the tflite. The error is ${e}`)
        setResult('Failed')
      })
  }, []);

  return (
    <View style={styles.container}>
      <Text>Result: {result}</Text>
    </View>
  );
}

You can see the parameter of path is the relative path of the tflite model

Here is the folder of the models structure of the models

After all of it done when I run the react-native app with the following command

In first terminal I run the command npx react-native start

The output of it is: output of npx react-native start

In another terminal I run the command yarn run android

The command will open the emulator and then install the app on the emulator this is no any problem The problem is when it render which mean it will call the function loadTflite The function loadTflite says the file not found here is the error message:

The error is Error: java.io.FileNotFoundException: ./models/deepSpeech.tflite

I dont know what the problem is so I tried to include the tflite file to assets

I edited the metro.config.js file and add the assetExts property on it.

Here is the content of the metro.config.js file

const path = require('path');
const escape = require('escape-string-regexp');
const exclusionList = require('metro-config/src/defaults/exclusionList');
const pak = require('../package.json');

const root = path.resolve(__dirname, '..');

const modules = Object.keys({
  ...pak.peerDependencies,
});
const defaultAssetExts = require("metro-config/src/defaults/defaults").assetExts;

module.exports = {
  projectRoot: __dirname,
  watchFolders: [root],

  // We need to make sure that only one version is loaded for peerDependencies
  // So we block them at the root, and alias them to the versions in example's node_modules
  resolver: {
    blacklistRE: exclusionList(
      modules.map(
        (m) =>
          new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`)
      )
    ),

    extraNodeModules: modules.reduce((acc, name) => {
      acc[name] = path.join(__dirname, 'node_modules', name);
      return acc;
    }, {}),
  
    
    assetExts: [
      ...defaultAssetExts,
      'tflite'
    ]
  },

  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
};

But the result is the same. I dont know what should I do to fix the problem.

What I want is just load a static file in java file which in the android folder from the example folder

Thanks.

Ma Zheng
  • 11
  • 2

0 Answers0