react-native-davoice-tts 1.0.233 → 1.0.235
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 +1 -1
- package/android/src/main/AndroidManifest.xml +3 -1
- package/android/src/main/java/com/davoice/tts/rn/DaVoiceTTSBridge.java +38 -21
- package/ios/SpeechBridge/SpeechBridge.m +71 -13
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64/DavoiceTTS.framework/DavoiceTTS +0 -0
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios.abi.json +2487 -2487
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios.private.swiftinterface +12 -12
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios.swiftinterface +12 -12
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/DavoiceTTS +0 -0
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios-simulator.abi.json +2851 -2851
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +20 -20
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios-simulator.swiftinterface +20 -20
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/x86_64-apple-ios-simulator.abi.json +2851 -2851
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +20 -20
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +20 -20
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/_CodeSignature/CodeDirectory +0 -0
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/_CodeSignature/CodeRequirements-1 +0 -0
- package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/_CodeSignature/CodeResources +24 -24
- package/package.json +1 -1
- package/speech/index.ts +29 -7
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.108" # 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 .
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
|
6
6
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
|
|
7
7
|
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
|
8
|
-
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
|
|
9
8
|
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
|
|
10
9
|
|
|
10
|
+
<!-- Place in the app -->
|
|
11
|
+
<!-- <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/> -->
|
|
12
|
+
|
|
11
13
|
</manifest>
|
|
12
14
|
|
|
@@ -17,6 +17,12 @@ import java.nio.ByteBuffer;
|
|
|
17
17
|
import java.nio.ByteOrder;
|
|
18
18
|
import java.util.Locale;
|
|
19
19
|
import android.util.Base64;
|
|
20
|
+
import android.media.MediaPlayer;
|
|
21
|
+
|
|
22
|
+
import android.util.Log;
|
|
23
|
+
import android.content.res.AssetFileDescriptor;
|
|
24
|
+
import java.io.IOException;
|
|
25
|
+
|
|
20
26
|
|
|
21
27
|
import com.davoice.tts.DaVoiceTTSInterface;
|
|
22
28
|
|
|
@@ -246,34 +252,45 @@ public class DaVoiceTTSBridge extends ReactContextBaseJavaModule {
|
|
|
246
252
|
// }
|
|
247
253
|
// }
|
|
248
254
|
// ADD
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
255
|
+
|
|
256
|
+
@ReactMethod
|
|
257
|
+
public void playWav(String pathOrURL, boolean markAsLast, Promise promise) {
|
|
258
|
+
final String TAG = "TTS";
|
|
259
|
+
Log.d(TAG, "playWav() called with: " + pathOrURL + " | markAsLast=" + markAsLast);
|
|
260
|
+
// 1️⃣ Handle RN dev server URLs (http://localhost:8081/...) by downloading them to cache first
|
|
261
|
+
try {
|
|
254
262
|
if (isHttpOrHttps(pathOrURL)) {
|
|
255
|
-
Log.
|
|
256
|
-
|
|
257
|
-
|
|
263
|
+
Log.w(TAG, "Downloading asset from dev server: " + pathOrURL);
|
|
264
|
+
java.net.URL url = new java.net.URL(pathOrURL);
|
|
265
|
+
java.io.InputStream in = url.openStream();
|
|
266
|
+
File out = new File(reactCtx.getCacheDir(), "rn_asset_" + System.currentTimeMillis() + ".wav");
|
|
267
|
+
try (FileOutputStream fos = new FileOutputStream(out)) {
|
|
268
|
+
byte[] buf = new byte[8192];
|
|
269
|
+
int len;
|
|
270
|
+
while ((len = in.read(buf)) != -1) fos.write(buf, 0, len);
|
|
271
|
+
}
|
|
272
|
+
in.close();
|
|
273
|
+
Log.d(TAG, "Downloaded asset to: " + out.getAbsolutePath());
|
|
274
|
+
tts.playWav(out, markAsLast);
|
|
275
|
+
promise.resolve("queued");
|
|
276
|
+
return;
|
|
258
277
|
}
|
|
259
278
|
|
|
260
|
-
//
|
|
279
|
+
// 2️⃣ Handle require() assets (resolved as "asset:/...") via Android asset manager
|
|
261
280
|
if (pathOrURL.startsWith("asset:/")) {
|
|
262
281
|
String assetName = pathOrURL.replace("asset:/", "");
|
|
263
282
|
Log.d(TAG, "Detected bundled asset: " + assetName);
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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;
|
|
283
|
+
File tmp = new File(reactCtx.getCacheDir(), "asset_" + System.currentTimeMillis() + ".wav");
|
|
284
|
+
try (java.io.InputStream in = reactCtx.getAssets().open(assetName);
|
|
285
|
+
FileOutputStream out = new FileOutputStream(tmp)) {
|
|
286
|
+
byte[] buf = new byte[8192];
|
|
287
|
+
int len;
|
|
288
|
+
while ((len = in.read(buf)) != -1) out.write(buf, 0, len);
|
|
276
289
|
}
|
|
290
|
+
Log.d(TAG, "Copied asset to: " + tmp.getAbsolutePath());
|
|
291
|
+
tts.playWav(tmp, markAsLast);
|
|
292
|
+
promise.resolve("queued");
|
|
293
|
+
return;
|
|
277
294
|
}
|
|
278
295
|
|
|
279
296
|
// --- file:// handling ---
|
|
@@ -332,27 +332,85 @@ RCT_EXPORT_METHOD(playWav:(NSString *)pathOrURL
|
|
|
332
332
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
333
333
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
334
334
|
{
|
|
335
|
-
if (!self.tts) {
|
|
335
|
+
if (!self.tts) {
|
|
336
|
+
reject(@"no_tts", @"Call initAll first", nil);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (pathOrURL == nil || pathOrURL.length == 0) {
|
|
341
|
+
reject(@"bad_path", @"Empty pathOrURL", nil);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
336
344
|
|
|
337
|
-
NSURL *
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
345
|
+
NSURL *fileURL = nil;
|
|
346
|
+
|
|
347
|
+
// 1️⃣ Handle http(s) URLs — download to temporary file first
|
|
348
|
+
if ([pathOrURL hasPrefix:@"http://"] || [pathOrURL hasPrefix:@"https://"]) {
|
|
349
|
+
NSLog(@"[TTS] Downloading asset from URL: %@", pathOrURL);
|
|
350
|
+
NSURL *remoteURL = [NSURL URLWithString:pathOrURL];
|
|
351
|
+
if (!remoteURL) {
|
|
352
|
+
reject(@"bad_url", @"Invalid remote URL", nil);
|
|
343
353
|
return;
|
|
344
354
|
}
|
|
345
|
-
|
|
346
|
-
|
|
355
|
+
|
|
356
|
+
NSData *data = [NSData dataWithContentsOfURL:remoteURL];
|
|
357
|
+
if (!data) {
|
|
358
|
+
reject(@"download_failed", @"Failed to download remote asset", nil);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
NSString *tempName = [NSString stringWithFormat:@"rn_asset_%f.wav", [[NSDate date] timeIntervalSince1970]];
|
|
363
|
+
NSString *tempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:tempName];
|
|
364
|
+
if (![data writeToFile:tempPath atomically:YES]) {
|
|
365
|
+
reject(@"write_failed", @"Failed to write temporary file", nil);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
fileURL = [NSURL fileURLWithPath:tempPath];
|
|
369
|
+
NSLog(@"[TTS] Downloaded to temp file: %@", tempPath);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// 2️⃣ Handle bundled asset:/ paths (copied from main bundle)
|
|
373
|
+
else if ([pathOrURL hasPrefix:@"asset:/"]) {
|
|
374
|
+
NSString *assetName = [pathOrURL stringByReplacingOccurrencesOfString:@"asset:/" withString:@""];
|
|
375
|
+
NSLog(@"[TTS] Detected bundled asset: %@", assetName);
|
|
376
|
+
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:[assetName stringByDeletingPathExtension]
|
|
377
|
+
ofType:[assetName pathExtension]];
|
|
378
|
+
if (!bundlePath) {
|
|
379
|
+
reject(@"asset_missing", [NSString stringWithFormat:@"Asset not found in bundle: %@", assetName], nil);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
// Copy to temp file so we have a writable/accessible URL
|
|
383
|
+
NSString *tempName = [NSString stringWithFormat:@"asset_%f.wav", [[NSDate date] timeIntervalSince1970]];
|
|
384
|
+
NSString *tempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:tempName];
|
|
385
|
+
NSError *copyError = nil;
|
|
386
|
+
[[NSFileManager defaultManager] copyItemAtPath:bundlePath toPath:tempPath error:©Error];
|
|
387
|
+
if (copyError) {
|
|
388
|
+
reject(@"asset_copy_failed", copyError.localizedDescription, copyError);
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
fileURL = [NSURL fileURLWithPath:tempPath];
|
|
392
|
+
NSLog(@"[TTS] Copied bundled asset to temp: %@", tempPath);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// 3️⃣ Handle file:// URLs
|
|
396
|
+
else if ([pathOrURL hasPrefix:@"file://"]) {
|
|
397
|
+
fileURL = [NSURL URLWithString:pathOrURL];
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// 4️⃣ Otherwise assume direct local path
|
|
401
|
+
else {
|
|
402
|
+
fileURL = [NSURL fileURLWithPath:pathOrURL];
|
|
347
403
|
}
|
|
348
404
|
|
|
349
|
-
|
|
350
|
-
|
|
405
|
+
// 5️⃣ Verify existence
|
|
406
|
+
if (!fileURL || ![[NSFileManager defaultManager] fileExistsAtPath:fileURL.path]) {
|
|
407
|
+
reject(@"file_missing", [NSString stringWithFormat:@"File missing: %@", fileURL.path], nil);
|
|
351
408
|
return;
|
|
352
409
|
}
|
|
353
410
|
|
|
354
|
-
//
|
|
355
|
-
[
|
|
411
|
+
// 6️⃣ Play through TTS engine (queued)
|
|
412
|
+
NSLog(@"[TTS] Playing file via DaVoiceTTS: %@", fileURL.path);
|
|
413
|
+
[self.tts playWav:fileURL markAsLastUtterance:markAsLast.boolValue];
|
|
356
414
|
resolve(@"queued");
|
|
357
415
|
}
|
|
358
416
|
|