echogarden 0.11.22 → 0.12.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.
Files changed (68) hide show
  1. package/dist/api/API.d.ts +1 -0
  2. package/dist/api/API.js +1 -0
  3. package/dist/api/API.js.map +1 -1
  4. package/dist/api/GlobalOptions.d.ts +6 -0
  5. package/dist/api/GlobalOptions.js +17 -0
  6. package/dist/api/GlobalOptions.js.map +1 -0
  7. package/dist/audio/AudioPlayer.js +2 -1
  8. package/dist/audio/AudioPlayer.js.map +1 -1
  9. package/dist/audio/AudioUtilities.d.ts +4 -4
  10. package/dist/audio/AudioUtilities.js +27 -28
  11. package/dist/audio/AudioUtilities.js.map +1 -1
  12. package/dist/audio/SoxPath.js +18 -17
  13. package/dist/audio/SoxPath.js.map +1 -1
  14. package/dist/cli/CLI.js +2 -1
  15. package/dist/cli/CLI.js.map +1 -1
  16. package/dist/cli/CLILauncher.js +1 -1
  17. package/dist/cli/CLILauncher.js.map +1 -1
  18. package/dist/cli/CLIStarter.js +1 -1
  19. package/dist/cli/CLIStarter.js.map +1 -1
  20. package/dist/codecs/FFMpegTranscoder.js +45 -13
  21. package/dist/codecs/FFMpegTranscoder.js.map +1 -1
  22. package/dist/nlp/Lexicon.js +2 -1
  23. package/dist/nlp/Lexicon.js.map +1 -1
  24. package/dist/server/Worker.js +1 -1
  25. package/dist/server/Worker.js.map +1 -1
  26. package/dist/synthesis/FliteTTS.js +2 -1
  27. package/dist/synthesis/FliteTTS.js.map +1 -1
  28. package/dist/synthesis/VitsTTS.js +68 -0
  29. package/dist/synthesis/VitsTTS.js.map +1 -1
  30. package/dist/utilities/FileSystem.d.ts +0 -4
  31. package/dist/utilities/FileSystem.js +1 -33
  32. package/dist/utilities/FileSystem.js.map +1 -1
  33. package/dist/utilities/Locale.js +2 -1
  34. package/dist/utilities/Locale.js.map +1 -1
  35. package/dist/utilities/NdArrayUtilities.js +1 -0
  36. package/dist/utilities/NdArrayUtilities.js.map +1 -1
  37. package/dist/utilities/PackageManager.js +61 -38
  38. package/dist/utilities/PackageManager.js.map +1 -1
  39. package/dist/utilities/PathUtilities.d.ts +4 -0
  40. package/dist/utilities/PathUtilities.js +36 -0
  41. package/dist/utilities/PathUtilities.js.map +1 -0
  42. package/dist/utilities/TarballMaker.js +2 -1
  43. package/dist/utilities/TarballMaker.js.map +1 -1
  44. package/dist/utilities/Utilities.js +2 -2
  45. package/dist/utilities/Utilities.js.map +1 -1
  46. package/docs/API.md +25 -0
  47. package/docs/Engines.md +1 -1
  48. package/package.json +6 -6
  49. package/src/api/API.ts +1 -0
  50. package/src/api/GlobalOptions.ts +25 -0
  51. package/src/audio/AudioPlayer.ts +2 -1
  52. package/src/audio/AudioUtilities.ts +29 -29
  53. package/src/audio/SoxPath.ts +24 -17
  54. package/src/cli/CLI.ts +2 -1
  55. package/src/cli/CLILauncher.ts +1 -1
  56. package/src/cli/CLIStarter.ts +1 -1
  57. package/src/codecs/FFMpegTranscoder.ts +43 -14
  58. package/src/nlp/Lexicon.ts +2 -1
  59. package/src/server/Worker.ts +2 -2
  60. package/src/synthesis/FliteTTS.ts +2 -1
  61. package/src/synthesis/VitsTTS.ts +72 -0
  62. package/src/utilities/FileSystem.ts +2 -41
  63. package/src/utilities/Locale.ts +2 -1
  64. package/src/utilities/NdArrayUtilities.ts +1 -1
  65. package/src/utilities/PackageManager.ts +69 -44
  66. package/src/utilities/PathUtilities.ts +41 -0
  67. package/src/utilities/TarballMaker.ts +2 -1
  68. package/src/utilities/Utilities.ts +4 -2
@@ -1,24 +1,31 @@
1
- import path from "path"
2
- import { loadPackage } from "../utilities/PackageManager.js"
3
- import { commandExists } from "../utilities/Utilities.js"
1
+ import path from 'path'
2
+ import { loadPackage } from '../utilities/PackageManager.js'
3
+ import { commandExists } from '../utilities/Utilities.js'
4
+ import { getGlobalOption } from '../api/GlobalOptions.js'
4
5
 
5
6
  export async function tryResolvingSoxPath() {
6
- let soxPath: string | undefined = undefined
7
+ if (getGlobalOption('soxPath')) {
8
+ return getGlobalOption('soxPath')
9
+ }
10
+
11
+ const platform = process.platform
12
+ const arch = process.arch
7
13
 
8
- if (process.platform == "win32") {
9
- const soxPackagePath = await loadPackage("sox-14.4.1a-win32")
10
- soxPath = path.join(soxPackagePath, "sox.exe")
14
+ if (platform === 'win32') {
15
+ const soxPackagePath = await loadPackage('sox-14.4.1a-win32')
16
+
17
+ return path.join(soxPackagePath, 'sox.exe')
11
18
  }
12
- /*else if (process.platform == "darwin" && process.arch == "x64") {
13
- const soxPackagePath = await loadPackage("sox-14.4.1-macosx")
14
- soxPath = path.join(soxPackagePath, "sox")
15
- } */
16
- else if (process.platform == "linux" && process.arch == "x64") {
17
- const soxPackagePath = await loadPackage("sox-14.4.2-linux-minimal")
18
- soxPath = path.join(soxPackagePath, "sox")
19
- } else if (await commandExists("sox")) {
20
- soxPath = "sox"
19
+
20
+ if (await commandExists('sox')) {
21
+ return 'sox'
22
+ }
23
+
24
+ if (platform === 'linux' && arch === 'x64') {
25
+ const soxPackagePath = await loadPackage('sox-14.4.2-linux-minimal')
26
+
27
+ return path.join(soxPackagePath, 'sox')
21
28
  }
22
29
 
23
- return soxPath
30
+ return undefined
24
31
  }
package/src/cli/CLI.ts CHANGED
@@ -15,7 +15,7 @@ import { splitToParagraphs, splitToWords, wordCharacterPattern } from "../nlp/Se
15
15
  import { playAudioSamples, playAudioWithWordTimeline } from "../audio/AudioPlayer.js"
16
16
  import { extendDeep } from "../utilities/ObjectUtilities.js"
17
17
  import { Timeline, TimelineEntry, addTimeOffsetToTimeline, addWordTextOffsetsToTimeline, roundTimelineProperties, wordTimelineToSegmentSentenceTimeline } from "../utilities/Timeline.js"
18
- import { ensureDir, existsSync, getLowercaseFileExtension, readAndParseJsonFile, readFile, readdir, resolveToModuleRootDir, writeFileSafe } from '../utilities/FileSystem.js'
18
+ import { ensureDir, existsSync, readAndParseJsonFile, readFile, readdir, writeFileSafe } from '../utilities/FileSystem.js'
19
19
  import { formatLanguageCodeWithName, getShortLanguageCode } from '../utilities/Locale.js'
20
20
  import { APIOptions } from '../api/APIOptions.js'
21
21
  import { ensureAndGetPackagesDir, getVersionTagFromPackageName, loadPackage, resolveVersionTagForUnversionedPackageName } from '../utilities/PackageManager.js'
@@ -24,6 +24,7 @@ import { appName } from '../api/Common.js'
24
24
  import { ServerOptions, startServer } from '../server/Server.js'
25
25
  import { OpenPromise } from '../utilities/OpenPromise.js'
26
26
  import JSON5 from 'json5'
27
+ import { getLowercaseFileExtension, resolveToModuleRootDir } from '../utilities/PathUtilities.js'
27
28
 
28
29
  //const log = logToStderr
29
30
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { spawn } from 'child_process'
4
4
  import { setupUnhandledExceptionListeners } from '../utilities/Utilities.js'
5
- import { resolveToModuleRootDir } from '../utilities/FileSystem.js'
5
+ import { resolveToModuleRootDir } from '../utilities/PathUtilities.js'
6
6
 
7
7
  setupUnhandledExceptionListeners()
8
8
 
@@ -1,4 +1,4 @@
1
- import { resolveToModuleRootDir } from '../utilities/FileSystem.js'
1
+ import { resolveToModuleRootDir } from '../utilities/PathUtilities.js'
2
2
  import { setupProgramTerminationListeners, setupUnhandledExceptionListeners, writeToStderr } from '../utilities/Utilities.js'
3
3
  import { Worker, SHARE_ENV } from 'node:worker_threads'
4
4
 
@@ -6,6 +6,7 @@ import { Logger } from "../utilities/Logger.js"
6
6
  import { commandExists, logToStderr } from "../utilities/Utilities.js"
7
7
  import path from "node:path"
8
8
  import { loadPackage } from "../utilities/PackageManager.js"
9
+ import { getGlobalOption } from "../api/GlobalOptions.js"
9
10
 
10
11
  const log = logToStderr
11
12
 
@@ -147,25 +148,53 @@ function buildCommandLineArguments(inputFilename: string, outputOptions: FFMpegO
147
148
  }
148
149
 
149
150
  async function getFFMpegExecutablePath() {
150
- if (process.platform == "win32") {
151
- const ffmpegPackagePath = await loadPackage("ffmpeg-6.0-essentials-win64")
152
-
153
- return path.join(ffmpegPackagePath, "ffmpeg.exe")
151
+ // If a global option set for the path, use it
152
+ if (getGlobalOption('ffmpegPath')) {
153
+ return getGlobalOption('ffmpegPath')
154
+ }
155
+
156
+ // If an 'ffmpeg' command exist in system path, use it
157
+ if (await commandExists('ffmpeg')) {
158
+ return 'ffmpeg'
159
+ }
160
+
161
+ // Otherwise, download and use an internal ffmpeg package
162
+ const platform = process.platform
163
+ const arch = process.arch
164
+
165
+ let packageName: string
166
+
167
+ if (platform === 'win32' && arch === 'x64') {
168
+ packageName = 'ffmpeg-6.0-win32-x64'
169
+ } else if (platform === 'win32' && arch === 'ia32') {
170
+ packageName = 'ffmpeg-6.0-win32-ia32'
171
+ } else if (platform === 'darwin' && arch === 'x64') {
172
+ packageName = 'ffmpeg-6.0-darwin-x64'
173
+ } else if (platform === 'darwin' && arch === 'arm64') {
174
+ packageName = 'ffmpeg-6.0-darwin-arm64'
175
+ } else if (platform === 'linux' && arch === 'x64') {
176
+ packageName = 'ffmpeg-6.0-linux-x64'
177
+ } else if (platform === 'linux' && arch === 'ia32') {
178
+ packageName = 'ffmpeg-6.0-linux-ia32'
179
+ } else if (platform === 'linux' && arch === 'arm64') {
180
+ packageName = 'ffmpeg-6.0-linux-arm64'
181
+ } else if (platform === 'linux' && arch === 'arm') {
182
+ packageName = 'ffmpeg-6.0-linux-arm'
183
+ } else if (platform === 'freebsd' && arch === 'x64') {
184
+ packageName = 'ffmpeg-6.0-freebsd-x64'
185
+ } else {
186
+ return undefined
154
187
  }
155
- /* else if (process.platform == "darwin" && process.arch == "x64") {
156
- const ffmpegPackagePath = await loadPackage("ffmpeg-6.0-macos64")
157
188
 
158
- return path.join(ffmpegPackagePath, "ffmpeg")
159
- }
160
- */ else if (process.platform == "linux" && process.arch == "x64") {
161
- const ffmpegPackagePath = await loadPackage("ffmpeg-6.0-linux-amd64")
189
+ const ffmpegPackagePath = await loadPackage(packageName)
190
+
191
+ let filename = packageName
162
192
 
163
- return path.join(ffmpegPackagePath, "ffmpeg")
164
- } else if (await commandExists("ffmpeg")) {
165
- return "ffmpeg"
193
+ if (platform === 'win32') {
194
+ filename += '.exe'
166
195
  }
167
196
 
168
- return undefined
197
+ return path.join(ffmpegPackagePath, filename)
169
198
  }
170
199
 
171
200
  export function getDefaultFFMpegOptionsForSpeech(fileExtension: string, customBitrate?: number) {
@@ -1,5 +1,6 @@
1
- import { readAndParseJsonFile, resolveToModuleRootDir } from "../utilities/FileSystem.js"
1
+ import { readAndParseJsonFile } from "../utilities/FileSystem.js"
2
2
  import { getShortLanguageCode } from "../utilities/Locale.js"
3
+ import { resolveToModuleRootDir } from "../utilities/PathUtilities.js"
3
4
 
4
5
  export function tryGetFirstLexiconSubstitution(sentenceWords: string[], wordIndex: number, lexicons: Lexicon[], languageCode: string) {
5
6
  const reversedLexicons = [...lexicons].reverse() // Give precedence to later lexicons
@@ -5,12 +5,12 @@ import { AudioSourceParam } from "../audio/AudioUtilities.js"
5
5
  import { RecognitionOptions, RecognitionResult, recognize } from "../api/Recognition.js"
6
6
  import { AlignmentOptions, AlignmentResult, align } from "../api/Alignment.js"
7
7
  import { SpeechTranslationOptions, SpeechTranslationResult, translateSpeech } from "../api/Translation.js"
8
- import { Logger, resetActiveLogger } from "../utilities/Logger.js"
8
+ import { resetActiveLogger } from "../utilities/Logger.js"
9
9
  import { writeToStderr } from '../utilities/Utilities.js'
10
- import { resolveToModuleRootDir } from '../utilities/FileSystem.js'
11
10
  import { Worker, SHARE_ENV } from 'node:worker_threads'
12
11
  import { SpeechLanguageDetectionOptions, SpeechLanguageDetectionResult, TextLanguageDetectionOptions, TextLanguageDetectionResult, detectSpeechLanguage, detectTextLanguage } from "../api/LanguageDetection.js"
13
12
  import chalk from "chalk"
13
+ import { resolveToModuleRootDir } from "../utilities/PathUtilities.js"
14
14
 
15
15
  const log = logToStderr
16
16
 
@@ -2,9 +2,10 @@ import { SynthesisVoice } from "../api/API.js"
2
2
  import { decodeWaveBuffer } from "../audio/AudioUtilities.js"
3
3
  import { Logger } from "../utilities/Logger.js"
4
4
  import { getRandomHexString, logToStderr, resolveModuleMainPath } from "../utilities/Utilities.js"
5
- import { getAppTempDir, readFile, open, close, remove, ensureDir } from "../utilities/FileSystem.js"
5
+ import { readFile, open, close, remove, ensureDir } from "../utilities/FileSystem.js"
6
6
  import path from "node:path"
7
7
  import { escape } from 'html-escaper'
8
+ import { getAppTempDir } from "../utilities/PathUtilities.js"
8
9
 
9
10
  const log = logToStderr
10
11
 
@@ -293,6 +293,12 @@ export const voiceList: SynthesisVoice[] = [
293
293
  languages: ["de-DE", "de"],
294
294
  gender: "male",
295
295
  },
296
+ {
297
+ name: "de_DE-mls-medium",
298
+ languages: ["de-DE", "de"],
299
+ gender: "unknown",
300
+ speakerCount: 236
301
+ },
296
302
 
297
303
  {
298
304
  name: "el_GR-rapunzelina-low",
@@ -353,6 +359,12 @@ export const voiceList: SynthesisVoice[] = [
353
359
  languages: ["en-GB", "en"],
354
360
  gender: "female",
355
361
  },
362
+ {
363
+ name: "en_GB-cori-high",
364
+ languages: ["en-GB", "en"],
365
+ gender: "female",
366
+ },
367
+
356
368
 
357
369
  {
358
370
  name: "en_US-amy-low",
@@ -443,6 +455,21 @@ export const voiceList: SynthesisVoice[] = [
443
455
  languages: ["en-US", "en"],
444
456
  gender: "female",
445
457
  },
458
+ {
459
+ name: "en_US-kristin-medium",
460
+ languages: ["en-US", "en"],
461
+ gender: "female",
462
+ },
463
+ {
464
+ name: "en_US-ljspeech-high",
465
+ languages: ["en-US", "en"],
466
+ gender: "female",
467
+ },
468
+ {
469
+ name: "en_US-ljspeech-medium",
470
+ languages: ["en-US", "en"],
471
+ gender: "female",
472
+ },
446
473
 
447
474
  {
448
475
  name: "es_ES-carlfm-x_low",
@@ -476,6 +503,23 @@ export const voiceList: SynthesisVoice[] = [
476
503
  languages: ["es-MX", "es"],
477
504
  gender: "male",
478
505
  },
506
+ {
507
+ name: "es_MX-claude-high",
508
+ languages: ["es-MX", "es"],
509
+ gender: "female",
510
+ },
511
+
512
+ {
513
+ name: "fa_IR-amir-medium",
514
+ languages: ["fa_IR", "fa"],
515
+ gender: "male",
516
+ },
517
+ {
518
+ name: "fa_IR-gyro-medium",
519
+ languages: ["fa_IR", "fa"],
520
+ gender: "male",
521
+ },
522
+
479
523
 
480
524
  {
481
525
  name: "fi_FI-harri-low",
@@ -514,6 +558,17 @@ export const voiceList: SynthesisVoice[] = [
514
558
  gender: "unknown",
515
559
  speakerCount: 2
516
560
  },
561
+ {
562
+ name: "fr_FR-mls-medium",
563
+ languages: ["fr-FR", "fr"],
564
+ gender: "unknown",
565
+ speakerCount: 125
566
+ },
567
+ {
568
+ name: "fr_FR-tom-medium",
569
+ languages: ["fr-FR", "fr"],
570
+ gender: "male",
571
+ },
517
572
 
518
573
  {
519
574
  name: "hu_HU-anna-medium",
@@ -605,6 +660,12 @@ export const voiceList: SynthesisVoice[] = [
605
660
  languages: ["nl-NL", "nl"],
606
661
  gender: "female",
607
662
  },
663
+ {
664
+ name: "nl_NL-mls-medium",
665
+ languages: ["nl-NL", "nl"],
666
+ gender: "unknown",
667
+ speakerCount: 52,
668
+ },
608
669
 
609
670
  {
610
671
  name: "nl_BE-nathalie-x_low",
@@ -705,6 +766,12 @@ export const voiceList: SynthesisVoice[] = [
705
766
  gender: "female",
706
767
  },
707
768
 
769
+ {
770
+ name: "sl_SI-artur-medium",
771
+ languages: ["sl_SI", "sl"],
772
+ gender: "male",
773
+ },
774
+
708
775
  {
709
776
  name: "sr_RS-serbski_institut-medium",
710
777
  languages: ["sr-RS", "sr"],
@@ -734,6 +801,11 @@ export const voiceList: SynthesisVoice[] = [
734
801
  languages: ["tr-TR", "tr"],
735
802
  gender: "male",
736
803
  },
804
+ {
805
+ name: "tr_TR-fettah-medium",
806
+ languages: ["tr-TR", "tr"],
807
+ gender: "male",
808
+ },
737
809
 
738
810
  {
739
811
  name: "uk_UA-lada-x_low",
@@ -3,11 +3,11 @@ import gracefulFS from 'graceful-fs'
3
3
  import * as os from 'node:os'
4
4
 
5
5
  import path from 'node:path'
6
- import { fileURLToPath } from 'node:url'
7
6
  import { promisify } from 'node:util'
8
7
  import { OpenPromise } from './OpenPromise.js'
9
- import { getRandomHexString, sha256AsHex } from './Utilities.js'
8
+ import { getRandomHexString } from './Utilities.js'
10
9
  import { appName } from '../api/Common.js'
10
+ import { getAppTempDir } from './PathUtilities.js'
11
11
 
12
12
  export const readFile = promisify(gracefulFS.readFile)
13
13
  //export const writeFile = promisify(gracefulFS.writeFile)
@@ -19,7 +19,6 @@ export const chmod = promisify(gracefulFS.chmod)
19
19
  export const copyFile = promisify(gracefulFS.copyFile)
20
20
  export const access = promisify(gracefulFS.access)
21
21
 
22
-
23
22
  export const createReadStream = gracefulFS.createReadStream
24
23
  export const createWriteStream = gracefulFS.createWriteStream
25
24
  export const existsSync = gracefulFS.existsSync
@@ -71,25 +70,6 @@ export async function isFileIsUpToDate(filePath: string, timeRangeSeconds: numbe
71
70
  return differenceInSeconds <= timeRangeSeconds
72
71
  }
73
72
 
74
- export function getModuleRootDir() {
75
- const currentScriptDir = path.dirname(fileURLToPath(import.meta.url))
76
- return path.resolve(currentScriptDir, '..', '..')
77
- }
78
-
79
- export function resolveToModuleRootDir(relativePath: string) {
80
- return path.resolve(getModuleRootDir(), relativePath)
81
- }
82
-
83
- export function getLowercaseFileExtension(filename: string) {
84
- const fileExtensionIndex = filename.lastIndexOf(".")
85
-
86
- if (fileExtensionIndex == -1) {
87
- return ""
88
- }
89
-
90
- return filename.substring(fileExtensionIndex + 1).toLowerCase()
91
- }
92
-
93
73
  export async function computeFileSha256Hex(filePath: string) {
94
74
  const resultOpenPromise = new OpenPromise<string>()
95
75
 
@@ -130,25 +110,6 @@ export async function writeFileSafe(filePath: string, data: string | NodeJS.Arra
130
110
  await move(tempFilePath, filePath)
131
111
  }
132
112
 
133
- export function getAppTempDir(appName: string) {
134
- let tempDir: string
135
-
136
- const platform = process.platform
137
- const homeDir = os.homedir()
138
-
139
- if (platform == "win32") {
140
- tempDir = path.join(homeDir, "AppData", "Local", "Temp", appName)
141
- } else if (platform == "darwin") {
142
- tempDir = path.join(homeDir, "Library", "Caches", appName)
143
- } else if (platform == "linux") {
144
- tempDir = path.join(homeDir, ".cache", appName)
145
- } else {
146
- throw new Error(`Unsupport platform ${platform}`)
147
- }
148
-
149
- return tempDir
150
- }
151
-
152
113
  export function getAppDataDir(appName: string) {
153
114
  let dataDir: string
154
115
 
@@ -1,4 +1,5 @@
1
- import { readAndParseJsonFile, resolveToModuleRootDir } from "./FileSystem.js"
1
+ import { readAndParseJsonFile } from "./FileSystem.js"
2
+ import { resolveToModuleRootDir } from "./PathUtilities.js"
2
3
 
3
4
  export function languageCodeToName(languageCode: string) {
4
5
  const languageNames = new Intl.DisplayNames(['en'], { type: 'language' })
@@ -1,5 +1,5 @@
1
1
  import ndarray from 'ndarray'
2
- import ops from 'ndarray-ops'
2
+ // import ops from 'ndarray-ops'
3
3
  import { medianFilter, softmax } from '../math/VectorMath.js'
4
4
 
5
5
  export function ndarraySoftMax(vector: ndarray.NdArray, temperature = 1.0) {
@@ -1,8 +1,9 @@
1
- import path from "node:path"
2
- import { downloadAndExtractTarball } from "./FileDownloader.js"
3
- import { getAppDataDir, getAppTempDir, ensureDir, existsSync, remove } from "./FileSystem.js"
4
- import { appName } from "../api/Common.js"
5
- import { GaxiosOptions } from "gaxios"
1
+ import path from 'node:path'
2
+ import { downloadAndExtractTarball } from './FileDownloader.js'
3
+ import { getAppDataDir, ensureDir, existsSync, remove } from './FileSystem.js'
4
+ import { appName } from '../api/Common.js'
5
+ import { GaxiosOptions } from 'gaxios'
6
+ import { getAppTempDir } from './PathUtilities.js'
6
7
 
7
8
  export async function loadPackage(packageName: string) {
8
9
  packageName = resolveToVersionedPackageNameIfNeeded(packageName)
@@ -48,7 +49,7 @@ export async function removePackage(packageName: string) {
48
49
  export async function ensureAndGetPackagesDir() {
49
50
  const dataPath = getAppDataDir(appName)
50
51
 
51
- const packagesPath = path.join(dataPath, "packages")
52
+ const packagesPath = path.join(dataPath, 'packages')
52
53
 
53
54
  await ensureDir(packagesPath)
54
55
 
@@ -75,45 +76,69 @@ export function resolveVersionTagForUnversionedPackageName(unversionedPackageNam
75
76
  return packageVersionTagResolutionLookup[unversionedPackageName] || defaultVersionTag
76
77
  }
77
78
 
78
- const basePackageUrl = "https://huggingface.co/echogarden/echogarden-packages/resolve/main/"
79
+ const basePackageUrl = 'https://huggingface.co/echogarden/echogarden-packages/resolve/main/'
79
80
 
80
- const defaultVersionTag = "20230718"
81
+ const defaultVersionTag = '20230718'
81
82
 
82
83
  const packageVersionTagResolutionLookup: { [packageName: string]: string } = {
83
- "sox-14.4.2-linux-minimal": "20230802",
84
-
85
- "vits-de_DE-thorsten_emotional-medium": "20230808",
86
- "vits-en_GB-semaine-medium": "20230808",
87
- "vits-fr_FR-upmc-medium": "20230808",
88
- "vits-lb_LU-marylux-medium": "20230808",
89
- "vits-ro_RO-mihai-medium": "20230808",
90
- "vits-sr_RS-serbski_institut-medium": "20230808",
91
- "vits-tr_TR-dfki-medium": "20230808",
92
-
93
- "vits-cs_CZ-jirka-medium": "20230824",
94
- "vits-de_DE-thorsten-high": "20230824",
95
- "vits-hu_HU-anna-medium": "20230824",
96
- "vits-pt_PT-tugao-medium": "20230824",
97
- "vits-sk_SK-lili-medium": "20230824",
98
- "vits-tr_TR-fahrettin-medium": "20230824",
99
-
100
- "vits-ar_JO-kareem-medium": "20231022",
101
- "vits-cs_CZ-jirka-low": "20231022",
102
- "vits-en_US-hfc_male-medium": "20231022",
103
- "vits-en_US-libritts_r-medium": "20231022",
104
- "vits-hu_HU-imre-medium": "20231022",
105
- "vits-pl_PL-mc_speech-medium": "20231022",
106
-
107
- "whisper-tiny": "20231126",
108
- "whisper-tiny.en": "20231126",
109
- "whisper-base": "20231126",
110
- "whisper-base.en": "20231126",
111
- "whisper-small": "20231126",
112
- "whisper-small.en": "20231126",
113
- "whisper-medium": "20231126",
114
- "whisper-medium.en": "20231126",
115
- "whisper-large-v3": "20231126",
116
-
117
- "vits-ar_JO-kareem-low": "20231126",
118
- "vits-en_US-hfc_female-medium": "20231126",
84
+ 'sox-14.4.2-linux-minimal': '20230802',
85
+
86
+ 'vits-de_DE-thorsten_emotional-medium': '20230808',
87
+ 'vits-en_GB-semaine-medium': '20230808',
88
+ 'vits-fr_FR-upmc-medium': '20230808',
89
+ 'vits-lb_LU-marylux-medium': '20230808',
90
+ 'vits-ro_RO-mihai-medium': '20230808',
91
+ 'vits-sr_RS-serbski_institut-medium': '20230808',
92
+ 'vits-tr_TR-dfki-medium': '20230808',
93
+
94
+ 'vits-cs_CZ-jirka-medium': '20230824',
95
+ 'vits-de_DE-thorsten-high': '20230824',
96
+ 'vits-hu_HU-anna-medium': '20230824',
97
+ 'vits-pt_PT-tugao-medium': '20230824',
98
+ 'vits-sk_SK-lili-medium': '20230824',
99
+ 'vits-tr_TR-fahrettin-medium': '20230824',
100
+
101
+ 'vits-ar_JO-kareem-medium': '20231022',
102
+ 'vits-cs_CZ-jirka-low': '20231022',
103
+ 'vits-en_US-hfc_male-medium': '20231022',
104
+ 'vits-en_US-libritts_r-medium': '20231022',
105
+ 'vits-hu_HU-imre-medium': '20231022',
106
+ 'vits-pl_PL-mc_speech-medium': '20231022',
107
+
108
+ 'whisper-tiny': '20231126',
109
+ 'whisper-tiny.en': '20231126',
110
+ 'whisper-base': '20231126',
111
+ 'whisper-base.en': '20231126',
112
+ 'whisper-small': '20231126',
113
+ 'whisper-small.en': '20231126',
114
+ 'whisper-medium': '20231126',
115
+ 'whisper-medium.en': '20231126',
116
+ 'whisper-large-v3': '20231126',
117
+
118
+ 'vits-ar_JO-kareem-low': '20231126',
119
+ 'vits-en_US-hfc_female-medium': '20231126',
120
+
121
+ 'ffmpeg-6.0-win32-x64': '20240316',
122
+ 'ffmpeg-6.0-win32-ia32': '20240316',
123
+ 'ffmpeg-6.0-darwin-x64': '20240316',
124
+ 'ffmpeg-6.0-darwin-arm64': '20240316',
125
+ 'ffmpeg-6.0-linux-x64': '20240316',
126
+ 'ffmpeg-6.0-linux-ia32': '20240316',
127
+ 'ffmpeg-6.0-linux-arm64': '20240316',
128
+ 'ffmpeg-6.0-linux-arm': '20240316',
129
+ 'ffmpeg-6.0-freebsd-x64': '20240316',
130
+
131
+ 'vits-de_DE-mls-medium': '20240316',
132
+ 'vits-en_GB-cori-high': '20240316',
133
+ 'vits-en_US-kristin-medium': '20240316',
134
+ 'vits-en_US-ljspeech-high': '20240316',
135
+ 'vits-en_US-ljspeech-medium': '20240316',
136
+ 'vits-es_MX-claude-high': '20240316',
137
+ 'vits-fa_IR-amir-medium': '20240316',
138
+ 'vits-fa_IR-gyro-medium': '20240316',
139
+ 'vits-fr_FR-mls-medium': '20240316',
140
+ 'vits-fr_FR-tom-medium': '20240316',
141
+ 'vits-nl_NL-mls-medium': '20240316',
142
+ 'vits-sl_SI-artur-medium': '20240316',
143
+ 'vits-tr_TR-fettah-medium': '20240316',
119
144
  }
@@ -0,0 +1,41 @@
1
+ import path from 'node:path'
2
+ import { fileURLToPath } from 'node:url'
3
+ import * as os from 'node:os'
4
+
5
+ export function getModuleRootDir() {
6
+ const currentScriptDir = path.dirname(fileURLToPath(import.meta.url))
7
+ return path.resolve(currentScriptDir, '..', '..')
8
+ }
9
+
10
+ export function resolveToModuleRootDir(relativePath: string) {
11
+ return path.resolve(getModuleRootDir(), relativePath)
12
+ }
13
+
14
+ export function getLowercaseFileExtension(filename: string) {
15
+ const fileExtensionIndex = filename.lastIndexOf(".")
16
+
17
+ if (fileExtensionIndex == -1) {
18
+ return ""
19
+ }
20
+
21
+ return filename.substring(fileExtensionIndex + 1).toLowerCase()
22
+ }
23
+
24
+ export function getAppTempDir(appName: string) {
25
+ let tempDir: string
26
+
27
+ const platform = process.platform
28
+ const homeDir = os.homedir()
29
+
30
+ if (platform == "win32") {
31
+ tempDir = path.join(homeDir, "AppData", "Local", "Temp", appName)
32
+ } else if (platform == "darwin") {
33
+ tempDir = path.join(homeDir, "Library", "Caches", appName)
34
+ } else if (platform == "linux") {
35
+ tempDir = path.join(homeDir, ".cache", appName)
36
+ } else {
37
+ throw new Error(`Unsupport platform ${platform}`)
38
+ }
39
+
40
+ return tempDir
41
+ }
@@ -1,9 +1,10 @@
1
1
  import path from "path"
2
2
  import { createTarball } from "./Compression.js"
3
- import { ensureDir, existsSync, getAppTempDir, move, readdir, stat } from "./FileSystem.js"
3
+ import { ensureDir, existsSync, move, readdir, stat } from "./FileSystem.js"
4
4
  import { ensureAndGetPackagesDir } from "./PackageManager.js"
5
5
  import { appName } from "../api/Common.js"
6
6
  import { getRandomHexString } from "./Utilities.js"
7
+ import { getAppTempDir } from "./PathUtilities.js"
7
8
 
8
9
  const tarballDir = "../resources/tarballs"
9
10
 
@@ -5,8 +5,6 @@ import { inspect } from 'node:util'
5
5
  import { RandomGenerator } from './RandomGenerator.js'
6
6
  import { randomUUID, randomBytes } from 'node:crypto'
7
7
  import { Logger } from './Logger.js'
8
- import chalk from 'chalk'
9
- import { shouldCancelCurrentTask } from '../server/Worker.js'
10
8
 
11
9
  const log = logToStderr
12
10
 
@@ -583,12 +581,16 @@ export async function runOperationWithRetries<R>(
583
581
  delayBetweenRetries = 2000,
584
582
  maxRetries = 200) {
585
583
 
584
+ const { default: chalk } = await import('chalk')
585
+
586
586
  for (let retryIndex = 1; retryIndex <= maxRetries; retryIndex++) {
587
587
  try {
588
588
  const result = await operationFunc()
589
589
 
590
590
  return result
591
591
  } catch (e: any) {
592
+ const { shouldCancelCurrentTask } = await import('../server/Worker.js')
593
+
592
594
  if (shouldCancelCurrentTask()) {
593
595
  throw new Error("Canceled")
594
596
  }