react-native-davoice-tts 1.0.231 → 1.0.233
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/TTSRNBridge.podspec
CHANGED
|
@@ -2,7 +2,7 @@ require 'json'
|
|
|
2
2
|
|
|
3
3
|
Pod::Spec.new do |s|
|
|
4
4
|
s.name = "TTSRNBridge"
|
|
5
|
-
s.version = "1.0.
|
|
5
|
+
s.version = "1.0.106" # Update to your package version
|
|
6
6
|
s.summary = "TTS for React Native."
|
|
7
7
|
s.description = <<-DESC
|
|
8
8
|
A React Native module for tts .
|
|
@@ -24,6 +24,7 @@ public class DaVoiceTTSBridge extends ReactContextBaseJavaModule {
|
|
|
24
24
|
|
|
25
25
|
private final DaVoiceTTSInterface tts;
|
|
26
26
|
private final ReactApplicationContext reactCtx;
|
|
27
|
+
final String TAG = "TTS";
|
|
27
28
|
|
|
28
29
|
public DaVoiceTTSBridge(ReactApplicationContext context) {
|
|
29
30
|
super(context);
|
|
@@ -198,36 +199,116 @@ public class DaVoiceTTSBridge extends ReactContextBaseJavaModule {
|
|
|
198
199
|
dst[f] = acc / channels;
|
|
199
200
|
}
|
|
200
201
|
}
|
|
201
|
-
|
|
202
|
-
@ReactMethod
|
|
202
|
+
|
|
203
|
+
// @ReactMethod
|
|
204
|
+
// public void playWav(String pathOrURL, boolean markAsLast, Promise promise) {
|
|
205
|
+
// Log.d(TAG, "playWav() called with: " + pathOrURL + " | markAsLast=" + markAsLast);
|
|
206
|
+
// try {
|
|
207
|
+
// if (isHttpOrHttps(pathOrURL)) {
|
|
208
|
+
// promise.reject("unsupported_url", "Remote URLs not supported. Download to a local file first.");
|
|
209
|
+
// return;
|
|
210
|
+
// }
|
|
211
|
+
|
|
212
|
+
// // --- NEW: handle require() assets from RN ---
|
|
213
|
+
// if (pathOrURL.startsWith("asset:/")) {
|
|
214
|
+
// Log.e(TAG, "Rejected remote URL: " + pathOrURL);
|
|
215
|
+
// String assetName = pathOrURL.replace("asset:/", "");
|
|
216
|
+
// Log.d(TAG, "Detected bundled asset: " + assetName);
|
|
217
|
+
// try (AssetFileDescriptor afd = getReactApplicationContext().getAssets().openFd(assetName)) {
|
|
218
|
+
// tts.playWav(afd, markAsLast); // overload that accepts AssetFileDescriptor
|
|
219
|
+
// promise.resolve("queued");
|
|
220
|
+
// return;
|
|
221
|
+
// } catch (IOException e) {
|
|
222
|
+
// promise.reject("asset_load_failed", "Unable to open bundled asset: " + e.getMessage(), e);
|
|
223
|
+
// return;
|
|
224
|
+
// }
|
|
225
|
+
// }
|
|
226
|
+
|
|
227
|
+
// String path = pathOrURL;
|
|
228
|
+
// if (isFileUrl(pathOrURL)) {
|
|
229
|
+
// Uri u = Uri.parse(pathOrURL);
|
|
230
|
+
// File f = new File(u.getPath());
|
|
231
|
+
// path = f.getAbsolutePath();
|
|
232
|
+
// }
|
|
233
|
+
// if (path == null) {
|
|
234
|
+
// promise.reject("bad_path", "Invalid file URL");
|
|
235
|
+
// return;
|
|
236
|
+
// }
|
|
237
|
+
// File f = new File(path);
|
|
238
|
+
// if (!f.exists()) {
|
|
239
|
+
// promise.reject("file_missing", "WAV file does not exist at path");
|
|
240
|
+
// return;
|
|
241
|
+
// }
|
|
242
|
+
// tts.playWav(f, markAsLast);
|
|
243
|
+
// promise.resolve("queued");
|
|
244
|
+
// } catch (Exception e) {
|
|
245
|
+
// promise.reject("PlayWavError", e.getMessage(), e);
|
|
246
|
+
// }
|
|
247
|
+
// }
|
|
248
|
+
// ADD
|
|
203
249
|
public void playWav(String pathOrURL, boolean markAsLast, Promise promise) {
|
|
250
|
+
final String TAG = "TTS";
|
|
251
|
+
Log.d(TAG, "playWav() called with: " + pathOrURL + " | markAsLast=" + markAsLast);
|
|
252
|
+
|
|
204
253
|
try {
|
|
205
254
|
if (isHttpOrHttps(pathOrURL)) {
|
|
255
|
+
Log.e(TAG, "Rejected remote URL: " + pathOrURL);
|
|
206
256
|
promise.reject("unsupported_url", "Remote URLs not supported. Download to a local file first.");
|
|
207
257
|
return;
|
|
208
258
|
}
|
|
259
|
+
|
|
260
|
+
// --- NEW: handle require() assets from RN ---
|
|
261
|
+
if (pathOrURL.startsWith("asset:/")) {
|
|
262
|
+
String assetName = pathOrURL.replace("asset:/", "");
|
|
263
|
+
Log.d(TAG, "Detected bundled asset: " + assetName);
|
|
264
|
+
try (AssetFileDescriptor afd = getReactApplicationContext().getAssets().openFd(assetName)) {
|
|
265
|
+
Log.d(TAG, "Successfully opened asset: " + assetName +
|
|
266
|
+
" | startOffset=" + afd.getStartOffset() +
|
|
267
|
+
" | length=" + afd.getLength());
|
|
268
|
+
tts.playWav(afd, markAsLast); // overload that accepts AssetFileDescriptor
|
|
269
|
+
Log.d(TAG, "Queued asset playback successfully.");
|
|
270
|
+
promise.resolve("queued");
|
|
271
|
+
return;
|
|
272
|
+
} catch (IOException e) {
|
|
273
|
+
Log.e(TAG, "Failed to open asset: " + assetName + " | " + e.getMessage(), e);
|
|
274
|
+
promise.reject("asset_load_failed", "Unable to open bundled asset: " + e.getMessage(), e);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// --- file:// handling ---
|
|
209
280
|
String path = pathOrURL;
|
|
210
281
|
if (isFileUrl(pathOrURL)) {
|
|
211
282
|
Uri u = Uri.parse(pathOrURL);
|
|
212
283
|
File f = new File(u.getPath());
|
|
213
284
|
path = f.getAbsolutePath();
|
|
285
|
+
Log.d(TAG, "Resolved file:// URL to path: " + path);
|
|
214
286
|
}
|
|
287
|
+
|
|
215
288
|
if (path == null) {
|
|
289
|
+
Log.e(TAG, "Invalid or null path provided");
|
|
216
290
|
promise.reject("bad_path", "Invalid file URL");
|
|
217
291
|
return;
|
|
218
292
|
}
|
|
293
|
+
|
|
219
294
|
File f = new File(path);
|
|
220
295
|
if (!f.exists()) {
|
|
296
|
+
Log.e(TAG, "File does not exist at path: " + path);
|
|
221
297
|
promise.reject("file_missing", "WAV file does not exist at path");
|
|
222
298
|
return;
|
|
223
299
|
}
|
|
300
|
+
|
|
301
|
+
Log.d(TAG, "Playing WAV from path: " + path + " (exists=" + f.exists() + ")");
|
|
224
302
|
tts.playWav(f, markAsLast);
|
|
303
|
+
Log.d(TAG, "Queued playback successfully for: " + path);
|
|
225
304
|
promise.resolve("queued");
|
|
305
|
+
|
|
226
306
|
} catch (Exception e) {
|
|
307
|
+
Log.e(TAG, "PlayWavError: " + e.getMessage(), e);
|
|
227
308
|
promise.reject("PlayWavError", e.getMessage(), e);
|
|
228
309
|
}
|
|
229
310
|
}
|
|
230
|
-
|
|
311
|
+
|
|
231
312
|
@ReactMethod
|
|
232
313
|
public void playBuffer(ReadableMap desc, Promise promise) {
|
|
233
314
|
try {
|
package/package.json
CHANGED
package/speech/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// speech/index.ts
|
|
2
2
|
import { NativeModules, NativeEventEmitter, DeviceEventEmitter, Platform } from 'react-native';
|
|
3
|
+
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
|
|
3
4
|
|
|
4
5
|
// If you use typed-array -> base64, Buffer is convenient (works in RN)
|
|
5
6
|
let toBase64: (u8: Uint8Array) => string;
|
|
@@ -406,18 +407,33 @@ private rewireListenersForMode() {
|
|
|
406
407
|
}
|
|
407
408
|
|
|
408
409
|
// --- NEW: TTS passthroughs for external audio ---
|
|
410
|
+
/** Queue a WAV file (local path, file:// URL, or require() asset). */
|
|
411
|
+
async playWav(pathOrURL: string | number, markAsLast = true) {
|
|
412
|
+
// NEW: resolve require() assets to actual file path/URI
|
|
413
|
+
const asset = resolveAssetSource(pathOrURL);
|
|
414
|
+
const realPath = asset?.uri ?? pathOrURL; // fallback keeps string path intact
|
|
409
415
|
|
|
410
|
-
/** Queue a WAV file (local path or file:// URL). Routed via AEC path, queued with speak(). */
|
|
411
|
-
async playWav(pathOrURL: string, markAsLast = true) {
|
|
412
416
|
// Prefer unified iOS bridge if present
|
|
413
417
|
if (Platform.OS === 'ios' && NativeSpeech?.playWav) {
|
|
414
|
-
return NativeSpeech.playWav(
|
|
418
|
+
return NativeSpeech.playWav(realPath, markAsLast);
|
|
415
419
|
}
|
|
420
|
+
|
|
416
421
|
// Fallback: direct TTS bridge (Android + iOS fallback)
|
|
417
422
|
if (!NativeTTS?.playWav) throw new Error('playWav not available on this platform.');
|
|
418
|
-
return NativeTTS.playWav(
|
|
423
|
+
return NativeTTS.playWav(realPath, markAsLast);
|
|
419
424
|
}
|
|
420
425
|
|
|
426
|
+
// /** Queue a WAV file (local path or file:// URL). Routed via AEC path, queued with speak(). */
|
|
427
|
+
// async playWav(pathOrURL: string, markAsLast = true) {
|
|
428
|
+
// // Prefer unified iOS bridge if present
|
|
429
|
+
// if (Platform.OS === 'ios' && NativeSpeech?.playWav) {
|
|
430
|
+
// return NativeSpeech.playWav(pathOrURL, markAsLast);
|
|
431
|
+
// }
|
|
432
|
+
// // Fallback: direct TTS bridge (Android + iOS fallback)
|
|
433
|
+
// if (!NativeTTS?.playWav) throw new Error('playWav not available on this platform.');
|
|
434
|
+
// return NativeTTS.playWav(pathOrURL, markAsLast);
|
|
435
|
+
// }
|
|
436
|
+
|
|
421
437
|
/**
|
|
422
438
|
* Convenience: queue a typed array (Int16Array | Float32Array | ArrayBuffer) as PCM.
|
|
423
439
|
* We’ll base64 it and pass through to native with the right metadata.
|