@readium/speech 0.1.0
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/LICENSE +28 -0
- package/README.md +144 -0
- package/build/WebSpeech/TmpNavigator.d.ts +39 -0
- package/build/WebSpeech/WebSpeechVoiceManager.d.ts +232 -0
- package/build/WebSpeech/index.d.ts +4 -0
- package/build/WebSpeech/webSpeechEngine.d.ts +67 -0
- package/build/WebSpeech/webSpeechEngineProvider.d.ts +11 -0
- package/build/ar-BYWkyZgW.cjs +1 -0
- package/build/ar-CJhBAgKq.js +13 -0
- package/build/bg-D7xe9YTl.cjs +1 -0
- package/build/bg-JvP4LoOT.js +13 -0
- package/build/bho-CpuLBMN3.js +13 -0
- package/build/bho-UB6aO8oz.cjs +1 -0
- package/build/bn-84u93pMd.js +13 -0
- package/build/bn-boRZ2pl5.cjs +1 -0
- package/build/ca-DdScTbex.js +13 -0
- package/build/ca-DkC8kSJ8.cjs +1 -0
- package/build/cmn-BsNLjyA4.cjs +1 -0
- package/build/cmn-Dd1zrvTE.js +13 -0
- package/build/cs-CDMne0uc.js +13 -0
- package/build/cs-p05r08p7.cjs +1 -0
- package/build/da-crefCup9.cjs +1 -0
- package/build/da-oFf4cHgj.js +13 -0
- package/build/de-Bjgc3bVq.js +13 -0
- package/build/de-xoW-RuhZ.cjs +1 -0
- package/build/el-C025sTug.cjs +1 -0
- package/build/el-FkKIcghI.js +13 -0
- package/build/en-DCQHxNny.js +13 -0
- package/build/en-Gmh32VcD.cjs +1 -0
- package/build/engine.d.ts +25 -0
- package/build/es-CDjjngpC.js +13 -0
- package/build/es-tgHiWsyf.cjs +1 -0
- package/build/eu-DxWirHU-.js +13 -0
- package/build/eu-uq15ZgwW.cjs +1 -0
- package/build/fa-CHOnwiFr.cjs +1 -0
- package/build/fa-CTVUniYi.js +13 -0
- package/build/fi-Bxlno6Zi.cjs +1 -0
- package/build/fi-Do6QFzRv.js +13 -0
- package/build/fr-B5-P9o29.js +13 -0
- package/build/fr-yAth5-FC.cjs +1 -0
- package/build/generated/language-metadata.d.ts +7 -0
- package/build/gl-BEgzCAO0.cjs +1 -0
- package/build/gl-DqSXeC_F.js +13 -0
- package/build/he-B-CTHJPL.cjs +1 -0
- package/build/he-CpyNwgaH.js +13 -0
- package/build/hi-C0yUjV1-.cjs +1 -0
- package/build/hi-CeOBacbl.js +13 -0
- package/build/hr-CSpU18l6.js +13 -0
- package/build/hr-CZvFOcdo.cjs +1 -0
- package/build/hu-_2PInItj.cjs +1 -0
- package/build/hu-oONHmpR6.js +13 -0
- package/build/id-BROcb7-t.cjs +1 -0
- package/build/id-BpZuB5Iw.js +13 -0
- package/build/index.cjs +27 -0
- package/build/index.d.ts +7 -0
- package/build/index.js +2801 -0
- package/build/it-Bmc8Ycff.cjs +1 -0
- package/build/it-CM4X84UA.js +13 -0
- package/build/ja-B8t6WOeg.cjs +1 -0
- package/build/ja-e-iw3c4_.js +13 -0
- package/build/kk-BdLCAb2s.js +13 -0
- package/build/kk-DskO1CW8.cjs +1 -0
- package/build/kn-BYRvouO5.js +13 -0
- package/build/kn-Cy3NH6na.cjs +1 -0
- package/build/ko-CZdQzppZ.cjs +1 -0
- package/build/ko-EIouMDK1.js +13 -0
- package/build/mr-9hGqBYlV.cjs +1 -0
- package/build/mr-DN-hwEV1.js +13 -0
- package/build/ms-B5E3oaWE.js +13 -0
- package/build/ms-DzpBxNFZ.cjs +1 -0
- package/build/navigator.d.ts +30 -0
- package/build/nb-BQfw9EEH.cjs +1 -0
- package/build/nb-DOw05HBh.js +13 -0
- package/build/nl-CEydw4A9.js +13 -0
- package/build/nl-CyM0R4Gr.cjs +1 -0
- package/build/pl-Da8XOMa1.cjs +1 -0
- package/build/pl-Ivj_eAP7.js +13 -0
- package/build/provider.d.ts +9 -0
- package/build/pt-BPEGqRmW.js +13 -0
- package/build/pt-tubyvYaM.cjs +1 -0
- package/build/ro-BQ617SOx.js +13 -0
- package/build/ro-C-rXDfuM.cjs +1 -0
- package/build/ru-DJocRaDd.cjs +1 -0
- package/build/ru-Dieeph4H.js +13 -0
- package/build/sk-BvpojIXp.cjs +1 -0
- package/build/sk-pEiOt4GQ.js +13 -0
- package/build/sl-D0X3JKvQ.cjs +1 -0
- package/build/sl-Z6jWAR8J.js +13 -0
- package/build/sv-4lEgrHda.cjs +1 -0
- package/build/sv-BT09piiZ.js +13 -0
- package/build/ta-B0YMGW5q.js +13 -0
- package/build/ta-CyeVPdIs.cjs +1 -0
- package/build/te-DqWIZZxL.cjs +1 -0
- package/build/te-ax-HNsAY.js +13 -0
- package/build/th-BcoSVZAp.cjs +1 -0
- package/build/th-C7Dbxwoz.js +13 -0
- package/build/tr-BuafNhfw.cjs +1 -0
- package/build/tr-mipEichO.js +13 -0
- package/build/uk-CHdx7DHz.js +13 -0
- package/build/uk-DkXNxnD9.cjs +1 -0
- package/build/utils/features.d.ts +23 -0
- package/build/utils/language.d.ts +6 -0
- package/build/utils/patches.d.ts +11 -0
- package/build/utterance.d.ts +6 -0
- package/build/vi-Ct2avSE6.cjs +1 -0
- package/build/vi-DrlcEwAD.js +13 -0
- package/build/voices/filters.d.ts +5 -0
- package/build/voices/languages.d.ts +44 -0
- package/build/voices/localized.d.ts +20 -0
- package/build/voices/packages.d.ts +2 -0
- package/build/voices/sorting.d.ts +7 -0
- package/build/voices/types.d.ts +87 -0
- package/build/voices/voiceDuplicates.d.ts +19 -0
- package/build/wuu-C6uQvT6g.js +13 -0
- package/build/wuu-DnwGQ6c-.cjs +1 -0
- package/build/yue-CFroa59o.js +13 -0
- package/build/yue-j9Y48sR-.cjs +1 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, Readium Foundation
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Readium Speech
|
|
2
|
+
|
|
3
|
+
Readium Speech is a TypeScript library for implementing a read aloud feature with Web technologies. It follows [best practices](https://github.com/HadrienGardeur/read-aloud-best-practices) gathered through interviews with members of the digital publishing industry.
|
|
4
|
+
|
|
5
|
+
While this project is still in a very early stage, it is meant to power the read aloud feature for two different Readium projects: [Readium Web](https://readium.org/guided-navigation) and [Thorium](https://thorium.edrlab.org/).
|
|
6
|
+
|
|
7
|
+
Readium Speech was spun out as a separate project in order to facilitate its integration as a shared component, but also because of its potential outside of the realm of ebook reading apps.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
* Extracting [Guided Navigation objects](https://readium.org/guided-navigation) from a document (or a fragment of a document)
|
|
12
|
+
* Generating utterances from these Guided Navigation objects
|
|
13
|
+
* Processing utterances (prepending/appending text to utterances based on context, pronunciation through SSML/PLS…)
|
|
14
|
+
* Voice selection
|
|
15
|
+
* TTS playback
|
|
16
|
+
* Highlighting
|
|
17
|
+
|
|
18
|
+
## Current focus
|
|
19
|
+
|
|
20
|
+
For our initial work on this project, we focused on voice selection based on [recommended voices](https://github.com/HadrienGardeur/web-speech-recommended-voices).
|
|
21
|
+
|
|
22
|
+
The outline of this work has been explored in a [GitHub discussion](https://github.com/HadrienGardeur/web-speech-recommended-voices/discussions/9) and through a [best practices document](https://github.com/HadrienGardeur/read-aloud-best-practices/blob/main/voice-selection.md).
|
|
23
|
+
|
|
24
|
+
In the second phase, we focused on implementing a WebSpeech API-based solution with an architecture designed for future extensibility:
|
|
25
|
+
|
|
26
|
+
- **Engine Layer**: Core TTS functionality through `ReadiumSpeechPlaybackEngine`
|
|
27
|
+
- **Navigator Layer**: Content and playback management via (a temporary) `ReadiumSpeechNavigator`
|
|
28
|
+
- **Current Implementation**: WebSpeech API with cross-browser compatibility
|
|
29
|
+
- **Future-Proof Design**: Architecture prepared for additional TTS service adapters
|
|
30
|
+
|
|
31
|
+
Key features include advanced voice selection, cross-browser playback control, flexible content loading, and comprehensive event handling for UI feedback. The architecture is designed to be extensible for different TTS backends while maintaining TypeScript-first development practices.
|
|
32
|
+
|
|
33
|
+
## Demos
|
|
34
|
+
|
|
35
|
+
Two live demos are available:
|
|
36
|
+
|
|
37
|
+
1. [Voice selection with playback demo](https://readium.org/speech/demo)
|
|
38
|
+
2. [In-context demo](https://readium.org/speech/demo/article)
|
|
39
|
+
|
|
40
|
+
The first demo showcases the following features:
|
|
41
|
+
|
|
42
|
+
- fetching a list of all available languages, translating them to the user's locale and sorting them based on these translations
|
|
43
|
+
- returning a list of voices for a given language, grouped by region and sorted based on quality
|
|
44
|
+
- filtering languages and voices based on gender and offline availability
|
|
45
|
+
- using embedded test utterances to demo voices
|
|
46
|
+
- using the current Navigator for playback control
|
|
47
|
+
|
|
48
|
+
The second demo focuses on in-context reading with seamless voice selection (grouped by region and sorted based on quality), and playback control, providing an optional read-along experience that integrates naturally with the content.
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
Install the package using npm:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install @readium/speech
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or using yarn:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
yarn add @readium/speech
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Quick Start
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { WebSpeechVoiceManager, WebSpeechReadAloudNavigator } from "@readium/speech";
|
|
68
|
+
|
|
69
|
+
// Initialize voice manager
|
|
70
|
+
const voiceManager = await WebSpeechVoiceManager.initialize({
|
|
71
|
+
languages: ["en", "fr", "es"] // List of languages to fetch voices for
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Get the best available voice for a specific language
|
|
75
|
+
const voice = await voiceManager.getDefaultVoice("en-US");
|
|
76
|
+
|
|
77
|
+
// Create a navigator instance
|
|
78
|
+
const navigator = new WebSpeechReadAloudNavigator();
|
|
79
|
+
await navigator.setVoice(voice);
|
|
80
|
+
|
|
81
|
+
// Handle playback events
|
|
82
|
+
navigator.on("play", () => console.log("Playback started"));
|
|
83
|
+
navigator.on("pause", () => console.log("Playback paused"));
|
|
84
|
+
navigator.on("end", () => console.log("Playback completed"));
|
|
85
|
+
|
|
86
|
+
// Load and play content
|
|
87
|
+
const content = document.getElementById("content");
|
|
88
|
+
navigator.loadContent(content);
|
|
89
|
+
navigator.play();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Docs
|
|
93
|
+
|
|
94
|
+
Documentation provides guides for:
|
|
95
|
+
|
|
96
|
+
- [SpeechSynthesis in browsers and OSes](docs/WebSpeech.md)
|
|
97
|
+
- [Voices and Filtering](docs/VoicesAndFiltering.md)
|
|
98
|
+
- [API Reference](docs/API.md)
|
|
99
|
+
|
|
100
|
+
## Development
|
|
101
|
+
|
|
102
|
+
We are trying to use a test-driven development approach as much as possible, where we write tests before implementing the code. Currently, this is true for the `WebSpeechVoiceManager` class as it deals primarily with voice selection and management, where mocking is straightforward.
|
|
103
|
+
|
|
104
|
+
The playback logic is more complex and may not be suitable for this approach yet, as it involves more intricate state management and user interactions that is difficult to handle through mock objects, especially as browsers vary significantly in their implementation of the Web Speech API.
|
|
105
|
+
|
|
106
|
+
### Building the Library
|
|
107
|
+
|
|
108
|
+
To build the library:
|
|
109
|
+
```bash
|
|
110
|
+
npm run build
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
This will compile the TypeScript code and generate the following outputs in the `build/` directory:
|
|
114
|
+
- `index.js` (ES modules)
|
|
115
|
+
- `index.cjs` (CommonJS)
|
|
116
|
+
- TypeScript type definitions
|
|
117
|
+
|
|
118
|
+
### Running Demos Locally
|
|
119
|
+
|
|
120
|
+
The project includes two demo applications that can be served locally:
|
|
121
|
+
|
|
122
|
+
1. Start the local development server:
|
|
123
|
+
```bash
|
|
124
|
+
npm run start
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
2. Open your browser to:
|
|
128
|
+
- [Voice selection demo](http://localhost:8080/demo)
|
|
129
|
+
- [In-context reading demo](http://localhost:8080/demo/article)
|
|
130
|
+
|
|
131
|
+
### ChromeOS Debugging
|
|
132
|
+
|
|
133
|
+
For ChromeOS development, the project includes a debug mode that mocks the Web Speech API with the set of voices exported from the ChromeOS browser:
|
|
134
|
+
|
|
135
|
+
1. Open the debug page: http://localhost:8080/debug
|
|
136
|
+
|
|
137
|
+
2. The debug page loads mock voices from a json file which contains a snapshot of ChromeOS voices.
|
|
138
|
+
|
|
139
|
+
### Running Tests
|
|
140
|
+
|
|
141
|
+
To run the test suite for `WebSpeechVoiceManager`:
|
|
142
|
+
```bash
|
|
143
|
+
npm test
|
|
144
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ReadiumSpeechPlaybackEngine } from '../engine';
|
|
2
|
+
import { ReadiumSpeechNavigator, ReadiumSpeechPlaybackEvent, ReadiumSpeechPlaybackState } from '../navigator';
|
|
3
|
+
import { ReadiumSpeechUtterance } from '../utterance';
|
|
4
|
+
import { ReadiumSpeechVoice } from '../voices/types';
|
|
5
|
+
export declare class WebSpeechReadAloudNavigator implements ReadiumSpeechNavigator {
|
|
6
|
+
private engine;
|
|
7
|
+
private contentQueue;
|
|
8
|
+
private eventListeners;
|
|
9
|
+
private navigatorState;
|
|
10
|
+
constructor(engine?: ReadiumSpeechPlaybackEngine);
|
|
11
|
+
private initializeEngine;
|
|
12
|
+
private setupEngineListeners;
|
|
13
|
+
private setNavigatorState;
|
|
14
|
+
getVoices(): Promise<ReadiumSpeechVoice[]>;
|
|
15
|
+
setVoice(voice: ReadiumSpeechVoice | string): void;
|
|
16
|
+
getCurrentVoice(): ReadiumSpeechVoice | null;
|
|
17
|
+
loadContent(content: ReadiumSpeechUtterance | ReadiumSpeechUtterance[]): void;
|
|
18
|
+
getCurrentContent(): ReadiumSpeechUtterance | null;
|
|
19
|
+
getContentQueue(): ReadiumSpeechUtterance[];
|
|
20
|
+
private getCurrentUtteranceIndex;
|
|
21
|
+
play(): void;
|
|
22
|
+
pause(): void;
|
|
23
|
+
stop(): void;
|
|
24
|
+
private skipToPosition;
|
|
25
|
+
next(forcePlay?: boolean): boolean;
|
|
26
|
+
previous(forcePlay?: boolean): boolean;
|
|
27
|
+
jumpTo(utteranceIndex: number, forcePlay?: boolean): boolean;
|
|
28
|
+
setRate(rate: number): void;
|
|
29
|
+
getRate(): number;
|
|
30
|
+
setPitch(pitch: number): void;
|
|
31
|
+
getPitch(): number;
|
|
32
|
+
setVolume(volume: number): void;
|
|
33
|
+
getVolume(): number;
|
|
34
|
+
getState(): ReadiumSpeechPlaybackState;
|
|
35
|
+
on(event: ReadiumSpeechPlaybackEvent["type"] | "contentchange", listener: (event: ReadiumSpeechPlaybackEvent) => void): () => void;
|
|
36
|
+
private emitEvent;
|
|
37
|
+
private emitContentChangeEvent;
|
|
38
|
+
destroy(): Promise<void>;
|
|
39
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { ReadiumSpeechVoice, TGender, TQuality, TSource } from '../voices/types';
|
|
2
|
+
/**
|
|
3
|
+
* Options for filtering voices
|
|
4
|
+
*/
|
|
5
|
+
interface VoiceFilterOptions {
|
|
6
|
+
languages?: string | string[];
|
|
7
|
+
source?: TSource;
|
|
8
|
+
gender?: TGender;
|
|
9
|
+
quality?: TQuality | TQuality[];
|
|
10
|
+
offlineOnly?: boolean;
|
|
11
|
+
provider?: string;
|
|
12
|
+
excludeNovelty?: boolean;
|
|
13
|
+
excludeVeryLowQuality?: boolean;
|
|
14
|
+
removeDuplicates?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Language/Region information with voice count
|
|
18
|
+
*/
|
|
19
|
+
interface LanguageInfo {
|
|
20
|
+
code: string;
|
|
21
|
+
label: string;
|
|
22
|
+
count: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Grouped voices
|
|
26
|
+
*/
|
|
27
|
+
interface VoiceGroup {
|
|
28
|
+
[key: string]: ReadiumSpeechVoice[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Grouping criteria for voices
|
|
32
|
+
*/
|
|
33
|
+
type GroupBy = "languages" | "gender" | "quality" | "region";
|
|
34
|
+
/**
|
|
35
|
+
* Manages Web Speech API voices with enhanced functionality
|
|
36
|
+
*/
|
|
37
|
+
export declare class WebSpeechVoiceManager {
|
|
38
|
+
private static instance;
|
|
39
|
+
private static initializationPromise;
|
|
40
|
+
private systemLocale;
|
|
41
|
+
private voices;
|
|
42
|
+
private browserVoices;
|
|
43
|
+
private isInitialized;
|
|
44
|
+
private constructor();
|
|
45
|
+
/**
|
|
46
|
+
* Initialize voice manager
|
|
47
|
+
* @param options Configuration options for voice loading
|
|
48
|
+
* @param options.languages Optional array of preferred language codes to filter voices during initialization
|
|
49
|
+
* @param options.maxTimeout Maximum time in milliseconds to wait for voices to load (passed to getBrowserVoices)
|
|
50
|
+
* @param options.interval Interval in milliseconds between voice loading checks (passed to getBrowserVoices)
|
|
51
|
+
* @returns Promise that resolves with the WebSpeechVoiceManager instance
|
|
52
|
+
*/
|
|
53
|
+
static initialize(options?: {
|
|
54
|
+
languages?: string[];
|
|
55
|
+
maxTimeout?: number;
|
|
56
|
+
interval?: number;
|
|
57
|
+
}): Promise<WebSpeechVoiceManager>;
|
|
58
|
+
/**
|
|
59
|
+
* Filter browser voices based on preferred languages
|
|
60
|
+
* @private
|
|
61
|
+
*/
|
|
62
|
+
private filterBrowserVoicesByLanguages;
|
|
63
|
+
/**
|
|
64
|
+
* Extract language and region from BCP47 language tag
|
|
65
|
+
* @param lang - The BCP47 language tag (e.g., "en-US", "zh-CN")
|
|
66
|
+
* @returns A tuple of [language, region] where language is lowercase and region is UPPERCASE
|
|
67
|
+
*/
|
|
68
|
+
static extractLangRegionFromBCP47(lang: string): [string, string | undefined];
|
|
69
|
+
/**
|
|
70
|
+
* Get display name for a language code
|
|
71
|
+
* @private
|
|
72
|
+
*/
|
|
73
|
+
private static getLanguageDisplayName;
|
|
74
|
+
/**
|
|
75
|
+
* Clean voice name by removing specific formatting
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
private cleanVoiceName;
|
|
79
|
+
/**
|
|
80
|
+
* Normalize voice name for comparison by removing common variations
|
|
81
|
+
* @private
|
|
82
|
+
*/
|
|
83
|
+
private normalizeVoiceName;
|
|
84
|
+
/**
|
|
85
|
+
* Count occurrences of each voice based on language and normalized name
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
private countVoiceDuplicates;
|
|
89
|
+
/**
|
|
90
|
+
* Updates the system locale based on available voices by detecting quality indicators.
|
|
91
|
+
* The method extracts voice names and attempts to find a matching locale with both
|
|
92
|
+
* high and normal quality indicators. If found, updates the systemLocale property.
|
|
93
|
+
*
|
|
94
|
+
* @param voices - Array of SpeechSynthesisVoice objects to analyze for locale detection
|
|
95
|
+
* @returns void - Updates the systemLocale property if a matching locale is found
|
|
96
|
+
*/
|
|
97
|
+
private updateSystemLocale;
|
|
98
|
+
/**
|
|
99
|
+
* Infer voice quality based on package, platform, JSON, or duplicate count
|
|
100
|
+
* Returns null if quality cannot be determined
|
|
101
|
+
* @private
|
|
102
|
+
*/
|
|
103
|
+
private inferVoiceQuality;
|
|
104
|
+
/**
|
|
105
|
+
* Find matching JSON voice by name or alternative names
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
private findMatchingJsonVoice;
|
|
109
|
+
/**
|
|
110
|
+
* Remove duplicate voices, keeping the highest quality version of each voice
|
|
111
|
+
* @param voices Array of voices to remove duplicates from
|
|
112
|
+
* @returns Filtered array with duplicates removed, keeping only the highest quality versions
|
|
113
|
+
*/
|
|
114
|
+
private removeDuplicates;
|
|
115
|
+
/**
|
|
116
|
+
* Get test utterance for a given language
|
|
117
|
+
* @param language - Language code (e.g., "en", "fr", "es")
|
|
118
|
+
* @returns Promise that resolves to the test utterance text
|
|
119
|
+
*/
|
|
120
|
+
getTestUtterance(language: string): string;
|
|
121
|
+
/**
|
|
122
|
+
* Get all voices matching the filter criteria
|
|
123
|
+
* @returns Promise that resolves to an array of filtered voices
|
|
124
|
+
*/
|
|
125
|
+
getVoices(options?: VoiceFilterOptions): ReadiumSpeechVoice[];
|
|
126
|
+
/**
|
|
127
|
+
* Get available languages with voice counts
|
|
128
|
+
* @param localization Optional BCP 47 language tag to use for language names
|
|
129
|
+
* @param filterOptions Optional filters to apply to voices before counting languages
|
|
130
|
+
* @param voices Optional array of voices to count (defaults to this.voices)
|
|
131
|
+
*/
|
|
132
|
+
getLanguages(localization?: string, filterOptions?: VoiceFilterOptions, voices?: ReadiumSpeechVoice[]): LanguageInfo[];
|
|
133
|
+
/**
|
|
134
|
+
* Get available regions with voice counts
|
|
135
|
+
* @param localization Optional BCP 47 language tag to use for region names
|
|
136
|
+
* @param filterOptions Optional filters to apply to voices before counting regions
|
|
137
|
+
* @param voices Optional array of voices to count (defaults to this.voices)
|
|
138
|
+
*/
|
|
139
|
+
getRegions(localization?: string, filterOptions?: VoiceFilterOptions, voices?: ReadiumSpeechVoice[]): LanguageInfo[];
|
|
140
|
+
/**
|
|
141
|
+
* Get the default voice for language preferences
|
|
142
|
+
* @param languages Array of preferred languages in order of preference, or a single language string
|
|
143
|
+
* @param voices Optional pre-filtered voices array to use instead of fetching voices
|
|
144
|
+
* @returns The default voice for the language, or null if no voices are available
|
|
145
|
+
*/
|
|
146
|
+
getDefaultVoice(languages: string | string[], voices?: ReadiumSpeechVoice[]): Promise<ReadiumSpeechVoice | null>;
|
|
147
|
+
getBrowserVoices(maxTimeout?: number, interval?: number): Promise<SpeechSynthesisVoice[]>;
|
|
148
|
+
/**
|
|
149
|
+
* Convert SpeechSynthesisVoice array to ReadiumSpeechVoice array
|
|
150
|
+
* @private
|
|
151
|
+
*/
|
|
152
|
+
private parseToReadiumSpeechVoices;
|
|
153
|
+
/**
|
|
154
|
+
* Convert an ReadiumSpeechVoice to a native SpeechSynthesisVoice
|
|
155
|
+
*/
|
|
156
|
+
convertToSpeechSynthesisVoice(voice: ReadiumSpeechVoice): SpeechSynthesisVoice | undefined;
|
|
157
|
+
/**
|
|
158
|
+
* Filter voices based on the provided options
|
|
159
|
+
*/
|
|
160
|
+
filterVoices(options: VoiceFilterOptions, voices?: ReadiumSpeechVoice[]): ReadiumSpeechVoice[];
|
|
161
|
+
/**
|
|
162
|
+
* Filter out novelty voices
|
|
163
|
+
* @param voices Array of voices to filter
|
|
164
|
+
* @returns Filtered array with novelty voices removed
|
|
165
|
+
*/
|
|
166
|
+
filterOutNoveltyVoices(voices?: ReadiumSpeechVoice[]): ReadiumSpeechVoice[];
|
|
167
|
+
/**
|
|
168
|
+
* Filter out very low quality voices
|
|
169
|
+
* @param voices Array of voices to filter
|
|
170
|
+
* @returns Filtered array with very low quality voices removed
|
|
171
|
+
*/
|
|
172
|
+
filterOutVeryLowQualityVoices(voices?: ReadiumSpeechVoice[]): ReadiumSpeechVoice[];
|
|
173
|
+
/**
|
|
174
|
+
* Get the numeric value for a quality level
|
|
175
|
+
* @param quality Quality level
|
|
176
|
+
* @returns Numeric value (higher = better quality, 0 for undefined/null)
|
|
177
|
+
*/
|
|
178
|
+
private static getQualityValue;
|
|
179
|
+
/**
|
|
180
|
+
* Sort two voices by quality, using JSON order as fallback for undefined/null quality
|
|
181
|
+
* @param a First voice
|
|
182
|
+
* @param b Second voice
|
|
183
|
+
* @param jsonOrderMaps Optional map of language codes to voice order maps
|
|
184
|
+
* @param baseLang Base language code to use for looking up the order map
|
|
185
|
+
* @returns Comparison result (-1, 0, or 1)
|
|
186
|
+
*/
|
|
187
|
+
private static sortByQuality;
|
|
188
|
+
/**
|
|
189
|
+
* Sort voices by quality, respecting JSON name order, then alphabetically for undefined/null quality
|
|
190
|
+
* @param voices Array of voices to sort
|
|
191
|
+
* @returns Sorted array of voices
|
|
192
|
+
*/
|
|
193
|
+
sortVoicesByQuality(voices?: ReadiumSpeechVoice[]): Promise<ReadiumSpeechVoice[]>;
|
|
194
|
+
/**
|
|
195
|
+
* Group voices by language based on processed preferred languages
|
|
196
|
+
*/
|
|
197
|
+
private static groupVoicesByLanguage;
|
|
198
|
+
/**
|
|
199
|
+
* Sort regions by default then alphabetically, sort voices by quality
|
|
200
|
+
*/
|
|
201
|
+
private static sortByDefaultRegion;
|
|
202
|
+
/**
|
|
203
|
+
* Sort voices alphabetically by language, then region, then quality
|
|
204
|
+
*/
|
|
205
|
+
private static sortAlphabetically;
|
|
206
|
+
/**
|
|
207
|
+
* Sort voices by language preference, then alphabetically
|
|
208
|
+
* @param voices Array of voices to sort
|
|
209
|
+
* @param preferredLanguages Array of preferred language codes in order of preference
|
|
210
|
+
* @returns Sorted array of voices
|
|
211
|
+
*/
|
|
212
|
+
sortVoicesByLanguages(preferredLanguages?: string[], voices?: ReadiumSpeechVoice[]): Promise<ReadiumSpeechVoice[]>;
|
|
213
|
+
/**
|
|
214
|
+
* Sort languages by region preference, then voices by quality
|
|
215
|
+
*/
|
|
216
|
+
private static sortByPreferredRegion;
|
|
217
|
+
/**
|
|
218
|
+
* Sort voices by region preference, then alphabetically
|
|
219
|
+
* @param voices Array of voices to sort
|
|
220
|
+
* @param preferredLanguages Array of preferred language codes in order of preference
|
|
221
|
+
* @returns Sorted array of voices
|
|
222
|
+
*/
|
|
223
|
+
sortVoicesByRegions(preferredLanguages: string[], voices?: ReadiumSpeechVoice[]): Promise<ReadiumSpeechVoice[]>;
|
|
224
|
+
/**
|
|
225
|
+
* Group voices by the specified criteria
|
|
226
|
+
* @param voices Array of voices to group
|
|
227
|
+
* @param options Grouping options
|
|
228
|
+
* @returns Object with voice groups keyed by the grouping criteria
|
|
229
|
+
*/
|
|
230
|
+
groupVoices(by: GroupBy, voices?: ReadiumSpeechVoice[]): VoiceGroup;
|
|
231
|
+
}
|
|
232
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ReadiumSpeechPlaybackEngine } from '../engine';
|
|
2
|
+
import { ReadiumSpeechPlaybackEvent, ReadiumSpeechPlaybackState } from '../navigator';
|
|
3
|
+
import { ReadiumSpeechUtterance } from '../utterance';
|
|
4
|
+
import { ReadiumSpeechVoice } from '../voices/types';
|
|
5
|
+
export declare class WebSpeechEngine implements ReadiumSpeechPlaybackEngine {
|
|
6
|
+
private speechSynthesis;
|
|
7
|
+
private speechSynthesisUtterance;
|
|
8
|
+
private currentVoice;
|
|
9
|
+
private currentUtterances;
|
|
10
|
+
private currentUtteranceIndex;
|
|
11
|
+
private playbackState;
|
|
12
|
+
private eventListeners;
|
|
13
|
+
private voiceManager;
|
|
14
|
+
private voices;
|
|
15
|
+
private defaultVoice;
|
|
16
|
+
private resumeInfinityTimer?;
|
|
17
|
+
private isSpeakingInternal;
|
|
18
|
+
private isPausedInternal;
|
|
19
|
+
private isAndroidPaused;
|
|
20
|
+
private pausedAtUtteranceIndex;
|
|
21
|
+
private initialized;
|
|
22
|
+
private maxLengthExceeded;
|
|
23
|
+
private utterancesBeingCancelled;
|
|
24
|
+
private rate;
|
|
25
|
+
private pitch;
|
|
26
|
+
private volume;
|
|
27
|
+
private features;
|
|
28
|
+
private patches;
|
|
29
|
+
constructor();
|
|
30
|
+
private shouldUseResumeInfinity;
|
|
31
|
+
private createUtterance;
|
|
32
|
+
initialize(options?: {
|
|
33
|
+
languages?: string[];
|
|
34
|
+
maxTimeout?: number;
|
|
35
|
+
interval?: number;
|
|
36
|
+
maxLengthExceeded?: "error" | "none" | "warn";
|
|
37
|
+
}): Promise<boolean>;
|
|
38
|
+
private validateText;
|
|
39
|
+
private getCurrentVoiceForUtterance;
|
|
40
|
+
getCurrentVoice(): ReadiumSpeechVoice | null;
|
|
41
|
+
private escapeSSML;
|
|
42
|
+
loadUtterances(contents: ReadiumSpeechUtterance[]): void;
|
|
43
|
+
setVoice(voice: ReadiumSpeechVoice | string): Promise<void>;
|
|
44
|
+
getAvailableVoices(): Promise<ReadiumSpeechVoice[]>;
|
|
45
|
+
speak(utteranceIndex?: number): void;
|
|
46
|
+
private cancelCurrentSpeech;
|
|
47
|
+
private speakCurrentUtterance;
|
|
48
|
+
private startResumeInfinity;
|
|
49
|
+
private stopResumeInfinity;
|
|
50
|
+
pause(): void;
|
|
51
|
+
resume(): void;
|
|
52
|
+
stop(): void;
|
|
53
|
+
setRate(rate: number): void;
|
|
54
|
+
getRate(): number;
|
|
55
|
+
setPitch(pitch: number): void;
|
|
56
|
+
getPitch(): number;
|
|
57
|
+
setVolume(volume: number): void;
|
|
58
|
+
getVolume(): number;
|
|
59
|
+
getState(): ReadiumSpeechPlaybackState;
|
|
60
|
+
getCurrentUtteranceIndex(): number;
|
|
61
|
+
setCurrentUtteranceIndex(index: number, onComplete?: (success: boolean) => void): void;
|
|
62
|
+
getUtteranceCount(): number;
|
|
63
|
+
on(event: ReadiumSpeechPlaybackEvent["type"], callback: (event: ReadiumSpeechPlaybackEvent) => void): () => void;
|
|
64
|
+
private emitEvent;
|
|
65
|
+
private setState;
|
|
66
|
+
destroy(): Promise<void>;
|
|
67
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReadiumSpeechEngineProvider } from '../provider';
|
|
2
|
+
import { ReadiumSpeechPlaybackEngine } from '../engine';
|
|
3
|
+
import { ReadiumSpeechVoice } from '../voices/types';
|
|
4
|
+
export declare class WebSpeechEngineProvider implements ReadiumSpeechEngineProvider {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly name: string;
|
|
7
|
+
private engine;
|
|
8
|
+
getVoices(): Promise<ReadiumSpeechVoice[]>;
|
|
9
|
+
createEngine(voice?: ReadiumSpeechVoice | string): Promise<ReadiumSpeechPlaybackEngine>;
|
|
10
|
+
destroy(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a="ar",e="ar-SA",r="مرحبًا، اسمي {name} وأنا صوت عربي.",l=[{label:"Amina",name:"Microsoft Amina Online (Natural) - Arabic (Algeria)",language:"ar-DZ",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Ismael",name:"Microsoft Ismael Online (Natural) - Arabic (Algeria)",language:"ar-DZ",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Laila",name:"Microsoft Laila Online (Natural) - Arabic (Bahrain)",language:"ar-BH",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Ali",name:"Microsoft Ali Online (Natural) - Arabic (Bahrain)",language:"ar-BH",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Salma",name:"Microsoft Salma Online (Natural) - Arabic (Egypt)",language:"ar-EG",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Shakir",name:"Microsoft Shakir Online (Natural) - Arabic (Egypt)",language:"ar-EG",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Rana",name:"Microsoft Rana Online (Natural) - Arabic (Iraq)",language:"ar-IQ",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Bassel",name:"Microsoft Bassel Online (Natural) - Arabic (Iraq)",language:"ar-IQ",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Sana",name:"Microsoft Sana Online (Natural) - Arabic (Jordan)",language:"ar-JO",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Taim",name:"Microsoft Taim Online (Natural) - Arabic (Jordan)",language:"ar-JO",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Noura",name:"Microsoft Noura Online (Natural) - Arabic (Kuwait)",language:"ar-KW",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Fahed",name:"Microsoft Fahed Online (Natural) - Arabic (Kuwait)",language:"ar-KW",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Layla",name:"Microsoft Layla Online (Natural) - Arabic (Lebanon)",language:"ar-LB",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Rami",name:"Microsoft Rami Online (Natural) - Arabic (Lebanon)",language:"ar-LB",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Iman",name:"Microsoft Iman Online (Natural) - Arabic (Libya)",language:"ar-LY",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Omar",name:"Microsoft Omar Online (Natural) - Arabic (Libya)",language:"ar-LY",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Mouna",name:"Microsoft Mouna Online (Natural) - Arabic (Morocco)",language:"ar-MA",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Jamal",name:"Microsoft Jamal Online (Natural) - Arabic (Morocco)",language:"ar-MA",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Aysha",name:"Microsoft Aysha Online (Natural) - Arabic (Oman)",language:"ar-OM",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Abdullah",name:"Microsoft Abdullah Online (Natural) - Arabic (Oman)",language:"ar-OM",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Amal",name:"Microsoft Amal Online (Natural) - Arabic (Qatar)",language:"ar-QA",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Moaz",name:"Microsoft Moaz Online (Natural) - Arabic (Qatar)",language:"ar-QA",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Zariyah",name:"Microsoft Zariyah Online (Natural) - Arabic (Saudi Arabia)",language:"ar-SA",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Hamed",name:"Microsoft Hamed Online (Natural) - Arabic (Saudi Arabia)",language:"ar-SA",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Amany",name:"Microsoft Amany Online (Natural) - Arabic (Syria)",language:"ar-SY",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Laith",name:"Microsoft Laith Online (Natural) - Arabic (Syria)",language:"ar-SY",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Reem",name:"Microsoft Reem Online (Natural) - Arabic (Tunisia)",language:"ar-TN",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Hedi",name:"Microsoft Hedi Online (Natural) - Arabic (Tunisia)",language:"ar-TN",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Fatima",name:"Microsoft Fatima Online (Natural) - Arabic (United Arab Emirates)",language:"ar-AE",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Hamdan",name:"Microsoft Hamdan Online (Natural) - Arabic (United Arab Emirates)",language:"ar-AE",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Maryam",name:"Microsoft Maryam Online (Natural) - Arabic (Yemen)",language:"ar-YE",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Saleh",name:"Microsoft Saleh Online (Natural) - Arabic (Yemen)",language:"ar-YE",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Mariam",name:"Mariam",localizedName:"apple",language:"ar-001",gender:"female",quality:["low","normal"],rate:1,pitch:1,os:["macOS","iOS","iPadOS"]},{label:"Apple Laila",name:"Laila",localizedName:"apple",language:"ar-001",gender:"female",quality:["low","normal"],rate:1,pitch:1,os:["macOS","iOS","iPadOS"]},{label:"Tarik",name:"Tarik",localizedName:"apple",language:"ar-001",gender:"male",quality:["low","normal"],rate:1,pitch:1,os:["macOS","iOS","iPadOS"]},{label:"Majed",name:"Majed",localizedName:"apple",language:"ar-001",gender:"male",quality:["low","normal","high"],rate:1,pitch:1,os:["macOS","iOS","iPadOS"],preloaded:!0},{label:"Hoda",name:"Microsoft Hoda - Arabic (Arabic )",language:"ar-EG",gender:"female",quality:["normal"],rate:1,pitch:1,os:["Windows"],preloaded:!0},{label:"Naayf",name:"Microsoft Naayf - Arabic (Saudi Arabia)",language:"ar-AS",gender:"male",quality:["normal"],rate:1,pitch:1,os:["Windows"],preloaded:!0},{label:"صوت انثوي 1",name:"Android Speech Recognition and Synthesis from Google ar-xa-x-arc-network",altNames:["Android Speech Recognition and Synthesis from Google ar-xa-x-arc-local","Android Speech Recognition and Synthesis from Google ar-language"],nativeID:["ar-xa-x-arc-network","ar-xa-x-arc-local"],language:"ar",gender:"female",quality:["high"],rate:1,pitch:1,os:["Android","ChromeOS"],preloaded:!0},{label:"صوت انثوي 2",name:"Android Speech Recognition and Synthesis from Google ar-xa-x-arz-network",altNames:["Android Speech Recognition and Synthesis from Google ar-xa-x-arz-local"],nativeID:["ar-xa-x-arz-network","ar-xa-x-arz-local"],language:"ar",gender:"female",quality:["high"],rate:1,pitch:1,os:["Android","ChromeOS"],preloaded:!0},{label:"صوت ذكر 1",name:"Android Speech Recognition and Synthesis from Google ar-xa-x-ard-network",altNames:["Android Speech Recognition and Synthesis from Google ar-xa-x-ard-local"],nativeID:["ar-xa-x-ard-network","ar-xa-x-ard-local"],language:"ar",gender:"male",quality:["high"],rate:1,pitch:1,os:["Android","ChromeOS"],preloaded:!0},{label:"صوت ذكر 2",name:"Android Speech Recognition and Synthesis from Google ar-xa-x-are-network",altNames:["Android Speech Recognition and Synthesis from Google ar-xa-x-are-local"],nativeID:["ar-xa-x-are-network","ar-xa-x-are-local"],language:"ar",gender:"male",quality:["high"],rate:1,pitch:1,os:["Android","ChromeOS"],preloaded:!0}],o={language:a,defaultRegion:e,testUtterance:r,voices:l};exports.default=o;exports.defaultRegion=e;exports.language=a;exports.testUtterance=r;exports.voices=l;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const l = "ar", a = "ar-SA", e = "مرحبًا، اسمي {name} وأنا صوت عربي.", r = [{ label: "Amina", name: "Microsoft Amina Online (Natural) - Arabic (Algeria)", language: "ar-DZ", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Ismael", name: "Microsoft Ismael Online (Natural) - Arabic (Algeria)", language: "ar-DZ", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Laila", name: "Microsoft Laila Online (Natural) - Arabic (Bahrain)", language: "ar-BH", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Ali", name: "Microsoft Ali Online (Natural) - Arabic (Bahrain)", language: "ar-BH", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Salma", name: "Microsoft Salma Online (Natural) - Arabic (Egypt)", language: "ar-EG", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Shakir", name: "Microsoft Shakir Online (Natural) - Arabic (Egypt)", language: "ar-EG", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Rana", name: "Microsoft Rana Online (Natural) - Arabic (Iraq)", language: "ar-IQ", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Bassel", name: "Microsoft Bassel Online (Natural) - Arabic (Iraq)", language: "ar-IQ", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Sana", name: "Microsoft Sana Online (Natural) - Arabic (Jordan)", language: "ar-JO", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Taim", name: "Microsoft Taim Online (Natural) - Arabic (Jordan)", language: "ar-JO", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Noura", name: "Microsoft Noura Online (Natural) - Arabic (Kuwait)", language: "ar-KW", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Fahed", name: "Microsoft Fahed Online (Natural) - Arabic (Kuwait)", language: "ar-KW", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Layla", name: "Microsoft Layla Online (Natural) - Arabic (Lebanon)", language: "ar-LB", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Rami", name: "Microsoft Rami Online (Natural) - Arabic (Lebanon)", language: "ar-LB", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Iman", name: "Microsoft Iman Online (Natural) - Arabic (Libya)", language: "ar-LY", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Omar", name: "Microsoft Omar Online (Natural) - Arabic (Libya)", language: "ar-LY", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Mouna", name: "Microsoft Mouna Online (Natural) - Arabic (Morocco)", language: "ar-MA", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Jamal", name: "Microsoft Jamal Online (Natural) - Arabic (Morocco)", language: "ar-MA", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Aysha", name: "Microsoft Aysha Online (Natural) - Arabic (Oman)", language: "ar-OM", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Abdullah", name: "Microsoft Abdullah Online (Natural) - Arabic (Oman)", language: "ar-OM", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Amal", name: "Microsoft Amal Online (Natural) - Arabic (Qatar)", language: "ar-QA", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Moaz", name: "Microsoft Moaz Online (Natural) - Arabic (Qatar)", language: "ar-QA", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Zariyah", name: "Microsoft Zariyah Online (Natural) - Arabic (Saudi Arabia)", language: "ar-SA", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Hamed", name: "Microsoft Hamed Online (Natural) - Arabic (Saudi Arabia)", language: "ar-SA", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Amany", name: "Microsoft Amany Online (Natural) - Arabic (Syria)", language: "ar-SY", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Laith", name: "Microsoft Laith Online (Natural) - Arabic (Syria)", language: "ar-SY", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Reem", name: "Microsoft Reem Online (Natural) - Arabic (Tunisia)", language: "ar-TN", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Hedi", name: "Microsoft Hedi Online (Natural) - Arabic (Tunisia)", language: "ar-TN", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Fatima", name: "Microsoft Fatima Online (Natural) - Arabic (United Arab Emirates)", language: "ar-AE", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Hamdan", name: "Microsoft Hamdan Online (Natural) - Arabic (United Arab Emirates)", language: "ar-AE", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Maryam", name: "Microsoft Maryam Online (Natural) - Arabic (Yemen)", language: "ar-YE", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Saleh", name: "Microsoft Saleh Online (Natural) - Arabic (Yemen)", language: "ar-YE", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Mariam", name: "Mariam", localizedName: "apple", language: "ar-001", gender: "female", quality: ["low", "normal"], rate: 1, pitch: 1, os: ["macOS", "iOS", "iPadOS"] }, { label: "Apple Laila", name: "Laila", localizedName: "apple", language: "ar-001", gender: "female", quality: ["low", "normal"], rate: 1, pitch: 1, os: ["macOS", "iOS", "iPadOS"] }, { label: "Tarik", name: "Tarik", localizedName: "apple", language: "ar-001", gender: "male", quality: ["low", "normal"], rate: 1, pitch: 1, os: ["macOS", "iOS", "iPadOS"] }, { label: "Majed", name: "Majed", localizedName: "apple", language: "ar-001", gender: "male", quality: ["low", "normal", "high"], rate: 1, pitch: 1, os: ["macOS", "iOS", "iPadOS"], preloaded: !0 }, { label: "Hoda", name: "Microsoft Hoda - Arabic (Arabic )", language: "ar-EG", gender: "female", quality: ["normal"], rate: 1, pitch: 1, os: ["Windows"], preloaded: !0 }, { label: "Naayf", name: "Microsoft Naayf - Arabic (Saudi Arabia)", language: "ar-AS", gender: "male", quality: ["normal"], rate: 1, pitch: 1, os: ["Windows"], preloaded: !0 }, { label: "صوت انثوي 1", name: "Android Speech Recognition and Synthesis from Google ar-xa-x-arc-network", altNames: ["Android Speech Recognition and Synthesis from Google ar-xa-x-arc-local", "Android Speech Recognition and Synthesis from Google ar-language"], nativeID: ["ar-xa-x-arc-network", "ar-xa-x-arc-local"], language: "ar", gender: "female", quality: ["high"], rate: 1, pitch: 1, os: ["Android", "ChromeOS"], preloaded: !0 }, { label: "صوت انثوي 2", name: "Android Speech Recognition and Synthesis from Google ar-xa-x-arz-network", altNames: ["Android Speech Recognition and Synthesis from Google ar-xa-x-arz-local"], nativeID: ["ar-xa-x-arz-network", "ar-xa-x-arz-local"], language: "ar", gender: "female", quality: ["high"], rate: 1, pitch: 1, os: ["Android", "ChromeOS"], preloaded: !0 }, { label: "صوت ذكر 1", name: "Android Speech Recognition and Synthesis from Google ar-xa-x-ard-network", altNames: ["Android Speech Recognition and Synthesis from Google ar-xa-x-ard-local"], nativeID: ["ar-xa-x-ard-network", "ar-xa-x-ard-local"], language: "ar", gender: "male", quality: ["high"], rate: 1, pitch: 1, os: ["Android", "ChromeOS"], preloaded: !0 }, { label: "صوت ذكر 2", name: "Android Speech Recognition and Synthesis from Google ar-xa-x-are-network", altNames: ["Android Speech Recognition and Synthesis from Google ar-xa-x-are-local"], nativeID: ["ar-xa-x-are-network", "ar-xa-x-are-local"], language: "ar", gender: "male", quality: ["high"], rate: 1, pitch: 1, os: ["Android", "ChromeOS"], preloaded: !0 }], o = {
|
|
2
|
+
language: "ar",
|
|
3
|
+
defaultRegion: a,
|
|
4
|
+
testUtterance: e,
|
|
5
|
+
voices: r
|
|
6
|
+
};
|
|
7
|
+
export {
|
|
8
|
+
o as default,
|
|
9
|
+
a as defaultRegion,
|
|
10
|
+
l as language,
|
|
11
|
+
e as testUtterance,
|
|
12
|
+
r as voices
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="bg",a="bg-BG",l="Здравейте, казвам се {name} и съм български глас.",n=[{label:"Kalina",name:"Microsoft Kalina Online (Natural) - Bulgarian (Bulgaria)",language:"bg-BG",gender:"female",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Borislav",name:"Microsoft Borislav Online (Natural) - Bulgarian (Bulgaria)",language:"bg-BG",gender:"male",quality:["veryHigh"],rate:1,pitchControl:!1,browser:["Edge"],preloaded:!0},{label:"Daria",name:"Daria",localizedName:"apple",language:"bg-BG",gender:"female",quality:["low","normal"],rate:1,pitch:1,os:["macOS","iOS","iPadOS"],preloaded:!0},{label:"Ivan",name:"Microsoft Ivan - Bulgarian (Bulgaria)",language:"bg-BG",gender:"male",quality:["normal"],rate:1,pitch:1,os:["Windows"],preloaded:!0},{label:"Женски глас",name:"Android Speech Recognition and Synthesis from Google bg-bg-x-ifk-network",altNames:["Android Speech Recognition and Synthesis from Google bg-bg-x-ifk-local","Android Speech Recognition and Synthesis from Google bg-bg-language"],nativeID:["bg-bg-x-ifk-network","bg-bg-x-ifk-local"],language:"bg-BG",gender:"female",quality:["high"],rate:1,pitch:1,os:["Android","ChromeOS"],preloaded:!0}],o={language:e,defaultRegion:a,testUtterance:l,voices:n};exports.default=o;exports.defaultRegion=a;exports.language=e;exports.testUtterance=l;exports.voices=n;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const n = "bg", e = "bg-BG", a = "Здравейте, казвам се {name} и съм български глас.", l = [{ label: "Kalina", name: "Microsoft Kalina Online (Natural) - Bulgarian (Bulgaria)", language: "bg-BG", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Borislav", name: "Microsoft Borislav Online (Natural) - Bulgarian (Bulgaria)", language: "bg-BG", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Daria", name: "Daria", localizedName: "apple", language: "bg-BG", gender: "female", quality: ["low", "normal"], rate: 1, pitch: 1, os: ["macOS", "iOS", "iPadOS"], preloaded: !0 }, { label: "Ivan", name: "Microsoft Ivan - Bulgarian (Bulgaria)", language: "bg-BG", gender: "male", quality: ["normal"], rate: 1, pitch: 1, os: ["Windows"], preloaded: !0 }, { label: "Женски глас", name: "Android Speech Recognition and Synthesis from Google bg-bg-x-ifk-network", altNames: ["Android Speech Recognition and Synthesis from Google bg-bg-x-ifk-local", "Android Speech Recognition and Synthesis from Google bg-bg-language"], nativeID: ["bg-bg-x-ifk-network", "bg-bg-x-ifk-local"], language: "bg-BG", gender: "female", quality: ["high"], rate: 1, pitch: 1, os: ["Android", "ChromeOS"], preloaded: !0 }], o = {
|
|
2
|
+
language: "bg",
|
|
3
|
+
defaultRegion: e,
|
|
4
|
+
testUtterance: a,
|
|
5
|
+
voices: l
|
|
6
|
+
};
|
|
7
|
+
export {
|
|
8
|
+
o as default,
|
|
9
|
+
e as defaultRegion,
|
|
10
|
+
n as language,
|
|
11
|
+
a as testUtterance,
|
|
12
|
+
l as voices
|
|
13
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const t = "bho", a = "bho-IN", e = "नमस्कार, हमार नाम {name} ह आ हम भोजपुरी आवाज हईं", o = [{ label: "Jaya", name: "Jaya", localizedName: "apple", language: "bho-IN", gender: "female", quality: ["low", "normal"], rate: 1, pitch: 1, os: ["macOS", "iOS", "iPadOS"], preloaded: !0 }], l = {
|
|
2
|
+
language: "bho",
|
|
3
|
+
defaultRegion: a,
|
|
4
|
+
testUtterance: e,
|
|
5
|
+
voices: o
|
|
6
|
+
};
|
|
7
|
+
export {
|
|
8
|
+
l as default,
|
|
9
|
+
a as defaultRegion,
|
|
10
|
+
t as language,
|
|
11
|
+
e as testUtterance,
|
|
12
|
+
o as voices
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="bho",a="bho-IN",t="नमस्कार, हमार नाम {name} ह आ हम भोजपुरी आवाज हईं",o=[{label:"Jaya",name:"Jaya",localizedName:"apple",language:"bho-IN",gender:"female",quality:["low","normal"],rate:1,pitch:1,os:["macOS","iOS","iPadOS"],preloaded:!0}],l={language:e,defaultRegion:a,testUtterance:t,voices:o};exports.default=l;exports.defaultRegion=a;exports.language=e;exports.testUtterance=t;exports.voices=o;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const o = "bn", e = "bn-IN", n = "হ্যালো, আমার নাম {name} এবং আমি একজন বাংলা ভয়েস।", a = [{ label: "Tanishaa", name: "Microsoft Tanishaa Online (Natural) - Bengali (India)", language: "bn-IN", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Bashkar", name: "Microsoft Bashkar Online (Natural) - Bangla (India)", language: "bn-IN", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Nabanita", name: "Microsoft Nabanita Online (Natural) - Bangla (Bangladesh)", language: "bn-BD", gender: "female", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Pradeep", name: "Microsoft Pradeep Online (Natural) - Bangla (Bangladesh)", language: "bn-BD", gender: "male", quality: ["veryHigh"], rate: 1, pitchControl: !1, browser: ["Edge"], preloaded: !0 }, { label: "Piya", name: "Piya", localizedName: "apple", language: "bn-IN", gender: "female", quality: ["low", "normal"], rate: 1, pitch: 1, os: ["macOS", "iOS", "iPadOS"], preloaded: !0 }, { label: "মহিলা কণ্ঠস্বর 1", name: "Android Speech Recognition and Synthesis from Google bn-in-x-bnf-network", altNames: ["Android Speech Recognition and Synthesis from Google bn-in-x-bnf-local", "Android Speech Recognition and Synthesis from Google bn-IN-language"], nativeID: ["bn-in-x-bnf-network", "bn-in-x-bnf-local"], language: "bn-IN", gender: "female", quality: ["high"], rate: 1, pitch: 1, os: ["Android", "ChromeOS"], preloaded: !0 }, { label: "মহিলা কণ্ঠস্বর 2", name: "Android Speech Recognition and Synthesis from Google bn-in-x-bnx-network", altNames: ["Android Speech Recognition and Synthesis from Google bn-in-x-bnx-local"], nativeID: ["bn-in-x-bnx-network", "bn-in-x-bnx-local"], language: "bn-IN", gender: "female", quality: ["high"], rate: 1, pitch: 1, os: ["Android", "ChromeOS"], preloaded: !0 }, { label: "পুরুষ কন্ঠ 1", name: "Android Speech Recognition and Synthesis from Google bn-in-x-bin-network", altNames: ["Android Speech Recognition and Synthesis from Google bn-in-x-bin-local"], nativeID: ["bn-in-x-bin-network", "bn-in-x-bin-local"], language: "bn-IN", gender: "male", quality: ["high"], rate: 1, pitch: 1, os: ["Android", "ChromeOS"], preloaded: !0 }, { label: "পুরুষ কন্ঠ 2", name: "Android Speech Recognition and Synthesis from Google bn-in-x-bnm-network", altNames: ["Android Speech Recognition and Synthesis from Google bn-in-x-bnm-local"], nativeID: ["bn-in-x-bnm-network", "bn-in-x-bnm-local"], language: "bn-IN", gender: "male", quality: ["high"], rate: 1, pitch: 1, os: ["Android", "ChromeOS"], preloaded: !0 }, { label: "পুরুষ কন্ঠ", name: "Google বাংলা (Natural)", altNames: ["Android Speech Recognition and Synthesis from Google bn-bd-x-ban-network", "Chrome OS বাংলা", "Android Speech Recognition and Synthesis from Google bn-bd-x-ban-local", "Android Speech Recognition and Synthesis from Google bn-BD-language"], nativeID: ["bn-bd-x-ban-network", "bn-bd-x-ban-local"], language: "bn-BD", gender: "male", quality: ["high"], rate: 1, pitch: 1, os: ["Android", "ChromeOS"], preloaded: !0 }], l = {
|
|
2
|
+
language: "bn",
|
|
3
|
+
defaultRegion: e,
|
|
4
|
+
testUtterance: n,
|
|
5
|
+
voices: a
|
|
6
|
+
};
|
|
7
|
+
export {
|
|
8
|
+
l as default,
|
|
9
|
+
e as defaultRegion,
|
|
10
|
+
o as language,
|
|
11
|
+
n as testUtterance,
|
|
12
|
+
a as voices
|
|
13
|
+
};
|