mia-narrative 1.0.0 → 1.0.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.
- package/.claude/settings.local.json +8 -0
- package/dist/src/commands/generate.d.ts.map +1 -1
- package/dist/src/commands/generate.js +94 -3
- package/dist/src/commands/generate.js.map +1 -1
- package/dist/src/engines/SystemTtsEngine.js +4 -4
- package/dist/src/engines/SystemTtsEngine.js.map +1 -1
- package/package.json +4 -2
- package/scripts/setup.js +85 -0
- package/src/commands/generate.ts +100 -5
- package/src/engines/SystemTtsEngine.ts +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/commands/generate.ts"],"names":[],"mappings":"AAYA,OAAO,EAAiB,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGlE,UAAU,eAAe;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/commands/generate.ts"],"names":[],"mappings":"AAYA,OAAO,EAAiB,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGlE,UAAU,eAAe;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAmED,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA8I7E"}
|
|
@@ -7,6 +7,51 @@ import { FileReader } from '../utils/file-reader.js';
|
|
|
7
7
|
import { Logger } from '../utils/logger.js';
|
|
8
8
|
import { EngineFactory } from '../engines/factory.js';
|
|
9
9
|
import { AudioProcessor } from '../audio/processor.js';
|
|
10
|
+
function printEngineSetupGuide(engine) {
|
|
11
|
+
Logger.log('');
|
|
12
|
+
Logger.log('═══════════════════════════════════════════════════════════');
|
|
13
|
+
Logger.log(`Setup Guide for ${engine} Engine`);
|
|
14
|
+
Logger.log('═══════════════════════════════════════════════════════════');
|
|
15
|
+
Logger.log('');
|
|
16
|
+
if (engine === 'system') {
|
|
17
|
+
Logger.log('The system TTS engine is only available on macOS and Windows.');
|
|
18
|
+
Logger.log('');
|
|
19
|
+
Logger.log('On Linux, use the Piper engine instead:');
|
|
20
|
+
Logger.log(' mia-narrative generate --engine piper --text "hello"');
|
|
21
|
+
Logger.log('');
|
|
22
|
+
}
|
|
23
|
+
else if (engine === 'piper') {
|
|
24
|
+
Logger.log('Piper is not installed or configured. To set up:');
|
|
25
|
+
Logger.log('');
|
|
26
|
+
Logger.log('1. Install Piper:');
|
|
27
|
+
Logger.log(' → https://github.com/rhasspy/piper');
|
|
28
|
+
Logger.log('');
|
|
29
|
+
Logger.log('2. Run the setup script (automatic model download):');
|
|
30
|
+
Logger.log(' → npm run setup');
|
|
31
|
+
Logger.log('');
|
|
32
|
+
Logger.log('3. Set environment variable in your shell profile:');
|
|
33
|
+
Logger.log(' → export MIA_NARRATIVE_PIPER_MODEL="$HOME/.local/share/piper-tts/en_US-lessac-medium.onnx"');
|
|
34
|
+
Logger.log('');
|
|
35
|
+
Logger.log('4. Test:');
|
|
36
|
+
Logger.log(' → mia-narrative generate --engine piper --text "hello"');
|
|
37
|
+
Logger.log('');
|
|
38
|
+
}
|
|
39
|
+
else if (engine === 'elevenlabs') {
|
|
40
|
+
Logger.log('ElevenLabs API key not set. To use:');
|
|
41
|
+
Logger.log('');
|
|
42
|
+
Logger.log('1. Get an API key:');
|
|
43
|
+
Logger.log(' → https://elevenlabs.io/');
|
|
44
|
+
Logger.log('');
|
|
45
|
+
Logger.log('2. Set the environment variable:');
|
|
46
|
+
Logger.log(' → export ELEVENLABS_API_KEY="sk_..."');
|
|
47
|
+
Logger.log('');
|
|
48
|
+
Logger.log('3. Test:');
|
|
49
|
+
Logger.log(' → mia-narrative generate --engine elevenlabs --text "hello"');
|
|
50
|
+
Logger.log('');
|
|
51
|
+
}
|
|
52
|
+
Logger.log('═══════════════════════════════════════════════════════════');
|
|
53
|
+
Logger.log('');
|
|
54
|
+
}
|
|
10
55
|
function validateParams(params) {
|
|
11
56
|
// Filter out undefined values to preserve defaults
|
|
12
57
|
const definedParams = Object.fromEntries(Object.entries(params).filter(([, v]) => v !== undefined));
|
|
@@ -40,17 +85,63 @@ export async function generateCommand(options) {
|
|
|
40
85
|
else {
|
|
41
86
|
text = options.text;
|
|
42
87
|
}
|
|
43
|
-
|
|
88
|
+
// Determine engine to use
|
|
89
|
+
let engineType = options.engine || 'system';
|
|
90
|
+
// If default engine requested but not available, try Piper
|
|
91
|
+
if (!options.engine) {
|
|
92
|
+
try {
|
|
93
|
+
const systemEngine = await EngineFactory.create('system', {
|
|
94
|
+
piperPath: process.env.MIA_NARRATIVE_PIPER_PATH,
|
|
95
|
+
modelPath: process.env.MIA_NARRATIVE_PIPER_MODEL,
|
|
96
|
+
});
|
|
97
|
+
const isSystemAvailable = await systemEngine.isAvailable();
|
|
98
|
+
if (!isSystemAvailable) {
|
|
99
|
+
Logger.debug('System engine not available, trying Piper...');
|
|
100
|
+
try {
|
|
101
|
+
const piperEngine = await EngineFactory.create('piper', {
|
|
102
|
+
piperPath: process.env.MIA_NARRATIVE_PIPER_PATH,
|
|
103
|
+
modelPath: process.env.MIA_NARRATIVE_PIPER_MODEL,
|
|
104
|
+
});
|
|
105
|
+
if (await piperEngine.isAvailable()) {
|
|
106
|
+
engineType = 'piper';
|
|
107
|
+
Logger.debug('Using Piper engine');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch (piperError) {
|
|
111
|
+
Logger.debug('Piper engine not available either');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (systemError) {
|
|
116
|
+
Logger.debug('Error checking system engine, trying Piper...');
|
|
117
|
+
try {
|
|
118
|
+
const piperEngine = await EngineFactory.create('piper', {
|
|
119
|
+
piperPath: process.env.MIA_NARRATIVE_PIPER_PATH,
|
|
120
|
+
modelPath: process.env.MIA_NARRATIVE_PIPER_MODEL,
|
|
121
|
+
});
|
|
122
|
+
if (await piperEngine.isAvailable()) {
|
|
123
|
+
engineType = 'piper';
|
|
124
|
+
Logger.debug('Using Piper engine');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (piperError) {
|
|
128
|
+
// Will try system engine anyway
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
44
132
|
spinner.start(`Initializing ${engineType} TTS engine...`);
|
|
45
133
|
const engine = await EngineFactory.create(engineType, {
|
|
46
134
|
piperPath: process.env.MIA_NARRATIVE_PIPER_PATH,
|
|
47
135
|
modelPath: process.env.MIA_NARRATIVE_PIPER_MODEL,
|
|
48
136
|
});
|
|
49
|
-
|
|
137
|
+
// Check if engine is actually available before saying "ready"
|
|
50
138
|
if (!(await engine.isAvailable())) {
|
|
51
|
-
|
|
139
|
+
spinner.fail();
|
|
140
|
+
Logger.error(`${engine.getName()} engine not available.`);
|
|
141
|
+
printEngineSetupGuide(engineType);
|
|
52
142
|
process.exit(ExitCode.TTS_ENGINE_ERROR);
|
|
53
143
|
}
|
|
144
|
+
spinner.succeed('TTS engine ready');
|
|
54
145
|
const voices = await engine.getVoices();
|
|
55
146
|
const voiceId = options.voiceId || voices[0]?.id;
|
|
56
147
|
if (!voiceId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAElB,QAAQ,GACT,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAc,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAkBvD,SAAS,cAAc,CAAC,MAAgC;IACtD,mDAAmD;IACnD,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CACtC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAC1D,CAAC;IAEF,MAAM,SAAS,GAAG,EAAE,GAAG,oBAAoB,EAAE,GAAG,aAAa,EAAE,CAAC;IAEhE,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC1D,MAAM,KAAK,GAAG,GAA4B,CAAC;QAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACrE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAwB;IAC5D,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC;IAEtB,IAAI,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjC,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,IAAY,CAAC;QACjB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACjC,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7C,OAAO,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,OAAO,CAAC,IAAK,CAAC;QACvB,CAAC;QAED,
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/commands/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TTSEngine } from './base.js';
|
|
2
2
|
import say from 'say';
|
|
3
|
-
import { tmpdir } from 'os';
|
|
3
|
+
import { tmpdir, platform } from 'os';
|
|
4
4
|
import { join } from 'path';
|
|
5
5
|
import { randomUUID } from 'crypto';
|
|
6
6
|
import { unlinkSync, readFileSync } from 'fs';
|
|
@@ -45,9 +45,9 @@ export class SystemTtsEngine extends TTSEngine {
|
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
async isAvailable() {
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
return
|
|
48
|
+
// System TTS only works on macOS (darwin) and Windows (win32)
|
|
49
|
+
const currentPlatform = platform();
|
|
50
|
+
return currentPlatform === 'darwin' || currentPlatform === 'win32';
|
|
51
51
|
}
|
|
52
52
|
getName() {
|
|
53
53
|
return 'system';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SystemTtsEngine.js","sourceRoot":"","sources":["../../../src/engines/SystemTtsEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgD,MAAM,WAAW,CAAC;AAEpF,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"SystemTtsEngine.js","sourceRoot":"","sources":["../../../src/engines/SystemTtsEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgD,MAAM,WAAW,CAAC;AAEpF,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,OAAO,eAAgB,SAAQ,SAAS;IAC5C,KAAK,CAAC,UAAU,CAAC,MAAuB;QACtC,0CAA0C;IAC5C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAA6B;QAC/C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QAC9C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CAAC,CAAC;QAEnE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC7D,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,CAAC,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;oBACzC,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;gBAChC,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,WAAW,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;oBAC5C,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,yBAAyB;oBAChD,OAAO,CAAC,WAAW,CAAC,CAAC;gBACvB,CAAC;gBAAC,OAAO,OAAgB,EAAE,CAAC;oBAC1B,IAAI,OAAO,YAAY,KAAK,EAAE,CAAC;wBAC7B,MAAM,CAAC,KAAK,CAAC,2CAA2C,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;oBAC7E,CAAC;oBACD,MAAM,CAAC,OAAO,CAAC,CAAC;gBAClB,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,SAAS;QACb,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAkB,EAAE,MAAgB,EAAE,EAAE;gBAC/D,IAAI,GAAG,EAAE,CAAC;oBACR,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,sBAAsB,CAAC,CAAC,CAAC;gBAC1D,CAAC;gBACD,OAAO,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACnE,CAAC,CAAQ,CAAC,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,WAAW;QACf,8DAA8D;QAC9D,MAAM,eAAe,GAAG,QAAQ,EAAE,CAAC;QACnC,OAAO,eAAe,KAAK,QAAQ,IAAI,eAAe,KAAK,OAAO,CAAC;IACrE,CAAC;IAED,OAAO;QACL,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mia-narrative",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Text-to-speech CLI for narrative audio generation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsc",
|
|
11
11
|
"dev": "ts-node bin/mia-narrative.ts",
|
|
12
|
-
"test": "node --test dist/**/*.test.js"
|
|
12
|
+
"test": "node --test dist/**/*.test.js",
|
|
13
|
+
"setup": "node scripts/setup.js",
|
|
14
|
+
"postinstall": "echo 'Run: npm run setup' to configure TTS engines"
|
|
13
15
|
},
|
|
14
16
|
"keywords": [
|
|
15
17
|
"tts",
|
package/scripts/setup.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { existsSync, mkdirSync } from 'fs';
|
|
5
|
+
import { homedir, platform } from 'os';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
|
|
8
|
+
const HOME = homedir();
|
|
9
|
+
const PIPER_MODEL_DIR = join(HOME, '.local/share/piper-tts');
|
|
10
|
+
const MODEL_NAME = 'en_US-lessac-medium';
|
|
11
|
+
const MODEL_PATH = join(PIPER_MODEL_DIR, `${MODEL_NAME}.onnx`);
|
|
12
|
+
|
|
13
|
+
console.log('\n🎙️ mia-narrative Setup\n');
|
|
14
|
+
|
|
15
|
+
// Check Piper installation
|
|
16
|
+
console.log('1️⃣ Checking for Piper TTS...');
|
|
17
|
+
try {
|
|
18
|
+
execSync('which piper > /dev/null 2>&1');
|
|
19
|
+
console.log(' ✓ Piper is installed');
|
|
20
|
+
} catch {
|
|
21
|
+
console.log(' ⚠️ Piper not found in PATH');
|
|
22
|
+
console.log(' → Install from: https://github.com/rhasspy/piper');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Check FFmpeg
|
|
27
|
+
console.log('2️⃣ Checking for FFmpeg...');
|
|
28
|
+
try {
|
|
29
|
+
execSync('which ffmpeg > /dev/null 2>&1');
|
|
30
|
+
console.log(' ✓ FFmpeg is installed');
|
|
31
|
+
} catch {
|
|
32
|
+
console.log(' ⚠️ FFmpeg not found');
|
|
33
|
+
console.log(' → Install: brew install ffmpeg (macOS) or apt-get install ffmpeg (Linux)');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Check/Setup Piper models
|
|
38
|
+
console.log(`3️⃣ Checking for Piper models...`);
|
|
39
|
+
if (existsSync(MODEL_PATH)) {
|
|
40
|
+
console.log(` ✓ Model found: ${MODEL_PATH}`);
|
|
41
|
+
} else {
|
|
42
|
+
console.log(` ℹ️ Model not found. Creating directory...`);
|
|
43
|
+
mkdirSync(PIPER_MODEL_DIR, { recursive: true });
|
|
44
|
+
console.log(` 📥 Downloading model ${MODEL_NAME}...`);
|
|
45
|
+
console.log(` (This may take a few minutes, ~61MB)...`);
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const modelUrl = `https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/lessac/medium/${MODEL_NAME}.onnx`;
|
|
49
|
+
const configUrl = `${modelUrl}.json`;
|
|
50
|
+
|
|
51
|
+
execSync(`curl -L "${modelUrl}" -o "${MODEL_PATH}"`, { stdio: 'inherit' });
|
|
52
|
+
execSync(`curl -L "${configUrl}" -o "${MODEL_PATH}.json"`, { stdio: 'inherit' });
|
|
53
|
+
|
|
54
|
+
console.log(' ✓ Model downloaded successfully');
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.log(' ✗ Failed to download model');
|
|
57
|
+
console.log(' → You can manually download from:');
|
|
58
|
+
console.log(` https://huggingface.co/rhasspy/piper-voices`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Set environment variable
|
|
64
|
+
console.log('\n4️⃣ Configuring environment...');
|
|
65
|
+
const envVar = `MIA_NARRATIVE_PIPER_MODEL=${MODEL_PATH}`;
|
|
66
|
+
|
|
67
|
+
if (process.env.SHELL?.includes('zsh')) {
|
|
68
|
+
const rcFile = join(HOME, '.zshrc');
|
|
69
|
+
console.log(` Add this to ${rcFile}:`);
|
|
70
|
+
console.log(` export ${envVar}`);
|
|
71
|
+
} else if (process.env.SHELL?.includes('bash')) {
|
|
72
|
+
const rcFile = join(HOME, '.bashrc');
|
|
73
|
+
console.log(` Add this to ${rcFile}:`);
|
|
74
|
+
console.log(` export ${envVar}`);
|
|
75
|
+
} else {
|
|
76
|
+
console.log(` Set this in your shell profile:`);
|
|
77
|
+
console.log(` export ${envVar}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
console.log('\n✅ Setup complete!');
|
|
81
|
+
console.log('\nNext steps:');
|
|
82
|
+
console.log('1. Add the environment variable to your shell profile');
|
|
83
|
+
console.log('2. Run: source ~/.bashrc (or ~/.zshrc)');
|
|
84
|
+
console.log('3. Test: mia-narrative generate --engine piper --text "hello"');
|
|
85
|
+
console.log('\n');
|
package/src/commands/generate.ts
CHANGED
|
@@ -29,6 +29,52 @@ interface GenerateOptions {
|
|
|
29
29
|
pause?: number;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
function printEngineSetupGuide(engine: string): void {
|
|
33
|
+
Logger.log('');
|
|
34
|
+
Logger.log('═══════════════════════════════════════════════════════════');
|
|
35
|
+
Logger.log(`Setup Guide for ${engine} Engine`);
|
|
36
|
+
Logger.log('═══════════════════════════════════════════════════════════');
|
|
37
|
+
Logger.log('');
|
|
38
|
+
|
|
39
|
+
if (engine === 'system') {
|
|
40
|
+
Logger.log('The system TTS engine is only available on macOS and Windows.');
|
|
41
|
+
Logger.log('');
|
|
42
|
+
Logger.log('On Linux, use the Piper engine instead:');
|
|
43
|
+
Logger.log(' mia-narrative generate --engine piper --text "hello"');
|
|
44
|
+
Logger.log('');
|
|
45
|
+
} else if (engine === 'piper') {
|
|
46
|
+
Logger.log('Piper is not installed or configured. To set up:');
|
|
47
|
+
Logger.log('');
|
|
48
|
+
Logger.log('1. Install Piper:');
|
|
49
|
+
Logger.log(' → https://github.com/rhasspy/piper');
|
|
50
|
+
Logger.log('');
|
|
51
|
+
Logger.log('2. Run the setup script (automatic model download):');
|
|
52
|
+
Logger.log(' → npm run setup');
|
|
53
|
+
Logger.log('');
|
|
54
|
+
Logger.log('3. Set environment variable in your shell profile:');
|
|
55
|
+
Logger.log(' → export MIA_NARRATIVE_PIPER_MODEL="$HOME/.local/share/piper-tts/en_US-lessac-medium.onnx"');
|
|
56
|
+
Logger.log('');
|
|
57
|
+
Logger.log('4. Test:');
|
|
58
|
+
Logger.log(' → mia-narrative generate --engine piper --text "hello"');
|
|
59
|
+
Logger.log('');
|
|
60
|
+
} else if (engine === 'elevenlabs') {
|
|
61
|
+
Logger.log('ElevenLabs API key not set. To use:');
|
|
62
|
+
Logger.log('');
|
|
63
|
+
Logger.log('1. Get an API key:');
|
|
64
|
+
Logger.log(' → https://elevenlabs.io/');
|
|
65
|
+
Logger.log('');
|
|
66
|
+
Logger.log('2. Set the environment variable:');
|
|
67
|
+
Logger.log(' → export ELEVENLABS_API_KEY="sk_..."');
|
|
68
|
+
Logger.log('');
|
|
69
|
+
Logger.log('3. Test:');
|
|
70
|
+
Logger.log(' → mia-narrative generate --engine elevenlabs --text "hello"');
|
|
71
|
+
Logger.log('');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
Logger.log('═══════════════════════════════════════════════════════════');
|
|
75
|
+
Logger.log('');
|
|
76
|
+
}
|
|
77
|
+
|
|
32
78
|
function validateParams(params: Partial<AudioParameters>): AudioParameters {
|
|
33
79
|
// Filter out undefined values to preserve defaults
|
|
34
80
|
const definedParams = Object.fromEntries(
|
|
@@ -71,21 +117,70 @@ export async function generateCommand(options: GenerateOptions): Promise<void> {
|
|
|
71
117
|
text = options.text!;
|
|
72
118
|
}
|
|
73
119
|
|
|
74
|
-
|
|
120
|
+
// Determine engine to use
|
|
121
|
+
let engineType = options.engine || 'system';
|
|
122
|
+
|
|
123
|
+
// If default engine requested but not available, try Piper
|
|
124
|
+
if (!options.engine) {
|
|
125
|
+
try {
|
|
126
|
+
const systemEngine = await EngineFactory.create('system', {
|
|
127
|
+
piperPath: process.env.MIA_NARRATIVE_PIPER_PATH,
|
|
128
|
+
modelPath: process.env.MIA_NARRATIVE_PIPER_MODEL,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const isSystemAvailable = await systemEngine.isAvailable();
|
|
132
|
+
if (!isSystemAvailable) {
|
|
133
|
+
Logger.debug('System engine not available, trying Piper...');
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
const piperEngine = await EngineFactory.create('piper', {
|
|
137
|
+
piperPath: process.env.MIA_NARRATIVE_PIPER_PATH,
|
|
138
|
+
modelPath: process.env.MIA_NARRATIVE_PIPER_MODEL,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
if (await piperEngine.isAvailable()) {
|
|
142
|
+
engineType = 'piper';
|
|
143
|
+
Logger.debug('Using Piper engine');
|
|
144
|
+
}
|
|
145
|
+
} catch (piperError) {
|
|
146
|
+
Logger.debug('Piper engine not available either');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
} catch (systemError) {
|
|
150
|
+
Logger.debug('Error checking system engine, trying Piper...');
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
const piperEngine = await EngineFactory.create('piper', {
|
|
154
|
+
piperPath: process.env.MIA_NARRATIVE_PIPER_PATH,
|
|
155
|
+
modelPath: process.env.MIA_NARRATIVE_PIPER_MODEL,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
if (await piperEngine.isAvailable()) {
|
|
159
|
+
engineType = 'piper';
|
|
160
|
+
Logger.debug('Using Piper engine');
|
|
161
|
+
}
|
|
162
|
+
} catch (piperError) {
|
|
163
|
+
// Will try system engine anyway
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
75
168
|
spinner.start(`Initializing ${engineType} TTS engine...`);
|
|
76
169
|
const engine = await EngineFactory.create(engineType, {
|
|
77
170
|
piperPath: process.env.MIA_NARRATIVE_PIPER_PATH,
|
|
78
171
|
modelPath: process.env.MIA_NARRATIVE_PIPER_MODEL,
|
|
79
172
|
});
|
|
80
|
-
spinner.succeed('TTS engine ready');
|
|
81
173
|
|
|
174
|
+
// Check if engine is actually available before saying "ready"
|
|
82
175
|
if (!(await engine.isAvailable())) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
);
|
|
176
|
+
spinner.fail();
|
|
177
|
+
Logger.error(`${engine.getName()} engine not available.`);
|
|
178
|
+
printEngineSetupGuide(engineType);
|
|
86
179
|
process.exit(ExitCode.TTS_ENGINE_ERROR);
|
|
87
180
|
}
|
|
88
181
|
|
|
182
|
+
spinner.succeed('TTS engine ready');
|
|
183
|
+
|
|
89
184
|
const voices = await engine.getVoices();
|
|
90
185
|
const voiceId = options.voiceId || voices[0]?.id;
|
|
91
186
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TTSEngine, GenerateAudioOptions, Voice, TTSEngineConfig } from './base.js';
|
|
2
2
|
import { AudioParameters } from '../config/defaults.js';
|
|
3
3
|
import say from 'say';
|
|
4
|
-
import { tmpdir } from 'os';
|
|
4
|
+
import { tmpdir, platform } from 'os';
|
|
5
5
|
import { join } from 'path';
|
|
6
6
|
import { randomUUID } from 'crypto';
|
|
7
7
|
import { unlinkSync, readFileSync } from 'fs';
|
|
@@ -50,9 +50,9 @@ export class SystemTtsEngine extends TTSEngine {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
async isAvailable(): Promise<boolean> {
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
return
|
|
53
|
+
// System TTS only works on macOS (darwin) and Windows (win32)
|
|
54
|
+
const currentPlatform = platform();
|
|
55
|
+
return currentPlatform === 'darwin' || currentPlatform === 'win32';
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
getName(): string {
|