@sefinek/google-tts-api 2.1.1 → 2.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/README.md +18 -30
- package/dist/splitLongText.js +1 -1
- package/dist/splitLongText.js.map +1 -1
- package/example/british.js +18 -0
- package/example/chinese.js +18 -0
- package/example/download-by-audio-url.js +54 -0
- package/example/english.js +18 -0
- package/example/long-chinese-text.js +44 -0
- package/example/long-english-text.js +53 -0
- package/package.json +12 -2
- package/.eslintrc.js +0 -57
- package/.github/workflows/build.yml +0 -32
- package/.idea/discord.xml +0 -7
- package/.idea/google-tts-api.iml +0 -12
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/jsLibraryMappings.xml +0 -6
- package/.idea/jsLinters/eslint.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/CHANGELOG.md +0 -62
- package/tsconfig.json +0 -73
package/README.md
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
# @sefinek/google-tts-api
|
|
2
|
-
Google TTS (Text-To-Speech) for Node.js without any vulnerabilities.
|
|
1
|
+
# 📢 @sefinek/google-tts-api
|
|
2
|
+
Google TTS (Text-To-Speech) for [Node.js](https://nodejs.org) without any vulnerabilities.
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+

|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
## 📥 Installation
|
|
11
12
|
```bash
|
|
12
13
|
$ npm install --save google-tts-api
|
|
13
14
|
$ npm install -D typescript @types/node # Only for TypeScript
|
|
14
15
|
```
|
|
15
16
|
|
|
16
|
-
## Change Log
|
|
17
|
-
[CHANGELOG.md](https://github.com/sefinek24/google-tts-api/blob/master/CHANGELOG.md)
|
|
18
17
|
|
|
19
|
-
## Usage
|
|
18
|
+
## 🤔 Usage
|
|
20
19
|
| Method | Options (all optional) | Return Type | Handle Long Text |
|
|
21
20
|
|---------------------|-------------------------------------------------|-----------------------------------------------------|:----------------:|
|
|
22
21
|
| `getAudioUrl` | `lang`, `slow`, `host` | `string` | |
|
|
@@ -33,13 +32,14 @@ $ npm install -D typescript @types/node # Only for TypeScript
|
|
|
33
32
|
| `timeout` | `number` | 10000 (ms) | (Only for `getAudioBase64` and `getAllAudioBase64`) Set timeout for the HTTP request. |
|
|
34
33
|
| `splitPunct` | `string` | | (Only for `getAllAudioUrls` and `getAllAudioBase64`) Set the punctuation to split the long text to short text. (e.g. ",、。") |
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
|
|
36
|
+
## 💻 Examples
|
|
37
37
|
### 1. `getAudioUrl(text, [option])`
|
|
38
38
|
```js
|
|
39
39
|
import * as googleTTS from '@sefinek/google-tts-api'; // ES6 or TypeScript
|
|
40
40
|
const googleTTS = require('@sefinek/google-tts-api'); // CommonJS
|
|
41
41
|
|
|
42
|
-
//
|
|
42
|
+
// Get audio URL
|
|
43
43
|
const url = googleTTS.getAudioUrl('Hello World', {
|
|
44
44
|
lang: 'en',
|
|
45
45
|
slow: false,
|
|
@@ -53,7 +53,7 @@ console.log(url); // https://translate.google.com/translate_tts?...
|
|
|
53
53
|
import * as googleTTS from '@sefinek/google-tts-api'; // ES6 or TypeScript
|
|
54
54
|
const googleTTS = require('@sefinek/google-tts-api'); // CommonJS
|
|
55
55
|
|
|
56
|
-
//
|
|
56
|
+
// Get base64 text
|
|
57
57
|
googleTTS
|
|
58
58
|
.getAudioBase64('Hello World', {
|
|
59
59
|
lang: 'en',
|
|
@@ -106,20 +106,8 @@ googleTTS
|
|
|
106
106
|
.catch(console.error);
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
[More
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
[npm-url]: https://nodei.co/npm/@sefinek/google-tts-api
|
|
115
|
-
[npm-img]: https://nodei.co/npm/@sefinek/google-tts-api.png
|
|
116
|
-
[install-size-img]: https://packagephobia.com/badge?p=@sefinek/google-tts-api
|
|
117
|
-
[install-size-result]: https://packagephobia.com/result?p=@sefinek/google-tts-api
|
|
118
|
-
[dependency-url]: https://david-dm.org/sefinek24/@sefinek/google-tts-api
|
|
119
|
-
[dependency-img]: https://img.shields.io/david/sefinek24/@sefinek/google-tts-api.svg
|
|
120
|
-
[dependency-dev-url]: https://david-dm.org/sefinek24/google-tts-api#info=devDependencies
|
|
121
|
-
[dependency-dev-img]: https://img.shields.io/david/dev/sefinek24/google-tts-api.svg
|
|
122
|
-
[gh-action-url]: https://github.com/sefinek24/google-tts-api/actions
|
|
123
|
-
[gh-action-img]: https://github.com/sefinek24/google-tts-api/actions/workflows/build.yml/badge.svg
|
|
124
|
-
[coverage-url]: https://coveralls.io/github/sefinek24/google-tts-api
|
|
125
|
-
[coverage-img]: https://img.shields.io/coveralls/github/sefinek24/google-tts-api
|
|
109
|
+
#### [More examples](https://github.com/sefinek24/google-tts-api/tree/master/example)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
## 📑 License
|
|
113
|
+
MIT
|
package/dist/splitLongText.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim
|
|
4
4
|
var SPACE_REGEX = '\\s\\uFEFF\\xA0';
|
|
5
|
-
// https://remarkablemark.org/blog/2019/09/28/javascript-remove-punctuation
|
|
5
|
+
// https://remarkablemark.org/blog/2019/09/28/javascript-remove-punctuation
|
|
6
6
|
var DEFAULT_PUNCTUATION_REGEX = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';
|
|
7
7
|
/**
|
|
8
8
|
* split the long text to short texts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"splitLongText.js","sourceRoot":"","sources":["../src/splitLongText.ts"],"names":[],"mappings":";;AAAA,+FAA+F;AAC/F,IAAM,WAAW,GAAG,iBAAiB,CAAC;AAEtC,
|
|
1
|
+
{"version":3,"file":"splitLongText.js","sourceRoot":"","sources":["../src/splitLongText.ts"],"names":[],"mappings":";;AAAA,+FAA+F;AAC/F,IAAM,WAAW,GAAG,iBAAiB,CAAC;AAEtC,2EAA2E;AAC3E,IAAM,yBAAyB,GAAG,oCAAoC,CAAC;AAOvE;;;;;;;;;GASG;AACH,IAAM,aAAa,GAAG,UAClB,IAAY,EACZ,EAAiD;QAAjD,qBAA+C,EAAE,KAAA,EAA/C,iBAAe,EAAf,SAAS,mBAAG,GAAG,KAAA,EAAE,kBAAe,EAAf,UAAU,mBAAG,EAAE,KAAA;IAEpC,IAAM,cAAc,GAAG,UAAC,CAAS,EAAE,CAAS;QAC1C,IAAM,KAAK,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,WAAW,GAAG,yBAAyB,GAAG,UAAU,GAAG,GAAG,CAAC,CAAC;QAC3F,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC;IAEF,IAAM,uBAAuB,GAAG,UAAC,CAAS,EAAE,IAAY,EAAE,KAAa;QACrE,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,IAAI,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;gBAAE,OAAO,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY;IACzB,CAAC,CAAC;IAEF,IAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAM,SAAS,GAAG,UAAC,IAAY,EAAE,KAAa,EAAE,GAAW;QACzD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,SAAS,CAAC;QACR,sBAAsB;QACtB,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,IAAI,SAAS,EAAE,CAAC;YACrC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,cAAc;QACvB,CAAC;QAED,+CAA+C;QAC/C,IAAI,GAAG,GAAG,KAAK,GAAG,SAAS,GAAG,CAAC,CAAC;QAChC,IAAI,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,cAAc,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;YAC/D,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;YAC5B,KAAK,GAAG,GAAG,GAAG,CAAC,CAAC;YAChB,SAAS;QACX,CAAC;QAED,2BAA2B;QAC3B,GAAG,GAAG,uBAAuB,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAChD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,IAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC,CAAC;YACjD,MAAM,IAAI,KAAK,CACX,kDAAkD;gBAClD,YAAK,GAAG,SAAM;gBACd,mEAAmE,CACtE,CAAC;QACJ,CAAC;QAED,aAAa;QACb,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAC5B,KAAK,GAAG,GAAG,GAAG,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,kBAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const googleTTS = require('../dist/index');
|
|
3
|
+
|
|
4
|
+
// 1. get audio URL
|
|
5
|
+
const url = googleTTS.getAudioUrl('Hello World', { lang: 'en-GB' });
|
|
6
|
+
console.log({ url }); // https://translate.google.com/translate_tts?...
|
|
7
|
+
|
|
8
|
+
// 2. get base64 text
|
|
9
|
+
googleTTS
|
|
10
|
+
.getAudioBase64('Hello World', { lang: 'en-GB' })
|
|
11
|
+
.then((base64) => {
|
|
12
|
+
console.log({ base64 });
|
|
13
|
+
|
|
14
|
+
// save the audio file
|
|
15
|
+
const buffer = Buffer.from(base64, 'base64');
|
|
16
|
+
fs.writeFileSync('hello-world-british.mp3', buffer, { encoding: 'base64' });
|
|
17
|
+
})
|
|
18
|
+
.catch(console.error);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const googleTTS = require('../dist/index');
|
|
3
|
+
|
|
4
|
+
// 1. get audio URL
|
|
5
|
+
const url = googleTTS.getAudioUrl('你好世界', { lang: 'zh-TW' });
|
|
6
|
+
console.log({ url }); // https://translate.google.com/translate_tts?...
|
|
7
|
+
|
|
8
|
+
// 2. get base64 text
|
|
9
|
+
googleTTS
|
|
10
|
+
.getAudioBase64('你好世界', { lang: 'zh-TW' })
|
|
11
|
+
.then((base64) => {
|
|
12
|
+
console.log({ base64 });
|
|
13
|
+
|
|
14
|
+
// save the audio file
|
|
15
|
+
const buffer = Buffer.from(base64, 'base64');
|
|
16
|
+
fs.writeFileSync('hello-world-chinese.mp3', buffer, { encoding: 'base64' });
|
|
17
|
+
})
|
|
18
|
+
.catch(console.error);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const http = require('http');
|
|
4
|
+
const https = require('https');
|
|
5
|
+
const urlParse = require('url').parse;
|
|
6
|
+
const googleTTS = require('../dist/index');
|
|
7
|
+
|
|
8
|
+
function downloadFile(url, dest) {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
const info = urlParse(url);
|
|
11
|
+
const httpClient = info.protocol === 'https:' ? https : http;
|
|
12
|
+
const options = {
|
|
13
|
+
host: info.host,
|
|
14
|
+
path: info.path,
|
|
15
|
+
headers: {
|
|
16
|
+
'user-agent': 'WHAT_EVER',
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
httpClient
|
|
21
|
+
.get(options, (res) => {
|
|
22
|
+
// check status code
|
|
23
|
+
if (res.statusCode !== 200) {
|
|
24
|
+
const msg = `request to ${url} failed, status code = ${res.statusCode} (${res.statusMessage})`;
|
|
25
|
+
reject(new Error(msg));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const file = fs.createWriteStream(dest);
|
|
30
|
+
file.on('finish', function() {
|
|
31
|
+
// close() is async, call resolve after close completes.
|
|
32
|
+
file.close(resolve);
|
|
33
|
+
});
|
|
34
|
+
file.on('error', function(err) {
|
|
35
|
+
// Delete the file async. (But we don't check the result)
|
|
36
|
+
fs.unlink(dest);
|
|
37
|
+
reject(err);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
res.pipe(file);
|
|
41
|
+
})
|
|
42
|
+
.on('error', reject)
|
|
43
|
+
.end();
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// start
|
|
48
|
+
const url = googleTTS.getAudioUrl('hello');
|
|
49
|
+
console.log(url); // https://translate.google.com/translate_tts?...
|
|
50
|
+
|
|
51
|
+
const dest = path.resolve(__dirname, 'hello.mp3'); // file destination
|
|
52
|
+
console.log('Download to ' + dest + ' ...');
|
|
53
|
+
downloadFile(url, dest);
|
|
54
|
+
console.log('Download success');
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const googleTTS = require('../dist/index');
|
|
3
|
+
|
|
4
|
+
// 1. get audio URL
|
|
5
|
+
const url = googleTTS.getAudioUrl('Hello World', { lang: 'en', slow: false });
|
|
6
|
+
console.log({ url }); // https://translate.google.com/translate_tts?...
|
|
7
|
+
|
|
8
|
+
// 2. get base64 text
|
|
9
|
+
googleTTS
|
|
10
|
+
.getAudioBase64('Hello World', { lang: 'en', slow: false })
|
|
11
|
+
.then((base64) => {
|
|
12
|
+
console.log({ base64 });
|
|
13
|
+
|
|
14
|
+
// save the audio file
|
|
15
|
+
const buffer = Buffer.from(base64, 'base64');
|
|
16
|
+
fs.writeFileSync('hello-world-english.mp3', buffer, { encoding: 'base64' });
|
|
17
|
+
})
|
|
18
|
+
.catch(console.error);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const googleTTS = require('../dist/index');
|
|
3
|
+
|
|
4
|
+
const article =
|
|
5
|
+
'如果想想生物在死之后被完全摧毁的种种方式,能够这样频繁出现化石是一件很令人惊讶的事。食腐动物和细菌的' +
|
|
6
|
+
'破坏、化学性腐烂、腐蚀以及其它地质因素都会非常不利于保存。不过,如果生物体碰巧具有矿化的骨骼并且死于' +
|
|
7
|
+
'可以迅速被沉积物掩埋的地方,摆脱被完全摧毁的几率便会大大增加。海底通常就具有上述的两方面条件,这里生' +
|
|
8
|
+
'活着很多带壳的无脊椎动物(没有脊椎的动物),不断累积的似雨的沉积颗粒会把它们掩埋起来。虽然多数的化石是' +
|
|
9
|
+
'在海洋沉积岩中发现的,但是在溪流和湖泊留下的陆相沉积物中也发现过。有时,浸入焦油和流沙、陷入冰或熔岩' +
|
|
10
|
+
'流或被急速降落的火山灰吞噬的动植物得以保存下来。术语“化石”常常意味着石化,字面意思就是变成了石头。生' +
|
|
11
|
+
'物体死后,软组织一般会被食腐动物和细菌吃掉。可能会留下蜗牛或蛤蜊空壳,如果空壳足够坚固并且能抵御分解' +
|
|
12
|
+
',就有可能在很长一段时间内基本上保持原样。事实上,我们现在所知的在沉积物中发现的海洋无脊椎动物保存良' +
|
|
13
|
+
'好的壳已超过了1亿年之久。不过,很多海洋生物的骨骼是由称为霰石的各式碳酸钙矿物质组成的。虽然霰石与我' +
|
|
14
|
+
'们更为熟悉的矿物方解石具有同样的组成,但是它的晶型不同,相对不稳定,最终会变成更稳定的方解石。很多其' +
|
|
15
|
+
'他过程也许会改变哈喇壳或蜗牛壳并且增加它被保存下来的几率。含有溶解的二氧化硅、碳酸钙或铁的水可能会在' +
|
|
16
|
+
'封闭的沉积物中流动,并沉积到诸如骨髓腔和骨头管道内,这些骨头管道曾经由血管和神经占据。这种情况下,骨' +
|
|
17
|
+
'和壳的原始组成没有改变,但是形成的化石更坚硬并且更持久。这种在孔隙中填充化学沉积物的过程就叫做“完全矿' +
|
|
18
|
+
'化”。石化还可能同时涉及死亡的动植物的原有物质与不同组成的矿物质的交换作用。该过程叫做“臵换作用”,因' +
|
|
19
|
+
'为溶液溶解了原始物质并将其臵换成为等体积的新物质。臵换是一个让人难以臵信的精确过程,贝壳装饰的细节、' +
|
|
20
|
+
'树木的年轮以及骨骼的精细结构都被精准地保存下来。另一种类型的石化,称为“碳化”,当软组织以碳薄膜的形式' +
|
|
21
|
+
'保存时会发生碳化。树叶和软体动物例如水母或蠕虫的组织可能会堆积起来,被掩埋并被压实,然后其中的挥发性' +
|
|
22
|
+
'成分会消失。碳通常以一种黑色轮廓的形式被保留下来。虽然拥有坚硬的部分的确会增加保存的可能性,但是具有' +
|
|
23
|
+
'软组织和器官的生物偶尔也会被保存下来。在针叶树以及某些其它的树种的凝固树脂中就发现了昆虫甚至是很小的' +
|
|
24
|
+
'无脊椎动物。对岩石薄片的X射线检查有时会发现可怕的触角轮廓、消化道和很多种海洋生物的视觉器官。冻土或石' +
|
|
25
|
+
'油渗漏时渗出的焦油中保存了包括皮肤、毛发和冰河时代猛犸象的内脏在内的软组织。如果生物体死于一个快速沉' +
|
|
26
|
+
'积和缺氧的环境,会有助于软组织残骸的保存。在这种条件下,细菌的破坏性影响会降低。德国始新世中期的麦塞' +
|
|
27
|
+
'尔页岩(来自4800万年前)就是在这种环境下积累起来的。该页岩在一个缺氧的湖泊里沉积,那里时有致命的气体' +
|
|
28
|
+
'冒出并杀死动物。动物的残骸在湖底聚集,然后被粘土和淤泥所覆盖。在保存完好的麦塞尔化石中有带闪亮外骨骼' +
|
|
29
|
+
'(硬质外部覆盖物)的昆虫,皮肤和血管完好无损的青蛙,甚至是毛皮和软组织都完整保存的小型哺乳动物。';
|
|
30
|
+
|
|
31
|
+
const option = { lang: 'zh', splitPunct: ',、。' };
|
|
32
|
+
|
|
33
|
+
// 1. all audio URLs
|
|
34
|
+
const results = googleTTS.getAllAudioUrls(article, option);
|
|
35
|
+
results.forEach((item, i) => {
|
|
36
|
+
console.log(`${i + 1}. ${item.shortText.length} characters`, item, '\n');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// 2. all audio base64 texts
|
|
40
|
+
googleTTS.getAllAudioBase64(article, option).then((results) => {
|
|
41
|
+
results.forEach((item, i) => {
|
|
42
|
+
console.log(`${i + 1}. ${item.shortText.length} characters`, item, '\n');
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const googleTTS = require('../dist/index');
|
|
2
|
+
|
|
3
|
+
const article = `The Industrial Revolution had several roots, one of which was a commercial revolution that, beginning as far back as the sixteenth century, accompanied Europe’s expansion overseas.
|
|
4
|
+
Both exports and imports showed spectacular growth, particularly in England and France.
|
|
5
|
+
An increasingly larger portion of the stepped-up commercial activity was the result of trade with overseas colonies.
|
|
6
|
+
Imports included a variety of new beverages, spices, and ship’s goods around the world and brought money flowing back.
|
|
7
|
+
Europe’s economic institutions, particularly those in England, were strong, had wealth available for new investment, and seemed almost to be waiting for some technological breakthrough that would expand their profit-making potential even more.
|
|
8
|
+
|
|
9
|
+
The breakthrough came in Great Britain, where several economic advantages created a climate especially favorable to the encouragement of new technology.
|
|
10
|
+
One was its geographic location at the crossroads of international trade.
|
|
11
|
+
Internally, Britain was endowed with easily navigable natural waterway, which helped its trade and communication with the world.
|
|
12
|
+
Beginning in the 1770’s, it enjoyed a boom in canal building, which helped make its domestic market more accessible.
|
|
13
|
+
Because water transportation was the cheapest means of carrying goods to market, canals reduced prices and thus increased consumer demand.
|
|
14
|
+
Great Britain also had rich deposits of coal that fed the factories springing up in industrial and consumer goods.
|
|
15
|
+
|
|
16
|
+
Another advantage was Britain’s large population of rural, agricultural wage earners,as well as cottage workers, who had the potential of being more mobile than peasants of some other countries.
|
|
17
|
+
Eventually they found their way to the cities or mining communities and provided the human power upon which the Industrial Revolution was built.
|
|
18
|
+
The British people were also consumers; the absence of internal tariffs, such as those that existed in France or Italy or between the German states, made Britain the largest free-trade area in Europe.
|
|
19
|
+
Britain’s relatively stable government also helped create an atmosphere conducive to industrial progress.
|
|
20
|
+
|
|
21
|
+
Great Britain’s better-developed banking and credit system also helped speed the industrial progress, as did the fact that it was the home of an impressive array of entrepreneurs and inventors.
|
|
22
|
+
Among them were a large number of nonconformists whose religious principles encouraged thrift and industry rather than luxurious living and who tended to pour their profits back into their business, thus providing the basis for continued expansion.
|
|
23
|
+
|
|
24
|
+
A precursor to the Industrial Revolution was a revolution in agricultural techniques.
|
|
25
|
+
Ideas about agricultural reform developed first in Holland, where as early as the mid-seventeenth century, such modern methods as crop rotation, heavy fertilization, and diversification were all in use.
|
|
26
|
+
Dutch peasant farmers were known throughout Europe for their agricultural innovations, but as British markets and opportunities grew, the English quickly learned from them.
|
|
27
|
+
As early as the seventeenth century the Dutch were helping them drain marshes and fens where, with the help of advanced techniques, they grew new crops.
|
|
28
|
+
By the mid-eighteenth century new agricultural methods as well as selective breeding of livestock had caught on throughout the country.
|
|
29
|
+
|
|
30
|
+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
31
|
+
|
|
32
|
+
Much of the increased production was consumed by Great Britain’s burgeoning population.
|
|
33
|
+
At the same time, people were moving to the city, partly because of the enclosure movement; that is, the fencing of common fields and pastures in order to provide more compact, efficient privately held agricultural parcels that would produce more goods and greater profits.
|
|
34
|
+
In the sixteenth century enclosures were usually used for creating sheep pastures, but by the eighteenth century new farming techniques made it advantageous for large landowners to seek enclosures in order to improve agricultural production.
|
|
35
|
+
Between 1714 and 1820 over 6 million acres of English land were enclosed.
|
|
36
|
+
As a result, many small, independent farmers were forced to sell out simply because they could not compete.
|
|
37
|
+
Non-landholding peasants and cottage workers, who worked for wages and grazed cows or pigs on the village common, were also hurt when the common was no longer available.
|
|
38
|
+
It was such people who began to flock to the cities seeking employment and who found work in the factories that would transform the nation and, the world.
|
|
39
|
+
|
|
40
|
+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`;
|
|
41
|
+
|
|
42
|
+
// 1. all audio URLs
|
|
43
|
+
const results = googleTTS.getAllAudioUrls(article);
|
|
44
|
+
results.forEach((item, i) => {
|
|
45
|
+
console.log(`${i + 1}. ${item.shortText.length} characters`, item, '\n');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// 2. all audio base64 texts
|
|
49
|
+
googleTTS.getAllAudioBase64(article).then((results) => {
|
|
50
|
+
results.forEach((item, i) => {
|
|
51
|
+
console.log(`${i + 1}. ${item.shortText.length} characters`, item, '\n');
|
|
52
|
+
});
|
|
53
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sefinek/google-tts-api",
|
|
3
|
-
"version": "2.1.
|
|
4
|
-
"description": "Google TTS (Text-To-Speech) for
|
|
3
|
+
"version": "2.1.3",
|
|
4
|
+
"description": "Google TTS (Text-To-Speech) for Node.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tts",
|
|
7
7
|
"google",
|
|
@@ -20,6 +20,16 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"author": "zlargon",
|
|
22
22
|
"main": "dist/index.js",
|
|
23
|
+
"directories": {
|
|
24
|
+
"example": "example",
|
|
25
|
+
"dist": "dist"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist/",
|
|
29
|
+
"example/",
|
|
30
|
+
"LICENSE",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
23
33
|
"scripts": {
|
|
24
34
|
"build": "tsc -p .",
|
|
25
35
|
"cover": "npm run build && jest --coverage",
|
package/.eslintrc.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
'env': {
|
|
3
|
-
'es6': true,
|
|
4
|
-
'node': true,
|
|
5
|
-
'browser': true,
|
|
6
|
-
'mongo': true,
|
|
7
|
-
},
|
|
8
|
-
'extends': ['eslint:recommended'],
|
|
9
|
-
'parserOptions': {
|
|
10
|
-
'ecmaVersion': 2023,
|
|
11
|
-
},
|
|
12
|
-
'rules': {
|
|
13
|
-
'arrow-spacing': ['warn', { before: true, after: true }],
|
|
14
|
-
// 'brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
|
|
15
|
-
'comma-dangle': ['error', 'always-multiline'],
|
|
16
|
-
'comma-spacing': 'error',
|
|
17
|
-
'comma-style': 'error',
|
|
18
|
-
'curly': ['error', 'multi-line', 'consistent'],
|
|
19
|
-
'dot-location': ['error', 'property'],
|
|
20
|
-
'handle-callback-err': 'off',
|
|
21
|
-
'indent': ['warn', 'tab'],
|
|
22
|
-
'keyword-spacing': 'warn',
|
|
23
|
-
'max-nested-callbacks': ['error', { max: 4 }],
|
|
24
|
-
'max-statements-per-line': ['error', { max: 2 }],
|
|
25
|
-
'no-console': 'off',
|
|
26
|
-
'no-empty': 'warn',
|
|
27
|
-
'no-empty-function': 'error',
|
|
28
|
-
'no-floating-decimal': 'error',
|
|
29
|
-
// 'no-inline-comments': 'error',
|
|
30
|
-
'no-lonely-if': 'error',
|
|
31
|
-
'no-multi-spaces': 'warn',
|
|
32
|
-
'no-multiple-empty-lines': ['warn', { 'max': 4, 'maxEOF': 1, 'maxBOF': 0 }],
|
|
33
|
-
'no-shadow': ['error', { allow: ['err', 'resolve', 'reject'] }],
|
|
34
|
-
'no-trailing-spaces': ['warn'],
|
|
35
|
-
'no-var': 'error',
|
|
36
|
-
'object-curly-spacing': ['error', 'always'],
|
|
37
|
-
'prefer-const': 'error',
|
|
38
|
-
'quotes': ['warn', 'single'],
|
|
39
|
-
'semi': ['warn', 'always'],
|
|
40
|
-
'space-before-blocks': 'error',
|
|
41
|
-
'space-before-function-paren': ['error', {
|
|
42
|
-
anonymous: 'never',
|
|
43
|
-
named: 'never',
|
|
44
|
-
asyncArrow: 'always',
|
|
45
|
-
}],
|
|
46
|
-
'space-in-parens': 'error',
|
|
47
|
-
'space-infix-ops': 'error',
|
|
48
|
-
'space-unary-ops': 'error',
|
|
49
|
-
'spaced-comment': 'warn',
|
|
50
|
-
'yoda': 'error',
|
|
51
|
-
'no-use-before-define': ['error', { functions: false, classes: true }],
|
|
52
|
-
'no-unused-vars': 'warn',
|
|
53
|
-
'wrap-regex': 'error',
|
|
54
|
-
'sort-vars': 'warn',
|
|
55
|
-
'no-unreachable': 'warn',
|
|
56
|
-
},
|
|
57
|
-
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
|
2
|
-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
|
3
|
-
|
|
4
|
-
name: google-tts
|
|
5
|
-
on: [push, pull_request]
|
|
6
|
-
jobs:
|
|
7
|
-
test:
|
|
8
|
-
runs-on: ${{ matrix.os }}
|
|
9
|
-
strategy:
|
|
10
|
-
matrix:
|
|
11
|
-
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
12
|
-
node-version: [10.x, 12.x, 14.x, 15.x, 18.x, 20.x]
|
|
13
|
-
steps:
|
|
14
|
-
- uses: actions/checkout@v4
|
|
15
|
-
- name: Use Node.js ${{ matrix.node-version }}
|
|
16
|
-
uses: actions/setup-node@v4
|
|
17
|
-
with:
|
|
18
|
-
node-version: ${{ matrix.node-version }}
|
|
19
|
-
- run: npm ci
|
|
20
|
-
- run: npm run build
|
|
21
|
-
- run: npm run cover
|
|
22
|
-
- uses: coverallsapp/github-action@v2
|
|
23
|
-
with:
|
|
24
|
-
github-token: ${{ secrets.github_token }}
|
|
25
|
-
upload-code-coverage-report:
|
|
26
|
-
needs: test
|
|
27
|
-
runs-on: ubuntu-latest
|
|
28
|
-
steps:
|
|
29
|
-
- uses: coverallsapp/github-action@v2
|
|
30
|
-
with:
|
|
31
|
-
github-token: ${{ secrets.github_token }}
|
|
32
|
-
parallel-finished: true
|
package/.idea/discord.xml
DELETED
package/.idea/google-tts-api.iml
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<module type="WEB_MODULE" version="4">
|
|
3
|
-
<component name="NewModuleRootManager">
|
|
4
|
-
<content url="file://$MODULE_DIR$">
|
|
5
|
-
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
6
|
-
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
7
|
-
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
8
|
-
</content>
|
|
9
|
-
<orderEntry type="inheritedJdk" />
|
|
10
|
-
<orderEntry type="sourceFolder" forTests="false" />
|
|
11
|
-
</component>
|
|
12
|
-
</module>
|
package/.idea/modules.xml
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectModuleManager">
|
|
4
|
-
<modules>
|
|
5
|
-
<module fileurl="file://$PROJECT_DIR$/.idea/google-tts-api.iml" filepath="$PROJECT_DIR$/.idea/google-tts-api.iml" />
|
|
6
|
-
</modules>
|
|
7
|
-
</component>
|
|
8
|
-
</project>
|
package/.idea/vcs.xml
DELETED
package/CHANGELOG.md
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
## 2.0.2 (Mar 20, 2021)
|
|
2
|
-
- Change default language to `en` ([#45](https://github.com/sefinek24/google-tts-api/issues/45))
|
|
3
|
-
- Typescript: Remove type `Language` since API doesn't fully support language codes listed in the document
|
|
4
|
-
|
|
5
|
-
## 2.0.1 (Jan 6, 2021)
|
|
6
|
-
- Fix the vulnerabilities by upgrading the dependencies (#42, #44)
|
|
7
|
-
|
|
8
|
-
## 2.0.0 (Dec 8, 2020)
|
|
9
|
-
- Add new APIs (Please see the **Break Change** below)
|
|
10
|
-
|
|
11
|
-
| Method | Options (optional) | Return Type | Handle Long Text |
|
|
12
|
-
|---------------------|-------------------------------------------------|-----------------------------------------------------|:----------------:|
|
|
13
|
-
| `getAudioUrl` | `lang`, `slow`, `host` | `string` | |
|
|
14
|
-
| `getAudioBase64` | `lang`, `slow`, `host`, `timeout` | `Promise<string>` | |
|
|
15
|
-
| `getAllAudioUrls` | `lang`, `slow`, `host`, `splitPunct` | `{ shortText: string; url: string; }[]` | ✅ |
|
|
16
|
-
| `getAllAudioBase64` | `lang`, `slow`, `host`, `timeout`, `splitPunct` | `Promise<{ shortText: string; base64: string; }[]>` | ✅ |
|
|
17
|
-
|
|
18
|
-
- Support new Google TTS API to get audio Base64 text ([#35](https://github.com/sefinek24/google-tts-api/issues/35))
|
|
19
|
-
- Support long text input: `getAllAudioUrls` and `getAllAudioBase64` ([#30](https://github.com/sefinek24/google-tts-api/issues/30))
|
|
20
|
-
- Support changing the `host` in option ([#16](https://github.com/sefinek24/google-tts-api/issues/16))
|
|
21
|
-
- Support Typescript
|
|
22
|
-
- Add dependency [axios](https://github.com/axios/axios)
|
|
23
|
-
|
|
24
|
-
### **Break Change from 0.x.x to 2.x.x**
|
|
25
|
-
`googleTTS()` is changed to `googleTTS.getAudioUrl()`.
|
|
26
|
-
|
|
27
|
-
```js
|
|
28
|
-
const googleTTS = require('@sefinek/google-tts-api');
|
|
29
|
-
|
|
30
|
-
// Before version 0.0.6
|
|
31
|
-
// Original googleTTS is a promise function
|
|
32
|
-
const url = await googleTTS('Hello World', 'en', 1);
|
|
33
|
-
|
|
34
|
-
// After version 2.0.0
|
|
35
|
-
// Now googleTTS is an object with 4 new methods (getAudioUrl, getAudioBase64, getAllAudioUrls, getAllAudioBase64)
|
|
36
|
-
// googleTTS.getAudioUrl is a non-promise function
|
|
37
|
-
const url = googleTTS.getAudioUrl('Hello World', {
|
|
38
|
-
lang: 'en-US',
|
|
39
|
-
slow: false, // speed (number) is changed to slow (boolean)
|
|
40
|
-
host: 'https://translate.google.com', // allow to change the host
|
|
41
|
-
});
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## 0.0.6 (Dec 5, 2020)
|
|
45
|
-
- `timeout` parameter is deprecated.
|
|
46
|
-
- Remove dependency `isomorphic-fetch`.
|
|
47
|
-
- Fix the change of Google Translate API ([@freddiefujiwara](https://github.com/freddiefujiwara) in [#37](https://github.com/sefinek24/google-tts-api/pull/37)). Read more in [#35](https://github.com/sefinek24/google-tts-api/issues/35)
|
|
48
|
-
|
|
49
|
-
## 0.0.5 (Nov 8, 2020)
|
|
50
|
-
- Upgrade the dependencies and fix the vulnerability. ([#32](https://github.com/sefinek24/google-tts-api/issues/32))
|
|
51
|
-
- Add retry mechanism to prevent fetching token key failed too frequently. ([#33](https://github.com/sefinek24/google-tts-api/issues/33))
|
|
52
|
-
|
|
53
|
-
## 0.0.4 (Nov 29, 2018)
|
|
54
|
-
- Fix the change of Google Translate API ([@ncpierson](https://github.com/ncpierson) in [#19](https://github.com/sefinek24/google-tts-api/pull/19))
|
|
55
|
-
|
|
56
|
-
## 0.0.3 (Sep 21, 2018)
|
|
57
|
-
- Add package-lock.lock file
|
|
58
|
-
- Fix the change of Google Translate API ([@ncpierson](https://github.com/ncpierson) in [#14](https://github.com/sefinek24/google-tts-api/pull/14))
|
|
59
|
-
|
|
60
|
-
## 0.0.2 (Aug 25, 2017)
|
|
61
|
-
- Add yarn.lock file
|
|
62
|
-
- If length of input text is over than 200 characters, throw a `RangeError` with error message. ([#5](https://github.com/sefinek24/google-tts-api/issues/5))
|
package/tsconfig.json
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
|
4
|
-
|
|
5
|
-
/* Basic Options */
|
|
6
|
-
// "incremental": true, /* Enable incremental compilation */
|
|
7
|
-
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
|
8
|
-
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
|
9
|
-
// "lib": [], /* Specify library files to be included in the compilation. */
|
|
10
|
-
// "allowJs": true, /* Allow javascript files to be compiled. */
|
|
11
|
-
// "checkJs": true, /* Report errors in .js files. */
|
|
12
|
-
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
|
13
|
-
"declaration": true, /* Generates corresponding '.d.ts' file. */
|
|
14
|
-
"declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
|
15
|
-
"sourceMap": true, /* Generates corresponding '.map' file. */
|
|
16
|
-
// "outFile": "./", /* Concatenate and emit output to single file. */
|
|
17
|
-
"outDir": "./dist", /* Redirect output structure to the directory. */
|
|
18
|
-
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
|
19
|
-
// "composite": true, /* Enable project compilation */
|
|
20
|
-
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
|
21
|
-
// "removeComments": true, /* Do not emit comments to output. */
|
|
22
|
-
// "noEmit": true, /* Do not emit outputs. */
|
|
23
|
-
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
|
24
|
-
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
|
25
|
-
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
|
26
|
-
|
|
27
|
-
/* Strict Type-Checking Options */
|
|
28
|
-
"strict": true, /* Enable all strict type-checking options. */
|
|
29
|
-
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
|
30
|
-
// "strictNullChecks": true, /* Enable strict null checks. */
|
|
31
|
-
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
|
32
|
-
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
|
33
|
-
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
|
34
|
-
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
|
35
|
-
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
|
36
|
-
|
|
37
|
-
/* Additional Checks */
|
|
38
|
-
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
|
39
|
-
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
|
40
|
-
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
|
41
|
-
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
|
42
|
-
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
|
43
|
-
|
|
44
|
-
/* Module Resolution Options */
|
|
45
|
-
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
|
46
|
-
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
|
47
|
-
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
|
48
|
-
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
|
49
|
-
// "typeRoots": [], /* List of folders to include type definitions from. */
|
|
50
|
-
// "types": [], /* Type declaration files to be included in compilation. */
|
|
51
|
-
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
|
52
|
-
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
|
53
|
-
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
|
54
|
-
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
|
55
|
-
|
|
56
|
-
/* Source Map Options */
|
|
57
|
-
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
|
58
|
-
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
|
59
|
-
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
|
60
|
-
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
|
61
|
-
|
|
62
|
-
/* Experimental Options */
|
|
63
|
-
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
|
64
|
-
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
|
65
|
-
|
|
66
|
-
/* Advanced Options */
|
|
67
|
-
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
|
68
|
-
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
|
69
|
-
},
|
|
70
|
-
"include": [
|
|
71
|
-
"src"
|
|
72
|
-
]
|
|
73
|
-
}
|