赞
踩
1、上一篇博客中讲到用SpeechRecognition库和Vosk模型来识别语音,通过麦克风录音的话,只能录很短的录音,经过不断网上搜寻,终于找到一段能控制录音时间的代码:
- class Recorder(): # 录音程序
- def __init__(self, chunk=1024, channels=1, rate=16000):
- self.CHUNK = chunk # 音频帧率(也就是每次读取的数据是多少,默认1024)
- self.FORMAT = pyaudio.paInt16 # 采样时生成wav文件正常格式
- self.CHANNELS = channels # 音轨数(每条音轨定义了该条音轨的属性,如音轨的音色、音色库、通道数、输入/输出端口、音量等。可以多个音轨,不唯一)
- self.RATE = rate # 采样率(即每秒采样多少数据)
- self._running = True
- self._frames = [] # 定义frames为一个空列表
-
- def start(self):
- _thread.start_new_thread(self.__recording, ())
-
- def __recording(self):
- self._running = True
- self._frames = []
- p = pyaudio.PyAudio() # 创建PyAudio对象
- stream = p.open(format=self.FORMAT, # 采样生成wav文件的正常格式
- channels=self.CHANNELS, # 音轨数
- rate=self.RATE, # 采样率
- input=True, # Ture代表这是一条输入流,False代表这不是输入流
- frames_per_buffer=self.CHUNK) # 每个缓冲多少帧
- while (self._running):
- data = stream.read(self.CHUNK) # 每次读chunk个数据
- self._frames.append(data) # 将读出的数据保存到列表中
- stream.stop_stream() # 停止输入流
- stream.close() # 关闭输入流
- p.terminate() # 终止pyaudio
-
- def stop(self):
- self._running = False
-
- def save_wave(self, filename):
- p = pyaudio.PyAudio() # 创建PyAudio对象
- if not filename.endswith(".wav"):
- filename = filename + ".wav"
- wf = wave.open(filename, 'wb') # 以’wb‘二进制流写的方式打开一个文件
- wf.setnchannels(self.CHANNELS) # 设置音轨数
- wf.setsampwidth(p.get_sample_size(self.FORMAT)) # 设置采样点数据的格式,和FOMART保持一致
- wf.setframerate(self.RATE) # 设置采样率与RATE要一致
- wf.writeframes(b''.join(self._frames)) # 将声音数据写入文件
- wf.close() # 数据流保存完,关闭文件
-
- def record(self):
- print('请按回车键开始录音:')
- a = input()
- if str.__len__(a) == 0:
- begin = time.time()
- print("开始录音ing")
- self.start()
- print("请按回车键停止录音:")
- b = input()
- if str.__len__(b) == 0:
- print("录音停止")
- self.stop()
- fina = time.time()
- t = fina - begin
- print('录音时间为%ds' % t)
-
- def positive(self):
- print('下面开始录音')
- self.record()
- self.save_wave("语音录音.wav")
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
解决了不能任意录音的难题。
2、语音识别的方法很多,离线使用的却不多。上次介绍了SpeechRecognition库和Vosk模型的组合,今天介绍现在流行的用OpenAI whisper来语音识别的方法。
- def Rec_OpenAI_whisper(filename):
- '''
- print('正在识别中......')
- # 加载识别模型
- model = whisper.load_model("tiny") # 'tiny','base','medium','large'等模型,自动下载后保存在C:\Users\xxx\.cache\whisper
- source = model.transcribe(filename,language='Chinese',fp16 = True) # 识别
- said = source['text']
- save_txt(said, '识别结果4.txt')
- print("识别结果:",said)
- with open('识别结果4.txt','r',encoding='UTF-8') as file: # 用来每行固定字数输出
- lines = file.readlines()
- for line in lines:
- for a in range(1, len(line) // 60 + 2): # 将长文截成50字每行
- print('\033[33m',line[(60 * (a - 1)):60 * a].strip(),'\033[0m')
人工智能固然流行,前期安装工作也很繁琐,光是要安装的各种插件就不少:
pip install - U openai - whisper
或 pip install git+https://github.com/openai/whisper.git
pip install --upgrade --no-deps --force- reinstall git+https://github.com/openai/whisper.git
pip install zhconv
pip install wheel
pip install torch torchvision torchaudio - i https://pypi.tuna.tsinghua.edu.cn/simple
还要安装ffmpeg,先去 https://github.com/BtbN/FFmpeg-Builds/releases下载ffmpeg-master-latest-win64-gpl.zip到主程序文件夹,解压后将bin文件夹下的ffmpeg.exe拷贝到主程序文件夹下。
语音识别还要依赖whisper语音模型。常见whisper模型如下 :
我们可在终端窗口中输入下面语句来自动下载相应tiny模型。
whisper 语音录音.wav --model tiny
运行后系统就自动开始下载相应模型。
将下面中的绿框分别按红框中的模型替换,就可下载不同的模型,并自动保存在用户文件夹下,如C:\Users\ XXX\.cache\whisper
3、我将前篇的Vosk语音识别和OpenAI whisper语音识别集成在一起,成为两种可选识别方案,同时也将录音和使用现有语音文件也作为选项,增加程序牟灵活性。主菜单如下:
对于同一语音文件,使用3或4两种方案,识别效果对比如下:
看起来是OpenAI whisper完胜,理应也如此。但且慢,后面对同一语音文件进行识别,有时OpenAI whisper也会出现很多错误,并不一定都能如第一次那般准确。原因我也不清楚,难道多次识别,电脑也累了,它也需要休息?
4、附送完整代码:
- import speech_recognition as sr
- import pyaudio # 使用pyaudio库可以进行录音,播放,生成wav文件
- import time
- import _thread
- import wave # 使用wave库可读、写wav类型的音频文件
- import whisper
-
- class Recorder(): # 录音程序
- def __init__(self, chunk=1024, channels=1, rate=16000):
- self.CHUNK = chunk # 音频帧率(也就是每次读取的数据是多少,默认1024)
- self.FORMAT = pyaudio.paInt16 # 采样时生成wav文件正常格式
- self.CHANNELS = channels # 音轨数(每条音轨定义了该条音轨的属性,如音轨的音色、音色库、通道数、输入/输出端口、音量等。可以多个音轨,不唯一)
- self.RATE = rate # 采样率(即每秒采样多少数据)
- self._running = True
- self._frames = [] # 定义frames为一个空列表
-
- def start(self):
- _thread.start_new_thread(self.__recording, ())
-
- def __recording(self):
- self._running = True
- self._frames = []
- p = pyaudio.PyAudio() # 创建PyAudio对象
- stream = p.open(format=self.FORMAT, # 采样生成wav文件的正常格式
- channels=self.CHANNELS, # 音轨数
- rate=self.RATE, # 采样率
- input=True, # Ture代表这是一条输入流,False代表这不是输入流
- frames_per_buffer=self.CHUNK) # 每个缓冲多少帧
- while (self._running):
- data = stream.read(self.CHUNK) # 每次读chunk个数据
- self._frames.append(data) # 将读出的数据保存到列表中
- stream.stop_stream() # 停止输入流
- stream.close() # 关闭输入流
- p.terminate() # 终止pyaudio
-
- def stop(self):
- self._running = False
-
- def save_wave(self, filename):
- p = pyaudio.PyAudio() # 创建PyAudio对象
- if not filename.endswith(".wav"):
- filename = filename + ".wav"
- wf = wave.open(filename, 'wb') # 以’wb‘二进制流写的方式打开一个文件
- wf.setnchannels(self.CHANNELS) # 设置音轨数
- wf.setsampwidth(p.get_sample_size(self.FORMAT)) # 设置采样点数据的格式,和FOMART保持一致
- wf.setframerate(self.RATE) # 设置采样率与RATE要一致
- wf.writeframes(b''.join(self._frames)) # 将声音数据写入文件
- wf.close() # 数据流保存完,关闭文件
-
- def record(self):
- print('请按回车键开始录音:')
- a = input()
- if str.__len__(a) == 0:
- begin = time.time()
- print("开始录音ing")
- self.start()
- print("请按回车键停止录音:")
- b = input()
- if str.__len__(b) == 0:
- print("录音停止")
- self.stop()
- fina = time.time()
- t = fina - begin
- print('录音时间为%ds' % t)
-
- def positive(self):
- print('下面开始录音')
- self.record()
- self.save_wave("语音录音.wav")
-
-
- def save_txt(result, filename):
- if not filename.endswith(".txt"):
- filename = filename + ".txt"
- wf = open(filename, encoding='utf-8', mode='a+')
- wf.writelines(result)
- wf.writelines(['\n'])
- wf.close()
-
- def Rec_Vosk(filename):
- print('正在识别中......')
- # 使用Vosk语音模型识别
- r = sr.Recognizer() # 调用识别器
- audioFile = sr.AudioFile(filename) # 导入语音文件
- with audioFile as source:
- try:
- audioData = r.record(source) # 从文件中获取数据
- except sr.UnknownValueError:
- exec()
-
- def formulateResult(resu):
- start = resu.index('"', resu.index('"', resu.index('"') + 1) + 1) + 1
- end = resu.index('"', start)
- return resu[start:end]
-
- said = r.recognize_vosk(audioData) # 识别输出。下载的语音模型解压后须改文件夹名为“model”
- said = formulateResult(said)
- print("you said:", said)
- save_txt(said, '识别结果3.txt')
- with open('识别结果3.txt','r',encoding='UTF-8') as file: # 将长文截成50字每行
- lines = file.readlines()
- for line in lines:
- for a in range(1, len(line) // 60 + 2): # 将长文截成50字每行
- print('\033[33m',line[(60 * (a - 1)):60 * a].strip(),'\033[0m')
-
- def Rec_OpenAI_whisper(filename):
- print('正在识别中......')
- # 加载识别模型
- model = whisper.load_model("tiny") # 'tiny','base','medium','large'等模型,自动下载后保存在C:\Users\xxx\.cache\whisper
- source = model.transcribe(filename,language='Chinese',fp16 = True) # 识别
- said = source['text']
- save_txt(said, '识别结果4.txt')
- print("识别结果:",said)
- with open('识别结果4.txt','r',encoding='UTF-8') as file: # 将长文截成50字每行
- lines = file.readlines()
- for line in lines:
- for a in range(1, len(line) // 60 + 2):
- print('\033[33m',line[(60 * (a - 1)):60 * a].strip(),'\033[0m')
-
- if __name__ == '__main__':
- while True:
- print('*' * 24)
- print('1、重新录音')
- print('2、使用原有录音文件')
- print('3、选择Vosk模型识别')
- print('4、选择OpenAI_whisper识别')
- print('*' * 24)
- n = int(input('请选择1、2、3或4:'))
- if n == 1:
- rec = Recorder()
- rec.positive()
- if n == 2:
- filename = '语音录音.wav'
- if n == 3:
- Rec_Vosk('语音录音.wav')
- continue
- if n == 4:
- Rec_OpenAI_whisper('语音录音.wav')
- continue
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
注意因要把识别的长文输出固定短句,是从保存文档再次读取后截短的,而保存是增量保存而不是覆盖保存,因此输出短句还包括了所有前面的识别内容。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。