PYTHON 语音识别高阶篇

文章介绍了如何使用Python的PyAudio库和Vosk、OpenAIwhisper模型实现语音录音控制时间和识别功能。作者提供了详细代码示例,展示了如何在程序中集成这两种语音识别方法,并讨论了它们在实际应用中的优缺点。
摘要由CSDN通过智能技术生成

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")

解决了不能任意录音的难题。

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

注意因要把识别的长文输出固定短句,是从保存文档再次读取后截短的,而保存是增量保存而不是覆盖保存,因此输出短句还包括了所有前面的识别内容。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值