@andresaya/edge-tts 1.1.9 → 1.2.1

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.
@@ -0,0 +1,5 @@
1
+ export declare const Constants: {
2
+ TRUSTED_CLIENT_TOKEN: string;
3
+ WSS_URL: string;
4
+ VOICES_URL: string;
5
+ };
@@ -1,28 +1,8 @@
1
- // @bun
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getProtoOf = Object.getPrototypeOf;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __toESM = (mod, isNodeMode, target) => {
8
- target = mod != null ? __create(__getProtoOf(mod)) : {};
9
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
- for (let key of __getOwnPropNames(mod))
11
- if (!__hasOwnProp.call(to, key))
12
- __defProp(to, key, {
13
- get: () => mod[key],
14
- enumerable: true
15
- });
16
- return to;
17
- };
18
- var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
-
20
- // src/config/constants.ts
21
- var Constants = {
22
- TRUSTED_CLIENT_TOKEN: "6A5AA1D4EAFF4E9FB37E23D68491D6F4",
23
- WSS_URL: "wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1",
24
- VOICES_URL: "https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list"
25
- };
26
- export {
27
- Constants
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Constants = void 0;
4
+ exports.Constants = {
5
+ TRUSTED_CLIENT_TOKEN: '6A5AA1D4EAFF4E9FB37E23D68491D6F4',
6
+ WSS_URL: 'wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1',
7
+ VOICES_URL: 'https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list',
28
8
  };
@@ -0,0 +1 @@
1
+ export { EdgeTTS } from './services/EdgeTTS';
package/dist/index.js CHANGED
@@ -1,139 +1,5 @@
1
- // @bun
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getProtoOf = Object.getPrototypeOf;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __toESM = (mod, isNodeMode, target) => {
8
- target = mod != null ? __create(__getProtoOf(mod)) : {};
9
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
- for (let key of __getOwnPropNames(mod))
11
- if (!__hasOwnProp.call(to, key))
12
- __defProp(to, key, {
13
- get: () => mod[key],
14
- enumerable: true
15
- });
16
- return to;
17
- };
18
- var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
-
20
- // src/config/constants.ts
21
- var Constants = {
22
- TRUSTED_CLIENT_TOKEN: "6A5AA1D4EAFF4E9FB37E23D68491D6F4",
23
- WSS_URL: "wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1",
24
- VOICES_URL: "https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list"
25
- };
26
-
27
- // src/services/EdgeTTS.ts
28
- import WebSocket from "ws";
29
- import {writeFileSync} from "fs";
30
-
31
- class EdgeTTS {
32
- audio_stream = [];
33
- audio_format = "mp3";
34
- ws;
35
- async getVoices() {
36
- const response = await fetch(`${Constants.VOICES_URL}?trustedclienttoken=${Constants.TRUSTED_CLIENT_TOKEN}`);
37
- const data = await response.json();
38
- return data.map((voice) => {
39
- delete voice.VoiceTag;
40
- delete voice.SuggestedCodec;
41
- delete voice.Status;
42
- return voice;
43
- });
44
- }
45
- generateUUID() {
46
- return "xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
47
- const r = Math.random() * 16 | 0;
48
- const v = c === "x" ? r : r & 3 | 8;
49
- return v.toString(16);
50
- });
51
- }
52
- validatePitch(pitch) {
53
- if (!/^(-?\d{1,3}Hz)$/.test(pitch)) {
54
- throw new Error("Invalid pitch format. Expected format: '-100Hz to 100Hz'.");
55
- }
56
- return pitch;
57
- }
58
- validateRate(rate) {
59
- if (!/^(-?\d{1,3}%)$/.test(rate)) {
60
- throw new Error("Invalid rate format. Expected format: '-100% to 100%'.");
61
- }
62
- return rate;
63
- }
64
- validateVolume(volume) {
65
- if (!/^(-?\d{1,3}%)$/.test(volume)) {
66
- throw new Error("Invalid volume format. Expected format: '-100% to 100%'.");
67
- }
68
- return volume;
69
- }
70
- async synthesize(text, voice = "en-US-AnaNeural", options = {}) {
71
- return new Promise((resolve, reject) => {
72
- const req_id = this.generateUUID();
73
- this.ws = new WebSocket(`${Constants.WSS_URL}?trustedclienttoken=${Constants.TRUSTED_CLIENT_TOKEN}&ConnectionId=${req_id}`);
74
- const SSML_text = this.getSSML(text, voice, options);
75
- this.ws.on("open", () => {
76
- const message = this.buildTTSConfigMessage();
77
- this.ws.send(message);
78
- const speechMessage = `X-RequestId:${req_id}\r\nContent-Type:application/ssml+xml\r\nX-Timestamp:${new Date().toISOString()}Z\r\nPath:ssml\r\n\r\n${SSML_text}`;
79
- this.ws.send(speechMessage);
80
- });
81
- this.ws.on("message", (data) => {
82
- this.processAudioData(data);
83
- });
84
- this.ws.on("close", () => {
85
- resolve();
86
- });
87
- this.ws.on("error", (err) => {
88
- reject(err);
89
- });
90
- });
91
- }
92
- getSSML(text, voice, options = {}) {
93
- options.pitch = options.pitch.replace("hz", "Hz");
94
- const pitch = this.validatePitch(options.pitch || "0Hz");
95
- const rate = this.validateRate(options.rate || "0%");
96
- const volume = this.validateVolume(options.volume || "0%");
97
- return `<speak version='1.0' xml:lang='en-US'><voice name='${voice}'><prosody pitch='${pitch}' rate='${rate}' volume='${volume}'>${text}</prosody></voice></speak>`;
98
- }
99
- buildTTSConfigMessage() {
100
- return `X-Timestamp:${new Date().toISOString()}Z\r\nContent-Type:application/json; charset=utf-8\r\nPath:speech.config\r\n\r\n` + `{"context":{"synthesis":{"audio":{"metadataoptions":{"sentenceBoundaryEnabled":false,"wordBoundaryEnabled":true},"outputFormat":"audio-24khz-48kbitrate-mono-mp3"}}}}`;
101
- }
102
- processAudioData(data) {
103
- if (Buffer.isBuffer(data)) {
104
- const needle = Buffer.from("Path:audio\r\n");
105
- const uint8Data = new Uint8Array(data);
106
- const start_ind = uint8Data.indexOf(needle[0]);
107
- if (start_ind !== -1) {
108
- const audioData = data.subarray(start_ind + needle.length);
109
- this.audio_stream.push(audioData);
110
- }
111
- if (data.includes("Path:turn.end")) {
112
- this.ws.close();
113
- }
114
- }
115
- }
116
- async toFile(outputPath) {
117
- if (this.audio_stream.length) {
118
- const audioBuffer = Buffer.concat(this.audio_stream);
119
- const uint8Array = new Uint8Array(audioBuffer);
120
- writeFileSync(`${outputPath}.${this.audio_format}`, uint8Array);
121
- } else {
122
- throw new Error("No audio data available to save.");
123
- }
124
- }
125
- toRaw() {
126
- if (this.audio_stream.length === 0) {
127
- throw new Error("No audio data available.");
128
- }
129
- const audioBuffer = Buffer.concat(this.audio_stream);
130
- return audioBuffer.toString("base64");
131
- }
132
- toBase64() {
133
- const audioBuffer = Buffer.concat(this.audio_stream);
134
- return audioBuffer.toString("base64");
135
- }
136
- }
137
- export {
138
- EdgeTTS
139
- };
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EdgeTTS = void 0;
4
+ var EdgeTTS_1 = require("./services/EdgeTTS");
5
+ Object.defineProperty(exports, "EdgeTTS", { enumerable: true, get: function () { return EdgeTTS_1.EdgeTTS; } });
@@ -0,0 +1,17 @@
1
+ export declare class EdgeTTS {
2
+ private audio_stream;
3
+ private audio_format;
4
+ private ws;
5
+ getVoices(): Promise<any[]>;
6
+ private generateUUID;
7
+ private validatePitch;
8
+ private validateRate;
9
+ private validateVolume;
10
+ synthesize(text: string, voice?: string, options?: any): Promise<void>;
11
+ private getSSML;
12
+ private buildTTSConfigMessage;
13
+ private processAudioData;
14
+ toFile(outputPath: string): Promise<void>;
15
+ toRaw(): string;
16
+ toBase64(): string;
17
+ }
@@ -1,139 +1,118 @@
1
- // @bun
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getProtoOf = Object.getPrototypeOf;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __toESM = (mod, isNodeMode, target) => {
8
- target = mod != null ? __create(__getProtoOf(mod)) : {};
9
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
- for (let key of __getOwnPropNames(mod))
11
- if (!__hasOwnProp.call(to, key))
12
- __defProp(to, key, {
13
- get: () => mod[key],
14
- enumerable: true
15
- });
16
- return to;
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17
4
  };
18
- var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
-
20
- // src/config/constants.ts
21
- var Constants = {
22
- TRUSTED_CLIENT_TOKEN: "6A5AA1D4EAFF4E9FB37E23D68491D6F4",
23
- WSS_URL: "wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1",
24
- VOICES_URL: "https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list"
25
- };
26
-
27
- // src/services/EdgeTTS.ts
28
- import WebSocket from "ws";
29
- import {writeFileSync} from "fs";
30
-
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EdgeTTS = void 0;
7
+ const ws_1 = __importDefault(require("ws"));
8
+ const constants_1 = require("../config/constants");
9
+ const fs_1 = require("fs");
31
10
  class EdgeTTS {
32
- audio_stream = [];
33
- audio_format = "mp3";
34
- ws;
35
- async getVoices() {
36
- const response = await fetch(`${Constants.VOICES_URL}?trustedclienttoken=${Constants.TRUSTED_CLIENT_TOKEN}`);
37
- const data = await response.json();
38
- return data.map((voice) => {
39
- delete voice.VoiceTag;
40
- delete voice.SuggestedCodec;
41
- delete voice.Status;
42
- return voice;
43
- });
44
- }
45
- generateUUID() {
46
- return "xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
47
- const r = Math.random() * 16 | 0;
48
- const v = c === "x" ? r : r & 3 | 8;
49
- return v.toString(16);
50
- });
51
- }
52
- validatePitch(pitch) {
53
- if (!/^(-?\d{1,3}Hz)$/.test(pitch)) {
54
- throw new Error("Invalid pitch format. Expected format: '-100Hz to 100Hz'.");
11
+ audio_stream = [];
12
+ audio_format = 'mp3';
13
+ ws;
14
+ async getVoices() {
15
+ const response = await fetch(`${constants_1.Constants.VOICES_URL}?trustedclienttoken=${constants_1.Constants.TRUSTED_CLIENT_TOKEN}`);
16
+ const data = await response.json();
17
+ return data.map((voice) => {
18
+ delete voice.VoiceTag;
19
+ delete voice.SuggestedCodec;
20
+ delete voice.Status;
21
+ return voice;
22
+ });
23
+ }
24
+ generateUUID() {
25
+ return 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
26
+ const r = Math.random() * 16 | 0;
27
+ const v = c === 'x' ? r : (r & 0x3 | 0x8);
28
+ return v.toString(16);
29
+ });
30
+ }
31
+ validatePitch(pitch) {
32
+ if (!/^(-?\d{1,3}Hz)$/.test(pitch)) {
33
+ throw new Error("Invalid pitch format. Expected format: '-100Hz to 100Hz'.");
34
+ }
35
+ return pitch;
36
+ }
37
+ validateRate(rate) {
38
+ if (!/^(-?\d{1,3}%)$/.test(rate)) {
39
+ throw new Error("Invalid rate format. Expected format: '-100% to 100%'.");
40
+ }
41
+ return rate;
55
42
  }
56
- return pitch;
57
- }
58
- validateRate(rate) {
59
- if (!/^(-?\d{1,3}%)$/.test(rate)) {
60
- throw new Error("Invalid rate format. Expected format: '-100% to 100%'.");
43
+ validateVolume(volume) {
44
+ if (!/^(-?\d{1,3}%)$/.test(volume)) {
45
+ throw new Error("Invalid volume format. Expected format: '-100% to 100%'.");
46
+ }
47
+ return volume;
61
48
  }
62
- return rate;
63
- }
64
- validateVolume(volume) {
65
- if (!/^(-?\d{1,3}%)$/.test(volume)) {
66
- throw new Error("Invalid volume format. Expected format: '-100% to 100%'.");
49
+ async synthesize(text, voice = 'en-US-AnaNeural', options = {}) {
50
+ return new Promise((resolve, reject) => {
51
+ const req_id = this.generateUUID();
52
+ this.ws = new ws_1.default(`${constants_1.Constants.WSS_URL}?trustedclienttoken=${constants_1.Constants.TRUSTED_CLIENT_TOKEN}&ConnectionId=${req_id}`);
53
+ const SSML_text = this.getSSML(text, voice, options);
54
+ this.ws.on('open', () => {
55
+ const message = this.buildTTSConfigMessage();
56
+ this.ws.send(message);
57
+ const speechMessage = `X-RequestId:${req_id}\r\nContent-Type:application/ssml+xml\r\nX-Timestamp:${new Date().toISOString()}Z\r\nPath:ssml\r\n\r\n${SSML_text}`;
58
+ this.ws.send(speechMessage);
59
+ });
60
+ this.ws.on('message', (data) => {
61
+ this.processAudioData(data);
62
+ });
63
+ this.ws.on('close', () => {
64
+ resolve();
65
+ });
66
+ this.ws.on('error', (err) => {
67
+ reject(err);
68
+ });
69
+ });
67
70
  }
68
- return volume;
69
- }
70
- async synthesize(text, voice = "en-US-AnaNeural", options = {}) {
71
- return new Promise((resolve, reject) => {
72
- const req_id = this.generateUUID();
73
- this.ws = new WebSocket(`${Constants.WSS_URL}?trustedclienttoken=${Constants.TRUSTED_CLIENT_TOKEN}&ConnectionId=${req_id}`);
74
- const SSML_text = this.getSSML(text, voice, options);
75
- this.ws.on("open", () => {
76
- const message = this.buildTTSConfigMessage();
77
- this.ws.send(message);
78
- const speechMessage = `X-RequestId:${req_id}\r\nContent-Type:application/ssml+xml\r\nX-Timestamp:${new Date().toISOString()}Z\r\nPath:ssml\r\n\r\n${SSML_text}`;
79
- this.ws.send(speechMessage);
80
- });
81
- this.ws.on("message", (data) => {
82
- this.processAudioData(data);
83
- });
84
- this.ws.on("close", () => {
85
- resolve();
86
- });
87
- this.ws.on("error", (err) => {
88
- reject(err);
89
- });
90
- });
91
- }
92
- getSSML(text, voice, options = {}) {
93
- options.pitch = options.pitch.replace("hz", "Hz");
94
- const pitch = this.validatePitch(options.pitch || "0Hz");
95
- const rate = this.validateRate(options.rate || "0%");
96
- const volume = this.validateVolume(options.volume || "0%");
97
- return `<speak version='1.0' xml:lang='en-US'><voice name='${voice}'><prosody pitch='${pitch}' rate='${rate}' volume='${volume}'>${text}</prosody></voice></speak>`;
98
- }
99
- buildTTSConfigMessage() {
100
- return `X-Timestamp:${new Date().toISOString()}Z\r\nContent-Type:application/json; charset=utf-8\r\nPath:speech.config\r\n\r\n` + `{"context":{"synthesis":{"audio":{"metadataoptions":{"sentenceBoundaryEnabled":false,"wordBoundaryEnabled":true},"outputFormat":"audio-24khz-48kbitrate-mono-mp3"}}}}`;
101
- }
102
- processAudioData(data) {
103
- if (Buffer.isBuffer(data)) {
104
- const needle = Buffer.from("Path:audio\r\n");
105
- const uint8Data = new Uint8Array(data);
106
- const start_ind = uint8Data.indexOf(needle[0]);
107
- if (start_ind !== -1) {
108
- const audioData = data.subarray(start_ind + needle.length);
109
- this.audio_stream.push(audioData);
110
- }
111
- if (data.includes("Path:turn.end")) {
112
- this.ws.close();
113
- }
71
+ getSSML(text, voice, options = {}) {
72
+ options.pitch = options.pitch.replace('hz', 'Hz');
73
+ const pitch = this.validatePitch(options.pitch || '0Hz');
74
+ const rate = this.validateRate(options.rate || '0%');
75
+ const volume = this.validateVolume(options.volume || '0%');
76
+ return `<speak version='1.0' xml:lang='en-US'><voice name='${voice}'><prosody pitch='${pitch}' rate='${rate}' volume='${volume}'>${text}</prosody></voice></speak>`;
114
77
  }
115
- }
116
- async toFile(outputPath) {
117
- if (this.audio_stream.length) {
118
- const audioBuffer = Buffer.concat(this.audio_stream);
119
- const uint8Array = new Uint8Array(audioBuffer);
120
- writeFileSync(`${outputPath}.${this.audio_format}`, uint8Array);
121
- } else {
122
- throw new Error("No audio data available to save.");
78
+ buildTTSConfigMessage() {
79
+ return `X-Timestamp:${new Date().toISOString()}Z\r\nContent-Type:application/json; charset=utf-8\r\nPath:speech.config\r\n\r\n` +
80
+ `{"context":{"synthesis":{"audio":{"metadataoptions":{"sentenceBoundaryEnabled":false,"wordBoundaryEnabled":true},"outputFormat":"audio-24khz-48kbitrate-mono-mp3"}}}}`;
123
81
  }
124
- }
125
- toRaw() {
126
- if (this.audio_stream.length === 0) {
127
- throw new Error("No audio data available.");
82
+ processAudioData(data) {
83
+ if (Buffer.isBuffer(data)) {
84
+ const needle = Buffer.from("Path:audio\r\n");
85
+ const uint8Data = new Uint8Array(data);
86
+ const start_ind = uint8Data.indexOf(needle[0]);
87
+ if (start_ind !== -1) {
88
+ const audioData = data.subarray(start_ind + needle.length);
89
+ this.audio_stream.push(audioData);
90
+ }
91
+ if (data.includes("Path:turn.end")) {
92
+ this.ws.close();
93
+ }
94
+ }
95
+ }
96
+ async toFile(outputPath) {
97
+ if (this.audio_stream.length) {
98
+ const audioBuffer = Buffer.concat(this.audio_stream);
99
+ const uint8Array = new Uint8Array(audioBuffer);
100
+ (0, fs_1.writeFileSync)(`${outputPath}.${this.audio_format}`, uint8Array);
101
+ }
102
+ else {
103
+ throw new Error("No audio data available to save.");
104
+ }
105
+ }
106
+ toRaw() {
107
+ if (this.audio_stream.length === 0) {
108
+ throw new Error("No audio data available.");
109
+ }
110
+ const audioBuffer = Buffer.concat(this.audio_stream);
111
+ return audioBuffer.toString('base64');
112
+ }
113
+ toBase64() {
114
+ const audioBuffer = Buffer.concat(this.audio_stream);
115
+ return audioBuffer.toString('base64');
128
116
  }
129
- const audioBuffer = Buffer.concat(this.audio_stream);
130
- return audioBuffer.toString("base64");
131
- }
132
- toBase64() {
133
- const audioBuffer = Buffer.concat(this.audio_stream);
134
- return audioBuffer.toString("base64");
135
- }
136
117
  }
137
- export {
138
- EdgeTTS
139
- };
118
+ exports.EdgeTTS = EdgeTTS;
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "@andresaya/edge-tts",
3
- "version": "1.1.9",
4
- "module": "dist/index.js",
3
+ "version": "1.2.1",
5
4
  "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "type": "module",
5
+
6
+
8
7
  "scripts": {
9
- "build": "bun build src/**/*.ts --outdir dist --target=bun",
8
+ "build": "tsc",
10
9
  "build:bin": "bun scripts/build.ts"
11
10
  },
12
11
  "devDependencies": {