Update avaliable. Click RELOAD to update.
目录

声音即文字 使用 OpenAI Whisper + SoundDevice 创建即时语音转录系统

openai-whisper.webp

上一篇 “走进 OpenAI Whisper 开源语音识别技术” 介绍了如何设计用 OpenAI Whisper 借助模型实现音频识别,本篇文章将在进一步,不使用音频文件,而是直接通过麦克风将同声语音做识别转录,并做简单输出。代码尽量简单,只做探索使用。

需要用到的开源库:

音频录入转文本输出

audio-to-text-1

import sounddevice as sd
import soundfile as sf
import numpy as np
from queue import Queue
import threading
import time

import whisper

# 启动加载 whisper 语言训练模型
model = whisper.load_model("medium")

def record_audio(stop_event, data_queue):
    '''
    使用 sounddevice 库录制音频
    '''
    def callback(indata, frames, time, status):
        '''
        sounddevice.RawInputStream 回调函数

        indata 是当前缓冲区的输入数据
        frames 指示当前缓冲区中有多少帧数据
        time 提供时间信息,例如当前回调的时间戳。
        status 指示回调执行过程中的状态或错误信息
        '''

        # 如果 status 非空,即存在错误或警告,它会被打印到控制台
        if status:
            print(status)
        data_queue.put(bytes(indata))

    # 采样率16000,数据类型为16位整数,通道位1的单声道录音
    with sounddevice.RawInputStream(samplerate=16000, dtype="int16", channels=1, callback=callback):
        while not stop_event.is_set():
            # 减轻 CPU 负担,每隔 0.1 秒检查 stop_event 状态
            time.sleep(0.1)

if __name__ == '__main__':
    print('Voice service started (Press Ctrl+C to exit)')

    try:
        while True:
            print('Press Enter to start recording, again to stop')

            # --------------- 启动音频录制 ---------------

            # 创建队列存储音频字节,启动线程开始接受音频输入
            data_queue = Queue()
            stop_event = threading.Event()
            recording_thread = threading.Thread(
                target=record_audio,
                args=(stop_event, data_queue),
            )
            recording_thread.start()

            # 使用 input() 函数等待用户输入,暂停程序执行,知道用户按下回车键
            input()
            # 设置线程旗标为 True,停止录制过程
            stop_event.set()
            # 等待recording_thread线程完成,即record_audio函数完成其执行
            # 在程序结束前的一个整理步骤,确保所有资源得以适当释放且没有遗留工作
            recording_thread.join()

            # --------------- 音频数据处理 ---------------

            audio_data = b"".join(list(data_queue.queue))
            # 用 numpy 库来将字节缓冲区(audio_data)转换为一个 NumPy 数组,并做类型转换和标准化处理
            audio_np = (
                np.frombuffer(audio_data, dtype=np.int16).astype(np.float32) / 32768.0
            )

            if audio_np.size > 0:
                # 使用 openai whisper 识别音频字节数据,并输出到控制台
                result = model.transcribe(audio_np, fp16=False)
                print(result["text"])

                sd.wait()
            else:
                print("No audio recorded. Please ensure your microphone is working.")
    except KeyboardInterrupt:
        print("\nVoice service ended")

上面的代码将录制的音频字节数据,转给 OpenAI Whisper 进行语音识别,然后打印到控制台中。

voice-input

额外的一些操作

如果希望播放录制的音频,也可以使用 sounddevice 实现,但需要将录制和播放时的采样率设置成 44100,以达到正常的语速输出

# --- snip --- 
# 采样率44100
    with sounddevice.RawInputStream(samplerate=44100, dtype="int16", channels=1, callback=callback):
# --- snip --- 

if audio_np.size > 0:
    # 播放录制的音频
    sd.play(audio_np, 44100)
    sd.wait()

如果希望保存录制的内容到音频文件,可以使用 soundfile 实现,下面是片段代码

import soundfile as sf
# --- snip --- 

if audio_np.size > 0:
    # 写入录制的音频
    sf.write('output.wav', audio_np, 44100, format='WAV')

总结

比较好的实现了语音转录,基于 whisper 的训练模型,语音识别度有很大提升,下一步应该思考如何把录制的文本,再转成音频播放出来

版权所有,本作品采用知识共享署名-非商业性使用 3.0 未本地化版本许可协议进行许可。转载请注明出处:https://www.wangjun.dev//2024/04/voice-transcription-openai-whisper-sounddevice/