echogarden 1.4.4 → 1.6.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/data/schemas/options.json +310 -25
- package/dist/alignment/DTWMfccSequenceAlignment.d.ts +1 -1
- package/dist/alignment/DTWMfccSequenceAlignment.js +5 -5
- package/dist/alignment/DTWSequenceAlignmentWindowed.js +1 -3
- package/dist/alignment/DTWSequenceAlignmentWindowed.js.map +1 -1
- package/dist/alignment/{TextAlignment.d.ts → SemanticTextAlignment.d.ts} +4 -2
- package/dist/alignment/SemanticTextAlignment.js +336 -0
- package/dist/alignment/SemanticTextAlignment.js.map +1 -0
- package/dist/alignment/SpeechAlignment.d.ts +4 -3
- package/dist/alignment/SpeechAlignment.js +130 -39
- package/dist/alignment/SpeechAlignment.js.map +1 -1
- package/dist/api/API.d.ts +7 -3
- package/dist/api/API.js +7 -2
- package/dist/api/API.js.map +1 -1
- package/dist/api/APIOptions.d.ts +4 -1
- package/dist/api/Alignment.d.ts +1 -1
- package/dist/api/Alignment.js +13 -5
- package/dist/api/Alignment.js.map +1 -1
- package/dist/api/LanguageDetectionCommon.d.ts +6 -0
- package/dist/api/LanguageDetectionCommon.js +2 -0
- package/dist/api/LanguageDetectionCommon.js.map +1 -0
- package/dist/api/Recognition.js.map +1 -1
- package/dist/api/{LanguageDetection.d.ts → SpeechLanguageDetection.d.ts} +1 -25
- package/dist/api/{LanguageDetection.js → SpeechLanguageDetection.js} +1 -68
- package/dist/api/SpeechLanguageDetection.js.map +1 -0
- package/dist/api/{Translation.js → SpeechTranslation.js} +3 -3
- package/dist/api/SpeechTranslation.js.map +1 -0
- package/dist/api/Synthesis.d.ts +0 -1
- package/dist/api/Synthesis.js +4 -4
- package/dist/api/TextLanguageDetection.d.ts +21 -0
- package/dist/api/TextLanguageDetection.js +67 -0
- package/dist/api/TextLanguageDetection.js.map +1 -0
- package/dist/api/TextTranslation.d.ts +25 -0
- package/dist/api/TextTranslation.js +101 -0
- package/dist/api/TextTranslation.js.map +1 -0
- package/dist/api/TimelineTranslationAlignment.d.ts +23 -0
- package/dist/api/TimelineTranslationAlignment.js +92 -0
- package/dist/api/TimelineTranslationAlignment.js.map +1 -0
- package/dist/api/TranscriptAndTranslationAlignment.d.ts +35 -0
- package/dist/api/TranscriptAndTranslationAlignment.js +78 -0
- package/dist/api/TranscriptAndTranslationAlignment.js.map +1 -0
- package/dist/api/TranslationAlignment.d.ts +4 -3
- package/dist/api/TranslationAlignment.js +9 -8
- package/dist/api/TranslationAlignment.js.map +1 -1
- package/dist/api/VoiceActivityDetection.js +16 -1
- package/dist/api/VoiceActivityDetection.js.map +1 -1
- package/dist/audio/AudioBufferConversion.d.ts +0 -1
- package/dist/audio/AudioPlayer.d.ts +0 -1
- package/dist/audio/AudioPlayer.js +62 -41
- package/dist/audio/AudioPlayer.js.map +1 -1
- package/dist/audio/AudioUtilities.d.ts +0 -1
- package/dist/cli/CLI.d.ts +28 -7
- package/dist/cli/CLI.js +265 -37
- package/dist/cli/CLI.js.map +1 -1
- package/dist/codecs/FFMpegTranscoder.d.ts +0 -1
- package/dist/codecs/FFMpegTranscoder.js +7 -0
- package/dist/codecs/FFMpegTranscoder.js.map +1 -1
- package/dist/codecs/TIMITCodec.d.ts +0 -1
- package/dist/codecs/WaveCodec.d.ts +0 -1
- package/dist/dsp/FFT.d.ts +1 -1
- package/dist/dsp/FFT.js +6 -0
- package/dist/dsp/FFT.js.map +1 -1
- package/dist/dsp/KWeightingFilter.js +1 -1
- package/dist/dsp/KWeightingFilter.js.map +1 -1
- package/dist/dsp/MelSpectogram.d.ts +3 -2
- package/dist/dsp/MelSpectogram.js +14 -8
- package/dist/dsp/MelSpectogram.js.map +1 -1
- package/dist/math/VectorMath.d.ts +9 -9
- package/dist/math/VectorMath.js +10 -10
- package/dist/math/VectorMath.js.map +1 -1
- package/dist/nlp/ChineseSegmentation.js +4 -4
- package/dist/nlp/ChineseSegmentation.js.map +1 -1
- package/dist/nlp/Segmentation.d.ts +2 -2
- package/dist/nlp/Segmentation.js +20 -13
- package/dist/nlp/Segmentation.js.map +1 -1
- package/dist/recognition/OpenAICloudSTT.d.ts +2 -1
- package/dist/recognition/OpenAICloudSTT.js +30 -19
- package/dist/recognition/OpenAICloudSTT.js.map +1 -1
- package/dist/recognition/SileroSTT.d.ts +0 -1
- package/dist/recognition/WhisperCppSTT.d.ts +3 -3
- package/dist/recognition/WhisperCppSTT.js +21 -9
- package/dist/recognition/WhisperCppSTT.js.map +1 -1
- package/dist/recognition/WhisperSTT.d.ts +9 -6
- package/dist/recognition/WhisperSTT.js +227 -46
- package/dist/recognition/WhisperSTT.js.map +1 -1
- package/dist/server/Client.d.ts +3 -4
- package/dist/server/Client.js.map +1 -1
- package/dist/server/Worker.d.ts +3 -3
- package/dist/server/Worker.js +3 -2
- package/dist/server/Worker.js.map +1 -1
- package/dist/source-separation/MDXNetSourceSeparation.d.ts +0 -1
- package/dist/source-separation/MDXNetSourceSeparation.js +1 -1
- package/dist/source-separation/MDXNetSourceSeparation.js.map +1 -1
- package/dist/speech-embeddings/WavToVec2BertFeatureEmbeddings.d.ts +12 -0
- package/dist/speech-embeddings/WavToVec2BertFeatureEmbeddings.js +68 -0
- package/dist/speech-embeddings/WavToVec2BertFeatureEmbeddings.js.map +1 -0
- package/dist/speech-language-detection/SileroLanguageDetection.d.ts +1 -2
- package/dist/speech-language-detection/SileroLanguageDetection.js +1 -1
- package/dist/speech-language-detection/SileroLanguageDetection.js.map +1 -1
- package/dist/subtitles/Subtitles.js +2 -2
- package/dist/subtitles/Subtitles.js.map +1 -1
- package/dist/synthesis/GoogleCloudTTS.d.ts +0 -1
- package/dist/synthesis/GoogleTranslateTTS.d.ts +0 -1
- package/dist/synthesis/GoogleTranslateTTS.js +6 -21
- package/dist/synthesis/GoogleTranslateTTS.js.map +1 -1
- package/dist/synthesis/StreamlabsPollyTTS.d.ts +0 -1
- package/dist/synthesis/VitsTTS.d.ts +0 -1
- package/dist/synthesis/VitsTTS.js +30 -0
- package/dist/synthesis/VitsTTS.js.map +1 -1
- package/dist/tests/Test.js +0 -31
- package/dist/tests/Test.js.map +1 -1
- package/dist/text-language-detection/FastTextLanguageDetection.d.ts +1 -1
- package/dist/text-language-detection/FastTextLanguageDetection.js.map +1 -1
- package/dist/text-language-detection/TinyLDLanguageDetection.d.ts +1 -1
- package/dist/text-language-detection/TinyLDLanguageDetection.js.map +1 -1
- package/dist/text-translation/DeepLTextTranslation.d.ts +2 -0
- package/dist/text-translation/DeepLTextTranslation.js +67 -0
- package/dist/text-translation/DeepLTextTranslation.js.map +1 -0
- package/dist/text-translation/GoogleTranslateTextTranslation.d.ts +10 -0
- package/dist/text-translation/GoogleTranslateTextTranslation.js +554 -0
- package/dist/text-translation/GoogleTranslateTextTranslation.js.map +1 -0
- package/dist/text-translation/NLLBTextTranslation.d.ts +2 -1
- package/dist/text-translation/NLLBTextTranslation.js +249 -19
- package/dist/text-translation/NLLBTextTranslation.js.map +1 -1
- package/dist/utilities/BinaryArrayConversion.d.ts +0 -1
- package/dist/utilities/BrowserRequestHeaders.d.ts +6 -0
- package/dist/utilities/BrowserRequestHeaders.js +52 -0
- package/dist/utilities/BrowserRequestHeaders.js.map +1 -0
- package/dist/utilities/BufferFileReadStream.d.ts +20 -0
- package/dist/utilities/BufferFileReadStream.js +81 -0
- package/dist/utilities/BufferFileReadStream.js.map +1 -0
- package/dist/utilities/DynamicUint8Array.d.ts +9 -0
- package/dist/utilities/DynamicUint8Array.js +31 -0
- package/dist/utilities/DynamicUint8Array.js.map +1 -0
- package/dist/utilities/FileSystem.d.ts +0 -2
- package/dist/utilities/Hashing.d.ts +3 -10
- package/dist/utilities/Hashing.js +10 -127
- package/dist/utilities/Hashing.js.map +1 -1
- package/dist/utilities/LEB128.d.ts +15 -5
- package/dist/utilities/LEB128.js +199 -119
- package/dist/utilities/LEB128.js.map +1 -1
- package/dist/utilities/LPVarInt.d.ts +11 -0
- package/dist/utilities/LPVarInt.js +187 -0
- package/dist/utilities/LPVarInt.js.map +1 -0
- package/dist/utilities/Locale.d.ts +1 -1
- package/dist/utilities/Locale.js +1 -1
- package/dist/utilities/OnnxUtilities.d.ts +1 -2
- package/dist/utilities/PVarInt.d.ts +4 -0
- package/dist/utilities/PVarInt.js +166 -0
- package/dist/utilities/PVarInt.js.map +1 -0
- package/dist/utilities/PackageManager.js +48 -25
- package/dist/utilities/PackageManager.js.map +1 -1
- package/dist/utilities/RandomGenerator.d.ts +3 -17
- package/dist/utilities/RandomGenerator.js +12 -81
- package/dist/utilities/RandomGenerator.js.map +1 -1
- package/dist/utilities/Timeline.d.ts +2 -0
- package/dist/utilities/Timeline.js +129 -20
- package/dist/utilities/Timeline.js.map +1 -1
- package/dist/utilities/Utilities.d.ts +1 -3
- package/dist/utilities/Utilities.js +30 -3
- package/dist/utilities/Utilities.js.map +1 -1
- package/dist/utilities/VarInt.d.ts +4 -0
- package/dist/utilities/VarInt.js +166 -0
- package/dist/utilities/VarInt.js.map +1 -0
- package/dist/utilities/VirtualFileReadStream.d.ts +20 -0
- package/dist/utilities/VirtualFileReadStream.js +79 -0
- package/dist/utilities/VirtualFileReadStream.js.map +1 -0
- package/dist/utilities/WebReader.js +7 -23
- package/dist/utilities/WebReader.js.map +1 -1
- package/dist/voice-activity-detection/SileroVAD.d.ts +0 -1
- package/docs/API.md +105 -3
- package/docs/CLI.md +51 -1
- package/docs/Engines.md +32 -3
- package/docs/Options.md +53 -12
- package/docs/Tasklist.md +1 -13
- package/package.json +20 -24
- package/src/alignment/DTWMfccSequenceAlignment.ts +5 -5
- package/src/alignment/DTWSequenceAlignmentWindowed.ts +1 -3
- package/src/alignment/SemanticTextAlignment.ts +467 -0
- package/src/alignment/SpeechAlignment.ts +214 -56
- package/src/api/API.ts +18 -2
- package/src/api/APIOptions.ts +14 -1
- package/src/api/Alignment.ts +31 -9
- package/src/api/LanguageDetectionCommon.ts +7 -0
- package/src/api/Recognition.ts +2 -0
- package/src/api/{LanguageDetection.ts → SpeechLanguageDetection.ts} +1 -119
- package/src/api/{Translation.ts → SpeechTranslation.ts} +2 -2
- package/src/api/Synthesis.ts +4 -4
- package/src/api/TextLanguageDetection.ts +116 -0
- package/src/api/TextTranslation.ts +177 -0
- package/src/api/TimelineTranslationAlignment.ts +162 -0
- package/src/api/TranscriptAndTranslationAlignment.ts +164 -0
- package/src/api/TranslationAlignment.ts +12 -10
- package/src/api/VoiceActivityDetection.ts +24 -3
- package/src/audio/AudioPlayer.ts +2 -0
- package/src/cli/CLI.ts +376 -40
- package/src/codecs/FFMpegTranscoder.ts +6 -0
- package/src/dsp/FFT.ts +8 -2
- package/src/dsp/KWeightingFilter.ts +1 -1
- package/src/dsp/MelSpectogram.ts +17 -8
- package/src/math/VectorMath.ts +15 -15
- package/src/nlp/ChineseSegmentation.ts +6 -4
- package/src/nlp/Segmentation.ts +18 -13
- package/src/recognition/OpenAICloudSTT.ts +47 -29
- package/src/recognition/WhisperCppSTT.ts +26 -11
- package/src/recognition/WhisperSTT.ts +364 -49
- package/src/server/Client.ts +3 -2
- package/src/server/Worker.ts +3 -2
- package/src/source-separation/MDXNetSourceSeparation.ts +1 -1
- package/src/speech-embeddings/WavToVec2BertFeatureEmbeddings.ts +107 -0
- package/src/speech-language-detection/SileroLanguageDetection.ts +2 -1
- package/src/subtitles/Subtitles.ts +2 -2
- package/src/synthesis/GoogleTranslateTTS.ts +7 -21
- package/src/synthesis/VitsTTS.ts +31 -3
- package/src/tests/Test.ts +1 -38
- package/src/text-language-detection/FastTextLanguageDetection.ts +1 -1
- package/src/text-language-detection/TinyLDLanguageDetection.ts +1 -1
- package/src/text-translation/DeepLTextTranslation.ts +88 -0
- package/src/text-translation/GoogleTranslateTextTranslation.ts +667 -0
- package/src/text-translation/NLLBTextTranslation.ts +261 -21
- package/src/typings/Fillers.d.ts +25 -2
- package/src/utilities/BrowserRequestHeaders.ts +59 -0
- package/src/utilities/DynamicUint8Array.ts +39 -0
- package/src/utilities/Hashing.ts +14 -167
- package/src/utilities/LEB128.ts +273 -148
- package/src/utilities/LPVarInt.ts +292 -0
- package/src/utilities/Locale.ts +1 -1
- package/src/utilities/OnnxUtilities.ts +1 -1
- package/src/utilities/PackageManager.ts +51 -30
- package/src/utilities/RandomGenerator.ts +12 -113
- package/src/utilities/Timeline.ts +162 -23
- package/src/utilities/Utilities.ts +40 -3
- package/src/utilities/VirtualFileReadStream.ts +109 -0
- package/src/utilities/WebReader.ts +9 -23
- package/dist/alignment/TextAlignment.js +0 -156
- package/dist/alignment/TextAlignment.js.map +0 -1
- package/dist/api/LanguageDetection.js.map +0 -1
- package/dist/api/Translation.js.map +0 -1
- package/src/alignment/TextAlignment.ts +0 -234
- /package/dist/api/{Translation.d.ts → SpeechTranslation.d.ts} +0 -0
package/dist/cli/CLI.js
CHANGED
|
@@ -5,7 +5,7 @@ import { getOptionTypeFromSchema } from './CLIOptionsSchema.js';
|
|
|
5
5
|
import { parseConfigFile, parseJSONConfigFile } from './CLIConfigFile.js';
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import { applyGainDecibels, encodeRawAudioToWave, getEmptyRawAudio, getRawAudioDuration, normalizeAudioLevel, sliceRawAudioByTime } from '../audio/AudioUtilities.js';
|
|
8
|
-
import { subtitlesToText,
|
|
8
|
+
import { subtitlesToText, timelineToSubtitles } from '../subtitles/Subtitles.js';
|
|
9
9
|
import { Logger, resetActiveLogger } from '../utilities/Logger.js';
|
|
10
10
|
import { isMainThread, parentPort } from 'node:worker_threads';
|
|
11
11
|
import { encodeFromChannels, getDefaultFFMpegOptionsForSpeech } from '../codecs/FFMpegTranscoder.js';
|
|
@@ -170,19 +170,25 @@ const help = [
|
|
|
170
170
|
`${executableName} ${chalk.magentaBright('speak-url')} url [output files...] [options...]`,
|
|
171
171
|
` Speak the HTML document on the given URL\n`,
|
|
172
172
|
`${executableName} ${chalk.magentaBright('speak-wikipedia')} articleName [output files...] [options...]`,
|
|
173
|
-
` Speak the given
|
|
173
|
+
` Speak the given Wikipedia article. Language edition can be specified by --language=<langCode>\n`,
|
|
174
174
|
`${executableName} ${chalk.magentaBright('transcribe')} audioFile [output files...] [options...]`,
|
|
175
|
-
` Transcribe audio file\n`,
|
|
176
|
-
`${executableName} ${chalk.magentaBright('align')} audioFile
|
|
177
|
-
` Align audio file to
|
|
178
|
-
`${executableName} ${chalk.magentaBright('translate-
|
|
179
|
-
`
|
|
180
|
-
`${executableName} ${chalk.magentaBright('
|
|
181
|
-
`
|
|
182
|
-
`${executableName} ${chalk.magentaBright('
|
|
183
|
-
`
|
|
175
|
+
` Transcribe a spoken audio file\n`,
|
|
176
|
+
`${executableName} ${chalk.magentaBright('align')} audioFile transcriptFile [output files...] [options...]`,
|
|
177
|
+
` Align spoken audio file to its transcript\n`,
|
|
178
|
+
`${executableName} ${chalk.magentaBright('translate-text')} inputFile [output files...] [options...]`,
|
|
179
|
+
` Translate text to a different language\n`,
|
|
180
|
+
`${executableName} ${chalk.magentaBright('translate-speech')} audioFile [output files...] [options...]`,
|
|
181
|
+
` Transcribe spoken audio file directly to a different language\n`,
|
|
182
|
+
`${executableName} ${chalk.magentaBright('align-translation')} audioFile translatedTranscriptFile [output files...] [options...]`,
|
|
183
|
+
` Align spoken audio file to its translated transcript\n`,
|
|
184
|
+
`${executableName} ${chalk.magentaBright('align-transcript-and-translation')} audioFile transcriptFile translatedTranscriptFile [output files...] [options...]`,
|
|
185
|
+
` Align spoken audio file to both its transcript and its translated transcript using a two-stage approach.\n`,
|
|
186
|
+
`${executableName} ${chalk.magentaBright('align-timeline-translation')} timelineFile translatedFile [output files...] [options...]`,
|
|
187
|
+
` Align a given timeline file to its translated text\n`,
|
|
184
188
|
`${executableName} ${chalk.magentaBright('detect-text-language')} inputFile [output files...] [options...]`,
|
|
185
189
|
` Detect language of textual file\n`,
|
|
190
|
+
`${executableName} ${chalk.magentaBright('detect-speech-language')} audioFile [output files...] [options...]`,
|
|
191
|
+
` Detect language of spoken audio file\n`,
|
|
186
192
|
`${executableName} ${chalk.magentaBright('detect-voice-activity')} audioFile [output files...] [options...]`,
|
|
187
193
|
` Detect voice activity in audio file\n`,
|
|
188
194
|
`${executableName} ${chalk.magentaBright('denoise')} audioFile [output files...] [options...]`,
|
|
@@ -221,6 +227,10 @@ async function startWithArgs(operationData) {
|
|
|
221
227
|
await align(operationData);
|
|
222
228
|
break;
|
|
223
229
|
}
|
|
230
|
+
case 'translate-text': {
|
|
231
|
+
await translateText(operationData);
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
224
234
|
case 'translate-speech': {
|
|
225
235
|
await translateSpeech(operationData);
|
|
226
236
|
break;
|
|
@@ -229,6 +239,14 @@ async function startWithArgs(operationData) {
|
|
|
229
239
|
await alignTranslation(operationData);
|
|
230
240
|
break;
|
|
231
241
|
}
|
|
242
|
+
case 'align-transcript-and-translation': {
|
|
243
|
+
await alignTranscriptAndTranslation(operationData);
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
case 'align-timeline-translation': {
|
|
247
|
+
await alignTimelineTranslation(operationData);
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
232
250
|
case 'detect-language': {
|
|
233
251
|
await detectLanguage(operationData, 'auto');
|
|
234
252
|
break;
|
|
@@ -283,7 +301,7 @@ async function startWithArgs(operationData) {
|
|
|
283
301
|
}
|
|
284
302
|
}
|
|
285
303
|
}
|
|
286
|
-
async function speak(operationData) {
|
|
304
|
+
export async function speak(operationData) {
|
|
287
305
|
const logger = new Logger();
|
|
288
306
|
const { operationArgs, operation, operationOptionsLookup, cliOptions } = operationData;
|
|
289
307
|
const mainArg = operationArgs[0];
|
|
@@ -345,8 +363,8 @@ async function speak(operationData) {
|
|
|
345
363
|
}
|
|
346
364
|
else if (sourceFileExtension == 'srt' || sourceFileExtension == 'vtt') {
|
|
347
365
|
const fileContent = await readFile(sourceFile, { encoding: 'utf-8' });
|
|
348
|
-
textSegments = subtitlesToTimeline(fileContent).map(entry => entry.text)
|
|
349
|
-
|
|
366
|
+
//textSegments = subtitlesToTimeline(fileContent).map(entry => entry.text)
|
|
367
|
+
textSegments = [subtitlesToText(fileContent)];
|
|
350
368
|
}
|
|
351
369
|
else if (sourceFileExtension == 'xml' || sourceFileExtension == 'ssml') {
|
|
352
370
|
options.ssml = true;
|
|
@@ -415,7 +433,7 @@ async function speak(operationData) {
|
|
|
415
433
|
}
|
|
416
434
|
logger.end();
|
|
417
435
|
}
|
|
418
|
-
async function transcribe(operationData) {
|
|
436
|
+
export async function transcribe(operationData) {
|
|
419
437
|
const logger = new Logger();
|
|
420
438
|
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
421
439
|
const sourceFilename = operationArgs[0];
|
|
@@ -458,7 +476,7 @@ async function transcribe(operationData) {
|
|
|
458
476
|
await playAudioWithWordTimeline(normalizedAudioToPlay, wordTimeline, transcript);
|
|
459
477
|
}
|
|
460
478
|
}
|
|
461
|
-
async function align(operationData) {
|
|
479
|
+
export async function align(operationData) {
|
|
462
480
|
const logger = new Logger();
|
|
463
481
|
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
464
482
|
const audioFilename = operationArgs[0];
|
|
@@ -531,13 +549,13 @@ async function align(operationData) {
|
|
|
531
549
|
await playAudioWithWordTimeline(normalizedAudioToPlay, wordTimeline, transcript);
|
|
532
550
|
}
|
|
533
551
|
}
|
|
534
|
-
async function alignTranslation(operationData) {
|
|
552
|
+
export async function alignTranslation(operationData) {
|
|
535
553
|
const logger = new Logger();
|
|
536
554
|
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
537
555
|
const audioFilename = operationArgs[0];
|
|
538
556
|
const outputFilenames = operationArgs.slice(2);
|
|
539
557
|
if (audioFilename == undefined) {
|
|
540
|
-
throw new Error(`align-translation requires
|
|
558
|
+
throw new Error(`align-translation requires a first argument containing the audio file path.`);
|
|
541
559
|
}
|
|
542
560
|
if (!existsSync(audioFilename)) {
|
|
543
561
|
throw new Error(`The given source file '${audioFilename}' was not found.`);
|
|
@@ -562,7 +580,7 @@ async function alignTranslation(operationData) {
|
|
|
562
580
|
text = subtitlesToText(fileContent);
|
|
563
581
|
}
|
|
564
582
|
else {
|
|
565
|
-
throw new Error(`align only supports reference files with extensions 'txt', 'html', 'htm', 'srt' or 'vtt'`);
|
|
583
|
+
throw new Error(`align-translation only supports reference files with extensions 'txt', 'html', 'htm', 'srt' or 'vtt'`);
|
|
566
584
|
}
|
|
567
585
|
if (cliOptions.play == null) {
|
|
568
586
|
cliOptions.play = outputFilenames.length === 0;
|
|
@@ -570,7 +588,7 @@ async function alignTranslation(operationData) {
|
|
|
570
588
|
const options = await optionsLookupToTypedObject(operationOptionsLookup, 'TranslationAlignmentOptions');
|
|
571
589
|
const allowOverwrite = getWithDefault(cliOptions.overwrite, overwriteByDefault);
|
|
572
590
|
const { includesPlaceholderPattern } = await checkOutputFilenames(outputFilenames, true, true, true);
|
|
573
|
-
const { timeline, wordTimeline,
|
|
591
|
+
const { timeline, wordTimeline, translatedTranscript, sourceLanguage, targetLanguage, inputRawAudio, isolatedRawAudio, backgroundRawAudio } = await API.alignTranslation(audioFilename, text, options);
|
|
574
592
|
if (outputFilenames.length > 0) {
|
|
575
593
|
logger.start('\nWrite output files');
|
|
576
594
|
}
|
|
@@ -579,9 +597,100 @@ async function alignTranslation(operationData) {
|
|
|
579
597
|
const segmentEntry = timeline[segmentIndex];
|
|
580
598
|
const segmentAudio = sliceRawAudioByTime(inputRawAudio, segmentEntry.startTime, segmentEntry.endTime);
|
|
581
599
|
const sentenceTimeline = addTimeOffsetToTimeline(segmentEntry.timeline, -segmentEntry.startTime);
|
|
582
|
-
await writeOutputFilesForSegment(outputFilenames, segmentIndex, timeline.length, segmentAudio, sentenceTimeline, segmentEntry.text,
|
|
600
|
+
await writeOutputFilesForSegment(outputFilenames, segmentIndex, timeline.length, segmentAudio, sentenceTimeline, segmentEntry.text, targetLanguage, allowOverwrite);
|
|
583
601
|
}
|
|
584
602
|
}
|
|
603
|
+
for (const outputFilename of outputFilenames) {
|
|
604
|
+
const partPatternMatch = outputFilename.match(filenamePlaceholderPattern);
|
|
605
|
+
if (partPatternMatch) {
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
608
|
+
const fileSaver = getFileSaver(outputFilename, allowOverwrite);
|
|
609
|
+
await fileSaver(inputRawAudio, timeline, translatedTranscript, options.subtitles);
|
|
610
|
+
await writeSourceSeparationOutputIfNeeded(outputFilename, isolatedRawAudio, backgroundRawAudio, allowOverwrite, true);
|
|
611
|
+
}
|
|
612
|
+
logger.end();
|
|
613
|
+
if (cliOptions.play) {
|
|
614
|
+
let audioToPlay;
|
|
615
|
+
if (isolatedRawAudio) {
|
|
616
|
+
audioToPlay = isolatedRawAudio;
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
audioToPlay = inputRawAudio;
|
|
620
|
+
}
|
|
621
|
+
const normalizedAudioToPlay = normalizeAudioLevel(audioToPlay);
|
|
622
|
+
await playAudioWithWordTimeline(normalizedAudioToPlay, wordTimeline, translatedTranscript);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
export async function alignTranscriptAndTranslation(operationData) {
|
|
626
|
+
const logger = new Logger();
|
|
627
|
+
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
628
|
+
const audioFilename = operationArgs[0];
|
|
629
|
+
const outputFilenames = operationArgs.slice(3);
|
|
630
|
+
if (audioFilename == undefined) {
|
|
631
|
+
throw new Error(`align-transcript-and-translation requires a first argument containing the audio file path.`);
|
|
632
|
+
}
|
|
633
|
+
if (!existsSync(audioFilename)) {
|
|
634
|
+
throw new Error(`The given source file '${audioFilename}' was not found.`);
|
|
635
|
+
}
|
|
636
|
+
const nativeTranscriptFilePath = operationArgs[1];
|
|
637
|
+
if (nativeTranscriptFilePath == undefined) {
|
|
638
|
+
throw new Error(`align-transcript-and-translation requires a second argument containing the native language transcript file path.`);
|
|
639
|
+
}
|
|
640
|
+
if (!existsSync(nativeTranscriptFilePath)) {
|
|
641
|
+
throw new Error(`The given transcript file '${nativeTranscriptFilePath}' was not found.`);
|
|
642
|
+
}
|
|
643
|
+
const translatedTranscriptFilePath = operationArgs[2];
|
|
644
|
+
if (translatedTranscriptFilePath == undefined) {
|
|
645
|
+
throw new Error(`align-transcript-and-translation requires a third argument containing the translated language transcript file path.`);
|
|
646
|
+
}
|
|
647
|
+
if (!existsSync(translatedTranscriptFilePath)) {
|
|
648
|
+
throw new Error(`The given translated transcript file '${nativeTranscriptFilePath}' was not found.`);
|
|
649
|
+
}
|
|
650
|
+
let transcript;
|
|
651
|
+
{
|
|
652
|
+
const nativeTranscriptFileExtension = getLowercaseFileExtension(nativeTranscriptFilePath);
|
|
653
|
+
const fileContent = await readFile(nativeTranscriptFilePath, { encoding: 'utf-8' });
|
|
654
|
+
if (nativeTranscriptFileExtension == 'txt') {
|
|
655
|
+
transcript = fileContent;
|
|
656
|
+
}
|
|
657
|
+
else if (nativeTranscriptFileExtension == 'html' || nativeTranscriptFileExtension == 'htm') {
|
|
658
|
+
transcript = await convertHtmlToText(fileContent);
|
|
659
|
+
}
|
|
660
|
+
else if (nativeTranscriptFileExtension == 'srt' || nativeTranscriptFileExtension == 'vtt') {
|
|
661
|
+
transcript = subtitlesToText(fileContent);
|
|
662
|
+
}
|
|
663
|
+
else {
|
|
664
|
+
throw new Error(`align-transcript-and-translation only supports transcript files with extensions 'txt', 'html', 'htm', 'srt' or 'vtt'`);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
let translatedTranscript;
|
|
668
|
+
{
|
|
669
|
+
const translatedTranscriptFileExtension = getLowercaseFileExtension(translatedTranscriptFilePath);
|
|
670
|
+
const fileContent = await readFile(translatedTranscriptFilePath, { encoding: 'utf-8' });
|
|
671
|
+
if (translatedTranscriptFileExtension == 'txt') {
|
|
672
|
+
translatedTranscript = fileContent;
|
|
673
|
+
}
|
|
674
|
+
else if (translatedTranscriptFileExtension == 'html' || translatedTranscriptFileExtension == 'htm') {
|
|
675
|
+
translatedTranscript = await convertHtmlToText(fileContent);
|
|
676
|
+
}
|
|
677
|
+
else if (translatedTranscriptFileExtension == 'srt' || translatedTranscriptFileExtension == 'vtt') {
|
|
678
|
+
translatedTranscript = subtitlesToText(fileContent);
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
throw new Error(`align-transcript-and-translation only supports transcript files with extensions 'txt', 'html', 'htm', 'srt' or 'vtt'`);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
if (cliOptions.play == null) {
|
|
685
|
+
cliOptions.play = outputFilenames.length === 0;
|
|
686
|
+
}
|
|
687
|
+
const options = await optionsLookupToTypedObject(operationOptionsLookup, 'TranscriptAndTranslationAlignmentOptions');
|
|
688
|
+
const allowOverwrite = getWithDefault(cliOptions.overwrite, overwriteByDefault);
|
|
689
|
+
const { includesPlaceholderPattern } = await checkOutputFilenames(outputFilenames, true, true, true);
|
|
690
|
+
const { timeline, wordTimeline, translatedTimeline, translatedWordTimeline, sourceLanguage, targetLanguage, inputRawAudio, isolatedRawAudio, backgroundRawAudio } = await API.alignTranscriptAndTranslation(audioFilename, transcript, translatedTranscript, options);
|
|
691
|
+
if (outputFilenames.length > 0) {
|
|
692
|
+
logger.start('\nWrite output files');
|
|
693
|
+
}
|
|
585
694
|
for (const outputFilename of outputFilenames) {
|
|
586
695
|
const partPatternMatch = outputFilename.match(filenamePlaceholderPattern);
|
|
587
696
|
if (partPatternMatch) {
|
|
@@ -590,6 +699,13 @@ async function alignTranslation(operationData) {
|
|
|
590
699
|
const fileSaver = getFileSaver(outputFilename, allowOverwrite);
|
|
591
700
|
await fileSaver(inputRawAudio, timeline, transcript, options.subtitles);
|
|
592
701
|
await writeSourceSeparationOutputIfNeeded(outputFilename, isolatedRawAudio, backgroundRawAudio, allowOverwrite, true);
|
|
702
|
+
const fileExtension = getLowercaseFileExtension(outputFilename);
|
|
703
|
+
if (['json', 'txt', 'srt', 'vtt'].includes(fileExtension)) {
|
|
704
|
+
const pathWithoutExtension = outputFilename.substring(0, outputFilename.lastIndexOf('.'));
|
|
705
|
+
const translatedOutputPath = `${pathWithoutExtension}.translated.${fileExtension}`;
|
|
706
|
+
const translatedFileSaver = getFileSaver(translatedOutputPath, allowOverwrite);
|
|
707
|
+
await translatedFileSaver(inputRawAudio, translatedTimeline, translatedTranscript, options.subtitles);
|
|
708
|
+
}
|
|
593
709
|
}
|
|
594
710
|
logger.end();
|
|
595
711
|
if (cliOptions.play) {
|
|
@@ -601,10 +717,118 @@ async function alignTranslation(operationData) {
|
|
|
601
717
|
audioToPlay = inputRawAudio;
|
|
602
718
|
}
|
|
603
719
|
const normalizedAudioToPlay = normalizeAudioLevel(audioToPlay);
|
|
604
|
-
await playAudioWithWordTimeline(normalizedAudioToPlay,
|
|
720
|
+
await playAudioWithWordTimeline(normalizedAudioToPlay, translatedWordTimeline, translatedTranscript);
|
|
605
721
|
}
|
|
606
722
|
}
|
|
607
|
-
async function
|
|
723
|
+
export async function alignTimelineTranslation(operationData) {
|
|
724
|
+
const logger = new Logger();
|
|
725
|
+
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
726
|
+
const timelineFilename = operationArgs[0];
|
|
727
|
+
const outputFilenames = operationArgs.slice(2);
|
|
728
|
+
if (timelineFilename == undefined) {
|
|
729
|
+
throw new Error(`align-timeline-translation requires a first argument containing the timeline file path.`);
|
|
730
|
+
}
|
|
731
|
+
if (getLowercaseFileExtension(timelineFilename) != 'json') {
|
|
732
|
+
throw new Error(`align-timeline-translation only supports timeline files with extension 'json'`);
|
|
733
|
+
}
|
|
734
|
+
if (!existsSync(timelineFilename)) {
|
|
735
|
+
throw new Error(`The given timeline file '${timelineFilename}' was not found.`);
|
|
736
|
+
}
|
|
737
|
+
const timeline = await readAndParseJsonFile(timelineFilename);
|
|
738
|
+
const translationFilePath = operationArgs[1];
|
|
739
|
+
if (translationFilePath == undefined) {
|
|
740
|
+
throw new Error(`align-timeline-translation requires a second argument containing the translated reference file path.`);
|
|
741
|
+
}
|
|
742
|
+
if (!existsSync(translationFilePath)) {
|
|
743
|
+
throw new Error(`The given reference file '${translationFilePath}' was not found.`);
|
|
744
|
+
}
|
|
745
|
+
const translationFileExtension = getLowercaseFileExtension(translationFilePath);
|
|
746
|
+
const translationFileContent = await readFile(translationFilePath, { encoding: 'utf-8' });
|
|
747
|
+
let translationText;
|
|
748
|
+
if (translationFileExtension == 'txt') {
|
|
749
|
+
translationText = translationFileContent;
|
|
750
|
+
}
|
|
751
|
+
else if (translationFileExtension == 'html' || translationFileExtension == 'htm') {
|
|
752
|
+
translationText = await convertHtmlToText(translationFileContent);
|
|
753
|
+
}
|
|
754
|
+
else if (translationFileExtension == 'srt' || translationFileExtension == 'vtt') {
|
|
755
|
+
translationText = subtitlesToText(translationFileContent);
|
|
756
|
+
}
|
|
757
|
+
else {
|
|
758
|
+
throw new Error(`align only supports reference files with extensions 'txt', 'html', 'htm', 'srt' or 'vtt'`);
|
|
759
|
+
}
|
|
760
|
+
const options = await optionsLookupToTypedObject(operationOptionsLookup, 'TimelineTranslationAlignmentOptions');
|
|
761
|
+
const { timeline: translationTimeline, wordTimeline: translationWordTimeline, rawAudio } = await API.alignTimelineTranslation(timeline, translationText, options);
|
|
762
|
+
if (outputFilenames.length > 0) {
|
|
763
|
+
logger.start('\nWrite output files');
|
|
764
|
+
}
|
|
765
|
+
const allowOverwrite = getWithDefault(cliOptions.overwrite, overwriteByDefault);
|
|
766
|
+
for (const outputFilename of outputFilenames) {
|
|
767
|
+
const partPatternMatch = outputFilename.match(filenamePlaceholderPattern);
|
|
768
|
+
if (partPatternMatch) {
|
|
769
|
+
continue;
|
|
770
|
+
}
|
|
771
|
+
const fileSaver = getFileSaver(outputFilename, allowOverwrite);
|
|
772
|
+
await fileSaver(getEmptyRawAudio(1, 16000), translationTimeline, translationText, options.subtitles);
|
|
773
|
+
}
|
|
774
|
+
logger.end();
|
|
775
|
+
if (cliOptions.play && rawAudio) {
|
|
776
|
+
const normalizedAudioToPlay = normalizeAudioLevel(rawAudio);
|
|
777
|
+
let transcriptToPlay;
|
|
778
|
+
let timelineToPlay;
|
|
779
|
+
transcriptToPlay = translationText;
|
|
780
|
+
timelineToPlay = translationWordTimeline;
|
|
781
|
+
await playAudioWithWordTimeline(normalizedAudioToPlay, timelineToPlay, transcriptToPlay);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
export async function translateText(operationData) {
|
|
785
|
+
const logger = new Logger();
|
|
786
|
+
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
787
|
+
const inputFilename = operationArgs[0];
|
|
788
|
+
const outputFilenames = operationArgs.slice(1);
|
|
789
|
+
if (inputFilename == undefined) {
|
|
790
|
+
throw new Error(`translate-text requires an argument containing the input file path.`);
|
|
791
|
+
}
|
|
792
|
+
if (!existsSync(inputFilename)) {
|
|
793
|
+
throw new Error(`The given input file '${inputFilename}' was not found.`);
|
|
794
|
+
}
|
|
795
|
+
const inputFileExtension = getLowercaseFileExtension(inputFilename);
|
|
796
|
+
const inputFileContent = await readFile(inputFilename, { encoding: 'utf-8' });
|
|
797
|
+
let inputText;
|
|
798
|
+
if (inputFileExtension === 'txt') {
|
|
799
|
+
inputText = inputFileContent;
|
|
800
|
+
}
|
|
801
|
+
else if (inputFileExtension === 'html' || inputFileExtension === 'htm') {
|
|
802
|
+
inputText = await convertHtmlToText(inputFileContent);
|
|
803
|
+
}
|
|
804
|
+
else if (inputFileExtension == 'srt' || inputFileExtension == 'vtt') {
|
|
805
|
+
inputText = subtitlesToText(inputFileContent);
|
|
806
|
+
}
|
|
807
|
+
else {
|
|
808
|
+
throw new Error(`align only supports reference files with extensions 'txt', 'html', 'htm', 'srt' or 'vtt'`);
|
|
809
|
+
}
|
|
810
|
+
const options = await optionsLookupToTypedObject(operationOptionsLookup, 'TextTranslationOptions');
|
|
811
|
+
const allowOverwrite = getWithDefault(cliOptions.overwrite, overwriteByDefault);
|
|
812
|
+
await checkOutputFilenames(outputFilenames, false, true, true);
|
|
813
|
+
const { text, translatedText, translationPairs, sourceLanguage, targetLanguage, } = await API.translateText(inputFileContent, options);
|
|
814
|
+
if (outputFilenames.length > 0) {
|
|
815
|
+
logger.start('\nWrite output files');
|
|
816
|
+
for (const outputFilename of outputFilenames) {
|
|
817
|
+
const partPatternMatch = outputFilename.match(filenamePlaceholderPattern);
|
|
818
|
+
if (partPatternMatch) {
|
|
819
|
+
continue;
|
|
820
|
+
}
|
|
821
|
+
const fileSaver = getFileSaver(outputFilename, allowOverwrite);
|
|
822
|
+
await fileSaver(getEmptyRawAudio(1, 16000), translationPairs, translatedText, undefined);
|
|
823
|
+
}
|
|
824
|
+
logger.end();
|
|
825
|
+
}
|
|
826
|
+
else {
|
|
827
|
+
logger.log(``);
|
|
828
|
+
logger.log(translatedText);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
export async function translateSpeech(operationData) {
|
|
608
832
|
const logger = new Logger();
|
|
609
833
|
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
610
834
|
const inputFilename = operationArgs[0];
|
|
@@ -667,7 +891,7 @@ async function translateSpeech(operationData) {
|
|
|
667
891
|
await playAudioWithWordTimeline(normalizedAudioToPlay, timelineToPlay, transcriptToPlay);
|
|
668
892
|
}
|
|
669
893
|
}
|
|
670
|
-
async function detectLanguage(operationData, mode) {
|
|
894
|
+
export async function detectLanguage(operationData, mode) {
|
|
671
895
|
const logger = new Logger();
|
|
672
896
|
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
673
897
|
const inputFilePath = operationArgs[0];
|
|
@@ -721,7 +945,7 @@ async function detectLanguage(operationData, mode) {
|
|
|
721
945
|
}
|
|
722
946
|
logger.end();
|
|
723
947
|
}
|
|
724
|
-
async function detectVoiceActivity(operationData) {
|
|
948
|
+
export async function detectVoiceActivity(operationData) {
|
|
725
949
|
const logger = new Logger();
|
|
726
950
|
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
727
951
|
const audioFilename = operationArgs[0];
|
|
@@ -766,7 +990,7 @@ async function detectVoiceActivity(operationData) {
|
|
|
766
990
|
await playAudioWithWordTimeline(normalizedAudio, timelineToPlay);
|
|
767
991
|
}
|
|
768
992
|
}
|
|
769
|
-
async function denoise(operationData) {
|
|
993
|
+
export async function denoise(operationData) {
|
|
770
994
|
const logger = new Logger();
|
|
771
995
|
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
772
996
|
const audioFilename = operationArgs[0];
|
|
@@ -796,7 +1020,7 @@ async function denoise(operationData) {
|
|
|
796
1020
|
await playAudioSamples(denoisedAudio);
|
|
797
1021
|
}
|
|
798
1022
|
}
|
|
799
|
-
async function isolate(operationData) {
|
|
1023
|
+
export async function isolate(operationData) {
|
|
800
1024
|
const logger = new Logger();
|
|
801
1025
|
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
802
1026
|
const audioFilename = operationArgs[0];
|
|
@@ -825,7 +1049,7 @@ async function isolate(operationData) {
|
|
|
825
1049
|
await playAudioSamples(isolatedRawAudio);
|
|
826
1050
|
}
|
|
827
1051
|
}
|
|
828
|
-
async function listEngines(operationData) {
|
|
1052
|
+
export async function listEngines(operationData) {
|
|
829
1053
|
const logger = new Logger();
|
|
830
1054
|
const { operationArgs } = operationData;
|
|
831
1055
|
const targetOperation = operationArgs[0];
|
|
@@ -857,6 +1081,10 @@ async function listEngines(operationData) {
|
|
|
857
1081
|
engines = API.translationAlignmentEngines;
|
|
858
1082
|
break;
|
|
859
1083
|
}
|
|
1084
|
+
case 'translate-text': {
|
|
1085
|
+
engines = API.textTranslationEngines;
|
|
1086
|
+
break;
|
|
1087
|
+
}
|
|
860
1088
|
case 'translate-speech': {
|
|
861
1089
|
engines = API.speechTranslationEngines;
|
|
862
1090
|
break;
|
|
@@ -892,7 +1120,7 @@ async function listEngines(operationData) {
|
|
|
892
1120
|
throw new Error(`The operation '${targetOperation}' is not associated with a list of engines.`);
|
|
893
1121
|
}
|
|
894
1122
|
default: {
|
|
895
|
-
throw new Error(`Unrecognized operation: '${targetOperation}'`);
|
|
1123
|
+
throw new Error(`Unrecognized operation name: '${targetOperation}'`);
|
|
896
1124
|
}
|
|
897
1125
|
}
|
|
898
1126
|
for (const [index, engine] of engines.entries()) {
|
|
@@ -905,7 +1133,7 @@ async function listEngines(operationData) {
|
|
|
905
1133
|
}
|
|
906
1134
|
}
|
|
907
1135
|
}
|
|
908
|
-
async function listTTSVoices(operationData) {
|
|
1136
|
+
export async function listTTSVoices(operationData) {
|
|
909
1137
|
const logger = new Logger();
|
|
910
1138
|
const { operationArgs, operationOptionsLookup, cliOptions } = operationData;
|
|
911
1139
|
const targetEngine = operationArgs[0];
|
|
@@ -947,7 +1175,7 @@ async function listTTSVoices(operationData) {
|
|
|
947
1175
|
}
|
|
948
1176
|
logger.end();
|
|
949
1177
|
}
|
|
950
|
-
async function installPackages(operationData) {
|
|
1178
|
+
export async function installPackages(operationData) {
|
|
951
1179
|
const logger = new Logger();
|
|
952
1180
|
const { operationArgs } = operationData;
|
|
953
1181
|
if (operationArgs.length == 0) {
|
|
@@ -973,7 +1201,7 @@ async function installPackages(operationData) {
|
|
|
973
1201
|
}
|
|
974
1202
|
}
|
|
975
1203
|
}
|
|
976
|
-
async function uninstallPackages(operationData) {
|
|
1204
|
+
export async function uninstallPackages(operationData) {
|
|
977
1205
|
const logger = new Logger();
|
|
978
1206
|
const { operationArgs } = operationData;
|
|
979
1207
|
if (operationArgs.length == 0) {
|
|
@@ -994,7 +1222,7 @@ async function uninstallPackages(operationData) {
|
|
|
994
1222
|
logger.log(`The packages ${failedPackageNames.join(', ')} failed to uninstall`, 'error');
|
|
995
1223
|
}
|
|
996
1224
|
}
|
|
997
|
-
async function listPackages(operationData) {
|
|
1225
|
+
export async function listPackages(operationData) {
|
|
998
1226
|
const logger = new Logger();
|
|
999
1227
|
const packagesDir = await ensureAndGetPackagesDir();
|
|
1000
1228
|
const installedPackageNames = await readdir(packagesDir);
|
|
@@ -1017,7 +1245,7 @@ async function listPackages(operationData) {
|
|
|
1017
1245
|
logger.log(``);
|
|
1018
1246
|
logger.log(installedPackageNamesFormatted.join('\n'));
|
|
1019
1247
|
}
|
|
1020
|
-
async function serve(operationData) {
|
|
1248
|
+
export async function serve(operationData) {
|
|
1021
1249
|
const { operationOptionsLookup } = operationData;
|
|
1022
1250
|
const options = await optionsLookupToTypedObject(operationOptionsLookup, 'ServerOptions');
|
|
1023
1251
|
async function onServerStarted(serverOptions) {
|
|
@@ -1143,13 +1371,13 @@ async function optionsLookupToTypedObject(cliOptionsMap, optionsRoot, additional
|
|
|
1143
1371
|
return resultingObj;
|
|
1144
1372
|
}
|
|
1145
1373
|
let cachedOptionsSchema;
|
|
1146
|
-
|
|
1374
|
+
async function getOptionsSchema() {
|
|
1147
1375
|
if (!cachedOptionsSchema) {
|
|
1148
1376
|
cachedOptionsSchema = await readAndParseJsonFile(resolveToModuleRootDir('data/schemas/options.json'));
|
|
1149
1377
|
}
|
|
1150
1378
|
return cachedOptionsSchema;
|
|
1151
1379
|
}
|
|
1152
|
-
|
|
1380
|
+
async function checkOutputFilenames(outputFilenames, acceptMediaOutputs, acceptMetadataOutputs, acceptSubtitleOutputs) {
|
|
1153
1381
|
const supportedFileExtensions = [];
|
|
1154
1382
|
if (acceptMediaOutputs) {
|
|
1155
1383
|
supportedFileExtensions.push(...supportedOutputMediaFileExtensions);
|
|
@@ -1188,7 +1416,7 @@ export async function checkOutputFilenames(outputFilenames, acceptMediaOutputs,
|
|
|
1188
1416
|
}
|
|
1189
1417
|
return { includesPlaceholderPattern };
|
|
1190
1418
|
}
|
|
1191
|
-
|
|
1419
|
+
async function writeOutputFilesForSegment(outputFilenames, index, total, audio, timeline, text, language, allowOverwrite) {
|
|
1192
1420
|
const digitCount = Math.max((total + 1).toString().length, 2);
|
|
1193
1421
|
const segmentWords = (await splitToWords(text, language)).filter(text => wordCharacterPattern.test(text));
|
|
1194
1422
|
const segmentJoinedWords = segmentWords.join(' ').trim();
|