impress_asr_input/src/main.ts
impressionyang 1e06cbc2b8 feat: 支持无模型启动配置模式
修改:
- main.ts: 模型不存在时显示配置指引而不是退出
- model-loader.ts: 重构模型路径解析逻辑
  - 使用动态路径代替硬编码路径
  - 添加 MODEL_FILES 常量定义模型优先级
  - 支持从任意目录加载模型

用户指引:
- 无模型时显示模型下载链接
- 显示模型文件应放置的位置
- 支持 --model 参数指定模型路径

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-20 16:15:53 +08:00

132 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Impress ASR Input - 主入口
* 命令行模式入口文件
*/
import { Command } from 'commander';
import { SpeechRecognizer, RecognitionResult } from './core/speech-recognizer.js';
import { TextOutput } from './core/text-output.js';
import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
const __dirname = dirname(fileURLToPath(import.meta.url));
const packageJson = JSON.parse(
readFileSync(join(__dirname, '../package.json'), 'utf-8')
);
const program = new Command();
program
.name('impress-asr-input')
.description('基于 ONNX 的本地语音识别输入工具')
.version(packageJson.version);
program
.command('start')
.description('开始语音识别')
.option('-l, --language <lang>', '识别语言', 'zh')
.option('-m, --model <path>', '模型文件路径(可选,无模型时以配置模式启动)')
.option('-o, --output <mode>', '输出模式clipboard|keyboard|both', 'clipboard')
.action(async (options) => {
console.log('🎤 Impress ASR Input');
console.log(` 版本:${packageJson.version}`);
console.log(` 语言:${options.language}`);
console.log(` 输出:${options.output}`);
// 检查模型文件是否存在
const { existsSync } = await import('fs');
const modelPath = options.model || join(__dirname, '../models/model.onnx');
if (!existsSync(modelPath)) {
console.log('\n⚠ 未检测到模型文件,以配置模式启动');
console.log('\n📥 模型下载指引:');
console.log(' 1. SenseVoice (推荐): https://huggingface.co/FunAudioLLM/SenseVoice');
console.log(' 2. Whisper: https://huggingface.co/onnx-community/whisper-base');
console.log(' 3. Paraformer: https://www.modelscope.cn/models/damo/speech_paraformer-large-vad-punct');
console.log('\n📁 将下载的模型文件放入以下目录之一:');
console.log(' - ./models/sensevoice.onnx');
console.log(' - ./models/whisper.onnx');
console.log(' - ./models/paraformer.onnx');
console.log('\n💡 或使用 --model 参数指定模型路径');
console.log(' 示例npm start -- start -m /path/to/your/model.onnx');
return;
}
console.log(` 模型:${modelPath}`);
const recognizer = new SpeechRecognizer({
modelPath,
language: options.language,
useVad: true,
beamSize: 5,
});
const textOutput = new TextOutput({
outputMode: options.output as 'clipboard' | 'keyboard' | 'both',
autoPaste: true,
delayMs: 50,
});
// 绑定事件
recognizer.on('ready', () => {
console.log('✅ 模型加载完成,开始识别...');
recognizer.start();
});
recognizer.on('result', (result: RecognitionResult) => {
console.log(`📝 ${result.text}`);
textOutput.output(result);
});
recognizer.on('error', (error: Error) => {
console.error('❌ 识别错误:', error.message);
process.exit(1);
});
// 初始化并开始
try {
await recognizer.initialize();
// 注意:音频采集在纯 Node.js 环境需要额外处理
// 这里仅作为框架演示
console.log('⚠️ 当前为演示模式,完整功能需要 Electron 环境');
} catch (error) {
console.error('❌ 启动失败:', error);
process.exit(1);
}
// 优雅退出
process.on('SIGINT', async () => {
console.log('\n🛑 停止识别...');
recognizer.stop();
await recognizer.release();
process.exit(0);
});
});
program
.command('transcribe')
.description('转写音频文件')
.argument('<file>', '音频文件路径')
.option('-l, --language <lang>', '识别语言', 'zh')
.option('-m, --model <path>', '模型文件路径')
.option('-o, --output <file>', '输出文件路径')
.action(async (file, options) => {
console.log(`🎵 转写文件:${file}`);
console.log(` 语言:${options.language}`);
// TODO: 实现文件转写功能
console.log('⚠️ 文件转写功能开发中...');
});
program
.command('list-devices')
.description('列出可用音频设备')
.action(() => {
console.log('🎧 可用音频设备:');
// TODO: 实现设备列表功能
console.log('⚠️ 设备列表功能开发中...');
});
program.parse();