package com.reactnativettsandroid import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactContextBaseJavaModule import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.Promise import android.net.Uri import android.os.Build import android.os.Bundle import android.os.Environment import android.speech.tts.TextToSpeech import android.speech.tts.UtteranceProgressListener import android.util.Log import java.io.File import java.util.* class TtsAndroidModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { override fun getName(): String { return "TtsAndroid" } private val TAG = "TextToSpeech" private var fileUri: Uri? = null private var tts: TextToSpeech? = null private fun initTextToSpeech() { if (tts == null) { tts = TextToSpeech(getReactApplicationContextIfActiveOrWarn()) { if (it == TextToSpeech.SUCCESS) { val result: Int? = tts?.setLanguage(Locale.getDefault()) if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Log.d(TAG, "reactContext Language is not supported" ) } else { Log.d(TAG, "Text-To-Speech engine is initialized" ) } } else if (it == TextToSpeech.ERROR) { Log.d(TAG, "Error occurred while initializing Text-To-Speech engine" ) } } tts?.setOnUtteranceProgressListener(object : UtteranceProgressListener() { override fun onStart(utteranceId: String?) { Log.d(TAG, "start created fileTTS") } override fun onDone(utteranceId: String?) { Log.d(TAG, "successfully created fileTTS") } override fun onError(utteranceId: String?) { Log.d(TAG, "error created fileTTS") } }) } } private fun fileCreate(inputText: String?, uri: String): String? { if (inputText.isNullOrEmpty()) { return "" } val destFileName = "$uri/tts_file.wav" Log.d(TAG, "ok "+ destFileName) val bundle = Bundle() bundle.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, inputText) val fileTTS = File(destFileName) if (!fileTTS.exists()) { val success: Boolean = fileTTS.createNewFile() if (!success) { Log.d(TAG, "failed to create fileTTS") return "" } } val sr: Int = tts!!.synthesizeToFile(inputText, bundle, fileTTS, destFileName) Log.d(TAG, "synthesize returns = $sr") fileUri = Uri.fromFile(fileTTS) return fileUri!!.getPath()?.orEmpty() } // Example method // See https://reactnative.dev/docs/native-modules-android @ReactMethod fun multiply(value: String, uri: String, promise: Promise) { initTextToSpeech() promise.resolve(fileCreate("123", uri).toString()) } }