基于pyaudio实现的录音和播放功能

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


注意下面
如果有车载讨论需要的小伙伴,可以私信加我微信,拉你进群,和同行业大佬交流
注意上面

前言

最近由于有实现录音和播放功能的需求,最近将pyaudio实现录音和播音功能进行实现,特此进行记录


提示:以下是本篇文章正文内容,下面案例可供参考

二、详细代码

代码如下(示例):

import threading
import time
import pyaudio
from pyaudio import Stream
import wave
from typing import Optional


class SoundRecord:
    """
    功能:实现录音功能
    """

    def __init__(self):
        self.__output_file = None  # 输出文件地址
        self.__chunk = 1024  # 读取数据段
        self.__sample_format = pyaudio.paInt16  # 采样格式
        self.__channels = 1  # 声道数
        self.__sample_rate = 44100  # 采样率44.1kz
        self.__input_stream: Optional[Stream] = None  # 输入音频流
        self.__output_stream: Optional[Stream] = None  # 输出音频流
        self.__input_audio = None
        self.__output_audio = None
        self.__record_state = True
        self.__play_flag = True
        self.__frame = list()
        self.__wf = None

    def open_audio_input_stream(self):
        """
        功能:打开录音stream音频流
        """
        # 创建Pyaudio对象
        self.__input_audio = pyaudio.PyAudio()
        # 打开音频流
        try:
            self.__input_stream = self.__input_audio.open(format=self.__sample_format,
                                                          channels=self.__channels,
                                                          rate=self.__sample_rate,
                                                          frames_per_buffer=self.__chunk,
                                                          input=True)
            return True
        except OSError:  # 没有找到设备
            return False

    def open_audio_output_stream(self, file_path):
        """
        功能:打开播放stream音频流
        """
        self.__wf = wave.open(file_path, 'rb')
        self.__output_audio = pyaudio.PyAudio()
        try:
            self.__output_stream = self.__output_audio.open(format=self.__output_audio.get_format_from_width(self.__wf.getsampwidth()),
                                                            channels=self.__wf.getnchannels(),
                                                            rate=self.__wf.getframerate(),
                                                            output=True)
            return True

        except OSError:  # 没有找到设备
            return False

    def play_file_thread(self):
        """
        功能:播放文件线程
        """
        play_thread = threading.Thread(target=self.play_file)
        play_thread.start()

    def play_file(self):
        """
        功能:播放文件
        """
        data = self.__wf.readframes(1024)  # 将文件写入进播放音频流
        while len(data) > 0:
            self.__output_stream.write(data)
            data = self.__wf.readframes(1024)
        self.__output_stream.start_stream()
        self.__play_flag = False

    def close_output_thread(self):
        """
        功能:释放相关资源线程
        """
        output_thread = threading.Thread(target=self.close_output)
        output_thread.start()

    def close_output(self):
        """
        功能:释放相关资源
        """
        while self.__play_flag is False:
            self.__output_stream.stop_stream()
            self.__output_stream.close()
            self.__output_audio.terminate()
            time.sleep(0.1)
        self.__play_flag = True

    def play_wav_file(self):
        """
        功能:播放wav文件
        """
        self.play_file_thread()
        self.close_output_thread()

    def start_record_thread(self, path):
        """
        功能:开启录音线程
        参数1:需要报文文件的路径
        """
        self.__output_file = path
        record_thread = threading.Thread(target=self.start_sound_record)
        record_thread.start()

    def start_sound_record(self):
        """
        功能:开启录音函数
        """
        self.__frame = list()
        while self.__record_state:
            data = self.__input_stream.read(self.__chunk, exception_on_overflow=False)  # exception_on_overflow防止出现阻塞问题
            if data != b'':
                self.__frame.append(data)

    def stop_sound_record(self):
        """
        功能:停止录音
        """
        time.sleep(1)  # 暂停1秒,防止有未录入的数据
        self.__record_state = False
        self.close_stream()
        self.save_sound_record()

    def close_stream(self):
        """
        功能:关闭音频流
        """
        if self.__record_state is False:  # 判断是否已停止录制,此处如果直接执行,会存在录制线程还未停止的问题
            self.__input_stream.stop_stream()
            self.__input_stream.close()
            self.__input_audio.terminate()

    def save_sound_record(self):
        """
        功能:保存录音文件
        """
        wave_file = wave.open(self.__output_file, 'wb')
        wave_file.setnchannels(self.__channels)
        wave_file.setsampwidth(self.__input_audio.get_sample_size(self.__sample_format))
        wave_file.setframerate(self.__sample_rate)
        wave_file.writeframes(b''.join(self.__frame))
        wave_file.close()


if __name__ == '__main__':
    sound_record = SoundRecord()
    # audio_state = sound_record.open_audio_input_stream()  # 录制音频
    # if audio_state is True:
    #     sound_record.start_record_thread("testcode.wav")
    #     time.sleep(10)
    #     sound_record.stop_sound_record()
    # else:
    #     print("设备未连接")
    audio_output_state = sound_record.open_audio_output_stream(r'testcode.wav')  # 播放录音
    if audio_output_state is True:
        sound_record.play_wav_file()
    else:
        print("扬声器被占用")


写在最后

我是一名车载测试开发工程师,希望能和志同道合的朋友一起相互学习进步

  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用PyQt5和PyAudio实现录音和放音功能。下面是一个简单的示例代码: ```python import sys import pyaudio from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton class AudioRecorder(QWidget): def __init__(self): super().__init__() # 初始化PyAudio self.audio = pyaudio.PyAudio() # 创建布局和按钮 layout = QVBoxLayout() self.record_button = QPushButton("Record", self) self.play_button = QPushButton("Play", self) # 添加按钮到布局 layout.addWidget(self.record_button) layout.addWidget(self.play_button) # 设置主窗口布局 self.setLayout(layout) # 绑定按钮点击事件 self.record_button.clicked.connect(self.start_recording) self.play_button.clicked.connect(self.play_recording) # 初始化录音状态和声音数据 self.is_recording = False self.record_data = [] def start_recording(self): if not self.is_recording: self.is_recording = True self.record_data = [] self.record_stream = self.audio.open(format=pyaudio.paInt16, channels=1, rate=44100, input=True, frames_per_buffer=1024) def play_recording(self): if not self.is_recording and self.record_data: self.play_stream = self.audio.open(format=pyaudio.paInt16, channels=1, rate=44100, output=True) for data in self.record_data: self.play_stream.write(data) self.play_stream.stop_stream() self.play_stream.close() def closeEvent(self, event): # 关闭窗口时停止录音并释放资源 if self.is_recording: self.is_recording = False self.record_stream.stop_stream() self.record_stream.close() self.audio.terminate() event.accept() def keyPressEvent(self, event): # 按下空格键开始/停止录音 if event.key() == Qt.Key_Space: if self.is_recording: self.is_recording = False self.record_stream.stop_stream() self.record_stream.close() self.record_data.append(b''.join(self.record_buffer)) else: self.is_recording = True self.record_buffer = [] self.record_stream = self.audio.open(format=pyaudio.paInt16, channels=1, rate=44100, input=True, frames_per_buffer=1024) if __name__ == '__main__': app = QApplication(sys.argv) recorder = AudioRecorder() recorder.show() sys.exit(app.exec_()) ``` 这个程序创建了一个窗口,其中包含“Record”和“Play”两个按钮。点击“Record”按钮将开始录音,点击“Play”按钮将播放录音。程序还允许通过按下空格键开始/停止录音录音数据存储在`record_data`变量中,以字节串的形式存储。播放录音时,程序将遍历这个列表并写入声音流。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值