【发布时间】:2021-09-24 19:15:56
【问题描述】:
我正在尝试将实时语音识别添加到我的 java 项目中(最好是离线的)。通过一些谷歌搜索和尝试其他解决方案,我决定使用 VOSK 进行语音识别。然而,我遇到的主要问题是 VOSK 的文档很少,并且只有一个 java 示例文件,用于从预先录制的 wav 文件中提取文本,如下所示。
public static void main(String[] argv) throws IOException, UnsupportedAudioFileException {
LibVosk.setLogLevel(LogLevel.DEBUG);
try (Model model = new Model("src\\main\\resources\\model");
InputStream ais = AudioSystem.getAudioInputStream(new BufferedInputStream(new FileInputStream("src\\main\\resources\\python_example_test.wav")));
Recognizer recognizer = new Recognizer(model, 16000)) {
int nbytes;
byte[] b = new byte[4096];
while ((nbytes = ais.read(b)) >= 0) {
System.out.println(nbytes);
if (recognizer.acceptWaveForm(b, nbytes)) {
System.out.println(recognizer.getResult());
} else {
System.out.println(recognizer.getPartialResult());
}
}
System.out.println(recognizer.getFinalResult());
}
}
我试图将其转换为可以接受麦克风音频的东西,如下所示:
public static void main(String[] args) {
LibVosk.setLogLevel(LogLevel.DEBUG);
AudioFormat format = new AudioFormat(8000.0f, 16, 1, true, true);
TargetDataLine microphone;
SourceDataLine speakers;
try (Model model = new Model("src\\main\\resources\\model");
Recognizer recognizer = new Recognizer(model, 16000)) {
try {
microphone = AudioSystem.getTargetDataLine(format);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
microphone = (TargetDataLine) AudioSystem.getLine(info);
microphone.open(format);
microphone.start();
ByteArrayOutputStream out = new ByteArrayOutputStream();
int numBytesRead;
int CHUNK_SIZE = 1024;
int bytesRead = 0;
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
speakers = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
speakers.open(format);
speakers.start();
byte[] b = new byte[4096];
while (bytesRead <= 100000) {
numBytesRead = microphone.read(b, 0, CHUNK_SIZE);
bytesRead += numBytesRead;
out.write(b, 0, numBytesRead);
speakers.write(b, 0, numBytesRead);
if (recognizer.acceptWaveForm(b, numBytesRead)) {
System.out.println(recognizer.getResult());
} else {
System.out.println(recognizer.getPartialResult());
}
}
System.out.println(recognizer.getFinalResult());
speakers.drain();
speakers.close();
microphone.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这似乎正确地捕获了麦克风数据(因为它也输出到扬声器)但 VOSK 显示没有输入,不断将结果打印为空字符串。我究竟做错了什么?我正在尝试的甚至可能吗?我应该尝试寻找不同的语音识别库吗?
【问题讨论】:
-
录制的采样率 (8KHz) 与识别器的采样率 (16KHz) 不匹配。也许试着让他们平等。例如将
AudioFormat更改为 16KHz。 -
不幸的是,使它们相等似乎并不能解决问题。
-
看起来你拥有的东西应该不错。根据您的描述,扬声器正在播放麦克风正在拾取的内容? (您已确认正在向 VOSK 发送数据)。如果您有一个 .wav 文件源,VOSK 是否可以工作(您是否确认他们的基本示例有效)?如果 VOSK 有某种“开启”开关,那将是非常糟糕的,因为这在他们的示例中没有显示。你看到他们的“测试”代码了吗? github.com/alphacep/vosk-api/blob/master/java/lib/src/test/java/…
-
@PhilFreihofner,是的,扬声器确实可以正确播放麦克风音频,而且我还确认基本示例使用 .wav 文件。不幸的是,VOSK 的文档很少,所以我不知道是否有“打开”开关。我正在探索 java VOSK 的其他可能性,但如果我能够让它工作,那将是非常理想的。您对此解决方案的替代方案或使其发挥作用的方法有任何想法吗?
-
您选择了 VOSK?你试过狮身人面像吗?我不是专家,但这是更成熟的解决方案。但如果你选择了一些没有文档的东西,也许这适合你。
标签: java audio speech-recognition microphone vosk