带有录音功能的 Yandex SpeechKit 识别器
YandexSpeechKit Recognizer with voice recording
我可以在 运行 YandexSpeechKit Recognizer 的同时将麦克风的声音录制到文件中吗?
需要同时进行语音识别(使用 class 识别器)并将设备麦克风的声音录制到文件中。使用标准机制 MediaRecord 是不可能的,因为 MediaRecord 和 YandexSpeechKit 使用本机方法和相同的资源。它导致某些进程(MediaRecord 或 Recognizer)崩溃。
我正在尝试使用 RecognizerListener -> onSoundDataRecorded(Recognizer recognizer, byte[] bytes) 代码如下:
@Override
public void onSoundDataRecorded(Recognizer recognizer, byte[] bytes) {
Logger.d(TAG, "onSoundDataRecorded");
write(bytes);
}
public void write(byte[] bytes) {
File file = getTmpFile();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file, true);
fos.write(bytes);
} catch (IOException e1) {
e1.printStackTrace();
} finally {
if(fos != null) {
try {
fos.flush();
fos.close();
} catch(IOException e) {
}
}
}
}
但是生成的文件无法播放。
有人可以帮我吗?
谢谢!
Yandex SpeechKit returns 原始 PCM(16 kHz 单声道 16 位)数据。您应该添加 WAV header 或作为 PCM 播放。例如在 unix-like OS 通过 sox:
play -r 16000 -b 16 -c 1 -e signed-integer filename.pcm
要添加 WAV header,您可以使用此 class https://github.com/MohammadAG/Android-SoundRecorder/blob/master/src/com/mohammadag/soundrecorder/WavConverter.java 和参数
private static final long SAMPLE_RATE = 16000;
private static final int RECORDER_BPP = 16;
private static final int CHANNELS = 1;
private static final long BYTE_RATE = RECORDER_BPP * SAMPLE_RATE * CHANNELS/8;
@Override
public void onRecognizerRecordingBegin() {
try {
tempFileName = getFilename();
os = new FileOutputStream(tempFileName, true);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
@Override
public void onRecognizerRecordingDone() {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
int bufferSize = AudioRecord.getMinBufferSize(
16000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
WavConverter.copyWaveFile(tempFileName, getFilename(), bufferSize);
deleteTempFile();
}
@Override
public void onRecognizerSoundDataRecorded(byte[] bytes) {
try {
os.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
我可以在 运行 YandexSpeechKit Recognizer 的同时将麦克风的声音录制到文件中吗?
需要同时进行语音识别(使用 class 识别器)并将设备麦克风的声音录制到文件中。使用标准机制 MediaRecord 是不可能的,因为 MediaRecord 和 YandexSpeechKit 使用本机方法和相同的资源。它导致某些进程(MediaRecord 或 Recognizer)崩溃。
我正在尝试使用 RecognizerListener -> onSoundDataRecorded(Recognizer recognizer, byte[] bytes) 代码如下:
@Override
public void onSoundDataRecorded(Recognizer recognizer, byte[] bytes) {
Logger.d(TAG, "onSoundDataRecorded");
write(bytes);
}
public void write(byte[] bytes) {
File file = getTmpFile();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file, true);
fos.write(bytes);
} catch (IOException e1) {
e1.printStackTrace();
} finally {
if(fos != null) {
try {
fos.flush();
fos.close();
} catch(IOException e) {
}
}
}
}
但是生成的文件无法播放。 有人可以帮我吗?
谢谢!
Yandex SpeechKit returns 原始 PCM(16 kHz 单声道 16 位)数据。您应该添加 WAV header 或作为 PCM 播放。例如在 unix-like OS 通过 sox:
play -r 16000 -b 16 -c 1 -e signed-integer filename.pcm
要添加 WAV header,您可以使用此 class https://github.com/MohammadAG/Android-SoundRecorder/blob/master/src/com/mohammadag/soundrecorder/WavConverter.java 和参数
private static final long SAMPLE_RATE = 16000;
private static final int RECORDER_BPP = 16;
private static final int CHANNELS = 1;
private static final long BYTE_RATE = RECORDER_BPP * SAMPLE_RATE * CHANNELS/8;
@Override
public void onRecognizerRecordingBegin() {
try {
tempFileName = getFilename();
os = new FileOutputStream(tempFileName, true);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
@Override
public void onRecognizerRecordingDone() {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
int bufferSize = AudioRecord.getMinBufferSize(
16000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
WavConverter.copyWaveFile(tempFileName, getFilename(), bufferSize);
deleteTempFile();
}
@Override
public void onRecognizerSoundDataRecorded(byte[] bytes) {
try {
os.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}