Python、speech_recognition 工具无法识别 .wav 文件
Python, speech_recognition tool does not recognize .wav file
我生成了一个 .wav 音频文件,其中包含一些语音和背景中的一些其他干扰语音。
此代码适用于我的测试 .wav 文件:
import speech_recognition as sr
r = sr.Recognizer()
with sr.WavFile(wav_path) as source:
audio = r.record(source)
text = r.recognize_google(audio)
如果我使用我的 .wav 文件,我会收到以下错误:
ValueError: Audio file could not be read as PCM WAV, AIFF/AIFF-C, or Native FLAC; check if file is corrupted or in another format
如果我用声音文件保存这个 .wav 文件,情况会略有改善:
import soundfile as sf
wav, samplerate = sf.read(wav_path)
sf.write(saved_wav_path, original_wav, fs)
然后将新的 saved_wav_path 加载回第一个代码块,这次我得到:
if not isinstance(actual_result, dict) or len(actual_result.get("alternative", [])) == 0: raise UnknownValueError()
音频文件保存为
wavfile.write(wav_path, fs, data)
其中 wav_path = 'data.wav'。有什么想法吗?
解决方案:
按以下方式保存音频数据会生成正确的 .wav 文件:
import wavio
wavio.write(wav_path, data, fs ,sampwidth=2)
通过简要查看 speech_recognition
包中的代码,它似乎使用 Python 标准库中的 wave
来读取 WAV 文件。 Python 的 wave
库不处理浮点 WAV 文件,因此您必须确保对以整数格式保存的文件使用 speech_recognition
。
SciPy 的函数 scipy.io.wavfile.write
将创建一个整数文件,如果您向它传递一个整数数组。所以如果 data
是一个浮点数 numpy 数组,你可以试试这个:
from scipy.io import wavfile
# Convert `data` to 32 bit integers:
y = (np.iinfo(np.int32).max * (data/np.abs(data).max())).astype(np.int32)
wavfile.write(wav_path, fs, y)
然后尝试使用 speech_recognition
读取该文件。
或者,您可以使用 wavio
(我创建的一个小型库)将数据保存到 WAV 文件。它还使用 Python 的 wave
库来创建其输出,因此 speech_recognition
应该能够读取它创建的文件。
我无法从其文档中找出 wavio 的 sampwidth 应该是多少;但是,我添加了以下行 sounddevice.default.dtype='int32', 'int32'
,它允许 sounddevice、scipy.io.wavfile.write / soundfile 和 speech_recognizer 最终协同工作。对于输入和输出,声音设备的默认数据类型都是 float32。我尝试只更改输出,但没有用。奇怪的是,audacity 仍然认为输出文件是 float32。我并不是说这是一个更好的解决方案,但它确实适用于声音文件和 scipy.
我还注意到另一个奇怪的地方。当 sounddevice.default.dtype 保留为默认 [float32, float32] 时,我大胆地打开了生成的文件。我从 audacity 导出它,这个导出的 wav 可以与 speechrecognizer 一起使用。 Audacity 说它的导出是 float32 和相同的采样率,所以我不完全理解。我是一个菜鸟,但在十六进制编辑器中查看了两个文件,前 64 个十六进制值看起来相同,然后它们不同......所以看起来 header 是相同的。这两个看起来与我使用 int32 输出制作的文件非常不同,所以似乎还有另一个因素在起作用......
我生成了一个 .wav 音频文件,其中包含一些语音和背景中的一些其他干扰语音。 此代码适用于我的测试 .wav 文件:
import speech_recognition as sr
r = sr.Recognizer()
with sr.WavFile(wav_path) as source:
audio = r.record(source)
text = r.recognize_google(audio)
如果我使用我的 .wav 文件,我会收到以下错误:
ValueError: Audio file could not be read as PCM WAV, AIFF/AIFF-C, or Native FLAC; check if file is corrupted or in another format
如果我用声音文件保存这个 .wav 文件,情况会略有改善:
import soundfile as sf
wav, samplerate = sf.read(wav_path)
sf.write(saved_wav_path, original_wav, fs)
然后将新的 saved_wav_path 加载回第一个代码块,这次我得到:
if not isinstance(actual_result, dict) or len(actual_result.get("alternative", [])) == 0: raise UnknownValueError()
音频文件保存为
wavfile.write(wav_path, fs, data)
其中 wav_path = 'data.wav'。有什么想法吗?
解决方案:
按以下方式保存音频数据会生成正确的 .wav 文件:
import wavio
wavio.write(wav_path, data, fs ,sampwidth=2)
通过简要查看 speech_recognition
包中的代码,它似乎使用 Python 标准库中的 wave
来读取 WAV 文件。 Python 的 wave
库不处理浮点 WAV 文件,因此您必须确保对以整数格式保存的文件使用 speech_recognition
。
SciPy 的函数 scipy.io.wavfile.write
将创建一个整数文件,如果您向它传递一个整数数组。所以如果 data
是一个浮点数 numpy 数组,你可以试试这个:
from scipy.io import wavfile
# Convert `data` to 32 bit integers:
y = (np.iinfo(np.int32).max * (data/np.abs(data).max())).astype(np.int32)
wavfile.write(wav_path, fs, y)
然后尝试使用 speech_recognition
读取该文件。
或者,您可以使用 wavio
(我创建的一个小型库)将数据保存到 WAV 文件。它还使用 Python 的 wave
库来创建其输出,因此 speech_recognition
应该能够读取它创建的文件。
我无法从其文档中找出 wavio 的 sampwidth 应该是多少;但是,我添加了以下行 sounddevice.default.dtype='int32', 'int32'
,它允许 sounddevice、scipy.io.wavfile.write / soundfile 和 speech_recognizer 最终协同工作。对于输入和输出,声音设备的默认数据类型都是 float32。我尝试只更改输出,但没有用。奇怪的是,audacity 仍然认为输出文件是 float32。我并不是说这是一个更好的解决方案,但它确实适用于声音文件和 scipy.
我还注意到另一个奇怪的地方。当 sounddevice.default.dtype 保留为默认 [float32, float32] 时,我大胆地打开了生成的文件。我从 audacity 导出它,这个导出的 wav 可以与 speechrecognizer 一起使用。 Audacity 说它的导出是 float32 和相同的采样率,所以我不完全理解。我是一个菜鸟,但在十六进制编辑器中查看了两个文件,前 64 个十六进制值看起来相同,然后它们不同......所以看起来 header 是相同的。这两个看起来与我使用 int32 输出制作的文件非常不同,所以似乎还有另一个因素在起作用......