@focus8/expo-acapela-tts 0.1.1 → 0.1.3
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/android/src/main/java/expo/modules/acapelatts/ExpoAcapelaTtsModule.kt +27 -12
- package/build/ExpoAcapelaTtsModule.android.d.ts +2 -0
- package/build/ExpoAcapelaTtsModule.android.d.ts.map +1 -1
- package/build/ExpoAcapelaTtsModule.android.js.map +1 -1
- package/build/ExpoAcapelaTtsModule.d.ts +2 -0
- package/build/ExpoAcapelaTtsModule.d.ts.map +1 -1
- package/build/ExpoAcapelaTtsModule.js +2 -0
- package/build/ExpoAcapelaTtsModule.js.map +1 -1
- package/package.json +1 -1
- package/src/ExpoAcapelaTtsModule.android.ts +2 -0
- package/src/ExpoAcapelaTtsModule.ts +2 -0
|
@@ -12,17 +12,13 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
|
|
|
12
12
|
private var tts: acattsandroid? = null
|
|
13
13
|
private var isInitialized = false
|
|
14
14
|
private var currentVoice: String? = null
|
|
15
|
+
private var voicePaths = mutableListOf("/system/media/voices", "/data/media/voices")
|
|
16
|
+
private var licenseUserId: Long? = null
|
|
17
|
+
private var licensePassword: Long? = null
|
|
18
|
+
private var licenseKey: String? = null
|
|
15
19
|
|
|
16
20
|
companion object {
|
|
17
21
|
private const val TAG = "ExpoAcapelaTts"
|
|
18
|
-
private val VOICE_PATHS = arrayOf("/system/media/voices", "/data/media/voices")
|
|
19
|
-
|
|
20
|
-
private const val LICENSE_USER_ID = 0x34307771L
|
|
21
|
-
private const val LICENSE_PASSWORD = 0x0008d44fL
|
|
22
|
-
private const val LICENSE_KEY = "\"1976 0 qw04 #EVALUATION#Focus8\"\n" +
|
|
23
|
-
"R%NUNVGz28KZdGZestTLeuatIwSRJoV8wn33qep6qR##\n" +
|
|
24
|
-
"VOO8rYtC9QJpPfoX!8wlLrI@JXk3KnFJ%fhyL4AlArB!xoRq\n" +
|
|
25
|
-
"UCNfz!@aiT9Sp88aLHnq\n"
|
|
26
22
|
|
|
27
23
|
private var nativeLibLoaded = false
|
|
28
24
|
|
|
@@ -48,11 +44,11 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
|
|
|
48
44
|
return@Function false
|
|
49
45
|
}
|
|
50
46
|
try {
|
|
51
|
-
val available =
|
|
47
|
+
val available = voicePaths.any { path ->
|
|
52
48
|
val dir = File(path)
|
|
53
49
|
dir.exists() && dir.isDirectory && (dir.list()?.isNotEmpty() == true)
|
|
54
50
|
}
|
|
55
|
-
logInfo("isAvailable: $available (paths: ${
|
|
51
|
+
logInfo("isAvailable: $available (paths: ${voicePaths.joinToString()})")
|
|
56
52
|
available
|
|
57
53
|
} catch (e: Exception) {
|
|
58
54
|
logError("isAvailable check failed", e)
|
|
@@ -60,6 +56,20 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
|
|
|
60
56
|
}
|
|
61
57
|
}
|
|
62
58
|
|
|
59
|
+
Function("addVoicePath") { path: String ->
|
|
60
|
+
if (!voicePaths.contains(path)) {
|
|
61
|
+
voicePaths.add(path)
|
|
62
|
+
logInfo("Added voice path: $path")
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
Function("setLicense") { userId: Long, password: Long, key: String ->
|
|
67
|
+
licenseUserId = userId
|
|
68
|
+
licensePassword = password
|
|
69
|
+
licenseKey = key
|
|
70
|
+
logInfo("License set")
|
|
71
|
+
}
|
|
72
|
+
|
|
63
73
|
AsyncFunction("initializeAsync") {
|
|
64
74
|
if (!nativeLibLoaded) {
|
|
65
75
|
logWarning("Cannot initialize: native library not loaded")
|
|
@@ -71,6 +81,11 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
|
|
|
71
81
|
return@AsyncFunction true
|
|
72
82
|
}
|
|
73
83
|
|
|
84
|
+
if (licenseUserId == null || licensePassword == null || licenseKey == null) {
|
|
85
|
+
logWarning("Cannot initialize: license not set. Call setLicense() first.")
|
|
86
|
+
return@AsyncFunction false
|
|
87
|
+
}
|
|
88
|
+
|
|
74
89
|
try {
|
|
75
90
|
val context = appContext.reactContext ?: run {
|
|
76
91
|
logWarning("ReactContext not available")
|
|
@@ -79,7 +94,7 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
|
|
|
79
94
|
|
|
80
95
|
tts = acattsandroid(context, this@ExpoAcapelaTtsModule, null)
|
|
81
96
|
tts!!.setLog(true)
|
|
82
|
-
tts!!.setLicense(
|
|
97
|
+
tts!!.setLicense(licenseUserId!!, licensePassword!!, licenseKey)
|
|
83
98
|
|
|
84
99
|
val version = tts!!.version
|
|
85
100
|
logInfo("Initialized, SDK version: $version")
|
|
@@ -101,7 +116,7 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
|
|
|
101
116
|
}
|
|
102
117
|
|
|
103
118
|
try {
|
|
104
|
-
val voiceDirPaths =
|
|
119
|
+
val voiceDirPaths = voicePaths.toTypedArray()
|
|
105
120
|
val voicesList = tts!!.getVoicesList(voiceDirPaths) ?: emptyArray()
|
|
106
121
|
logInfo("Found ${voicesList.size} voices")
|
|
107
122
|
|
|
@@ -2,6 +2,8 @@ import { NativeModule } from 'expo';
|
|
|
2
2
|
import { AcapelaVoice, ExpoAcapelaTtsModuleEvents } from './ExpoAcapelaTts.types';
|
|
3
3
|
declare class ExpoAcapelaTtsModule extends NativeModule<ExpoAcapelaTtsModuleEvents> {
|
|
4
4
|
isAvailable(): boolean;
|
|
5
|
+
addVoicePath(path: string): void;
|
|
6
|
+
setLicense(userId: number, password: number, key: string): void;
|
|
5
7
|
initializeAsync(): Promise<boolean>;
|
|
6
8
|
getVoicesAsync(): Promise<AcapelaVoice[]>;
|
|
7
9
|
loadVoiceAsync(voiceName: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoAcapelaTtsModule.android.d.ts","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AAEzD,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC3B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,OAAO,oBAAqB,SAAQ,YAAY,CAAC,0BAA0B,CAAC;IACjF,WAAW,IAAI,OAAO;IACtB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IACnC,cAAc,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IACzC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IACnD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACzC,IAAI,IAAI,IAAI;IACZ,UAAU,IAAI,OAAO;IACrB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC7B,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAClC,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CAC/B;;AAED,wBAA2E"}
|
|
1
|
+
{"version":3,"file":"ExpoAcapelaTtsModule.android.d.ts","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AAEzD,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC3B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,OAAO,oBAAqB,SAAQ,YAAY,CAAC,0BAA0B,CAAC;IACjF,WAAW,IAAI,OAAO;IACtB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAChC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAC/D,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IACnC,cAAc,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IACzC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IACnD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACzC,IAAI,IAAI,IAAI;IACZ,UAAU,IAAI,OAAO;IACrB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC7B,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAClC,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CAC/B;;AAED,wBAA2E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoAcapelaTtsModule.android.js","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ExpoAcapelaTtsModule.android.js","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAuBzD,eAAe,mBAAmB,CAAuB,gBAAgB,CAAC,CAAC","sourcesContent":["import { NativeModule, requireNativeModule } from 'expo';\n\nimport {\n AcapelaVoice,\n ExpoAcapelaTtsModuleEvents,\n} from './ExpoAcapelaTts.types';\n\ndeclare class ExpoAcapelaTtsModule extends NativeModule<ExpoAcapelaTtsModuleEvents> {\n isAvailable(): boolean;\n addVoicePath(path: string): void;\n setLicense(userId: number, password: number, key: string): void;\n initializeAsync(): Promise<boolean>;\n getVoicesAsync(): Promise<AcapelaVoice[]>;\n loadVoiceAsync(voiceName: string): Promise<boolean>;\n speakAsync(text: string): Promise<number>;\n stop(): void;\n isSpeaking(): boolean;\n setSpeechRate(rate: number): void;\n setPitch(pitch: number): void;\n setAudioBoost(boost: number): void;\n shutdownAsync(): Promise<void>;\n}\n\nexport default requireNativeModule<ExpoAcapelaTtsModule>('ExpoAcapelaTts');\n"]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
declare const _default: {
|
|
2
2
|
isAvailable(): boolean;
|
|
3
|
+
addVoicePath(_path: string): void;
|
|
4
|
+
setLicense(_userId: number, _password: number, _key: string): void;
|
|
3
5
|
initializeAsync(): Promise<boolean>;
|
|
4
6
|
getVoicesAsync(): Promise<never[]>;
|
|
5
7
|
loadVoiceAsync(_voiceName: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoAcapelaTtsModule.d.ts","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.ts"],"names":[],"mappings":";mBAEiB,OAAO;
|
|
1
|
+
{"version":3,"file":"ExpoAcapelaTtsModule.d.ts","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.ts"],"names":[],"mappings":";mBAEiB,OAAO;wBAGF,MAAM;wBACN,MAAM,aAAa,MAAM,QAAQ,MAAM;uBAClC,OAAO,CAAC,OAAO,CAAC;;+BAMR,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;sBAGlC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;;kBAIlC,OAAO;yBAGA,MAAM;qBACV,MAAM;0BACD,MAAM;;;;;;;AAxB9B,wBA8BE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoAcapelaTtsModule.js","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,eAAe;IACb,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,eAAe;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,cAAc;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,CAAC,cAAc,CAAC,UAAkB;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,KAAa;QAC5B,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IACD,IAAI,KAAI,CAAC;IACT,UAAU;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IACD,aAAa,CAAC,KAAa,IAAG,CAAC;IAC/B,QAAQ,CAAC,MAAc,IAAG,CAAC;IAC3B,aAAa,CAAC,MAAc,IAAG,CAAC;IAChC,KAAK,CAAC,aAAa,KAAI,CAAC;IACxB,WAAW;QACT,OAAO,EAAE,MAAM,KAAI,CAAC,EAAE,CAAC;IACzB,CAAC;IACD,eAAe,KAAI,CAAC;CACrB,CAAC","sourcesContent":["// No-op stub for non-Android platforms\nexport default {\n isAvailable(): boolean {\n return false;\n },\n async initializeAsync(): Promise<boolean> {\n return false;\n },\n async getVoicesAsync() {\n return [];\n },\n async loadVoiceAsync(_voiceName: string): Promise<boolean> {\n return false;\n },\n async speakAsync(_text: string): Promise<number> {\n return -1;\n },\n stop() {},\n isSpeaking(): boolean {\n return false;\n },\n setSpeechRate(_rate: number) {},\n setPitch(_pitch: number) {},\n setAudioBoost(_boost: number) {},\n async shutdownAsync() {},\n addListener() {\n return { remove() {} };\n },\n removeListeners() {},\n};\n"]}
|
|
1
|
+
{"version":3,"file":"ExpoAcapelaTtsModule.js","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,eAAe;IACb,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IACD,YAAY,CAAC,KAAa,IAAG,CAAC;IAC9B,UAAU,CAAC,OAAe,EAAE,SAAiB,EAAE,IAAY,IAAG,CAAC;IAC/D,KAAK,CAAC,eAAe;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,cAAc;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,CAAC,cAAc,CAAC,UAAkB;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,KAAa;QAC5B,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IACD,IAAI,KAAI,CAAC;IACT,UAAU;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IACD,aAAa,CAAC,KAAa,IAAG,CAAC;IAC/B,QAAQ,CAAC,MAAc,IAAG,CAAC;IAC3B,aAAa,CAAC,MAAc,IAAG,CAAC;IAChC,KAAK,CAAC,aAAa,KAAI,CAAC;IACxB,WAAW;QACT,OAAO,EAAE,MAAM,KAAI,CAAC,EAAE,CAAC;IACzB,CAAC;IACD,eAAe,KAAI,CAAC;CACrB,CAAC","sourcesContent":["// No-op stub for non-Android platforms\nexport default {\n isAvailable(): boolean {\n return false;\n },\n addVoicePath(_path: string) {},\n setLicense(_userId: number, _password: number, _key: string) {},\n async initializeAsync(): Promise<boolean> {\n return false;\n },\n async getVoicesAsync() {\n return [];\n },\n async loadVoiceAsync(_voiceName: string): Promise<boolean> {\n return false;\n },\n async speakAsync(_text: string): Promise<number> {\n return -1;\n },\n stop() {},\n isSpeaking(): boolean {\n return false;\n },\n setSpeechRate(_rate: number) {},\n setPitch(_pitch: number) {},\n setAudioBoost(_boost: number) {},\n async shutdownAsync() {},\n addListener() {\n return { remove() {} };\n },\n removeListeners() {},\n};\n"]}
|
package/package.json
CHANGED
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
|
|
8
8
|
declare class ExpoAcapelaTtsModule extends NativeModule<ExpoAcapelaTtsModuleEvents> {
|
|
9
9
|
isAvailable(): boolean;
|
|
10
|
+
addVoicePath(path: string): void;
|
|
11
|
+
setLicense(userId: number, password: number, key: string): void;
|
|
10
12
|
initializeAsync(): Promise<boolean>;
|
|
11
13
|
getVoicesAsync(): Promise<AcapelaVoice[]>;
|
|
12
14
|
loadVoiceAsync(voiceName: string): Promise<boolean>;
|