Python使用PyAudio制作录音工具的实现代码

目录
  • 应用平台
  • 音频录制部分
  • 音频播放部分
  • GUI窗口所需属性值代码部分
  • pynput监听键盘
  • 总结

最近有在使用屏幕录制软件录制桌面,在用的过程中突发奇想,使用python能不能做屏幕录制工具,也锻炼下自己的动手能力。
接下准备写使用python如何做屏幕录制工具的系列文章:

录制屏幕制作视频

录制音频

合成视频,音频

基于pyqt5制作可视化窗口

大概上述四个部分,希望自己能够尽快完善,上一篇文章利用opencv制作了屏幕录制部分,接下继续更新系列,使用python录制音频。

应用平台

  • windows 10
  • python 3.7

音频录制部分

音频录制与视频录制相似,也是以数据帧的方式录制保存,这次使用强大的第三方包PyAudio和内置的wave模块编写主要部分代码:

pip install PyAudio

如果出现安装失败,可点击去此处下载对应.whl文件,cp37代表python3.7环境,64代表64位操作系统。
假如不是下载对应的whl包会导致安装失败,下载完成后,cmd窗口下进入whl的所在目录,使用pip install PyAudio-xx.whl即可完成安装。

音频录制主要代码:

from pyaudio import PyAudio, paInt16, paContinue, paComplete

# 设置固定参数
chunk = 1024  # 每个缓冲区的帧数
format_sample = paInt16  # 采样位数
channels = 2  # 声道: 1,单声道;2,双声道
fps = 44100  # 采样频率
# 这里采用回调的方式录制音频
def callback(in_data, frame_count, time_info, status):
    """录制回调函数"""
    wf.writeframes(in_data)
    if xx:  # 当某某条件满足时
        return in_data, paContinue
    else:
        return in_data, paComplete
# 实例化PyAudio
p = PyAudio()
stream = p.open(format=format_sample,
				channels=channels,
				rate=fps,
                frames_per_buffer=chunk,
                input=True,
                input_device_index=None,  # 输入设备索引, None为默认设备
                stream_callback=callback   # 回调函数
                )
# 开始流录制
stream.start_stream()
# 判断流是否活跃
while stream.is_active():
	time.sleep(0.1)    # 0.1为灵敏度
# 录制完成,关闭流及实例
stream.stop_stream()
stream.close()
p.terminate()

采取流式并用回调函数录制,需要先定义保存音频文件,用wave新建音频二进制文件:

import wave
wf = wave.open('test.wav', 'wb')
wf.setnchannels(channels)
wf.setsampwidth(p.get_sample_size(format_sample))
wf.setframerate(fps)

为了后续代码可以很好的与之结合复用,将上面的代码包装成类

from pyaudio import PyAudio
class AudioRecord(PyAudio):
    def __init__(self,):

源码于文末补充。

音频播放部分

播放部分代码与录制部分代码相差不大,核心部分:

wf = wave.open('test.wav', 'rb')
def callback(in_data, frame_count, time_info, status):
	data = wf.readframes(frame_count)
	return data, paContinue
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
				channels=wf.getnchannels(),
                rate=wf.getframerate(),
				output=True,
				output_device_index=output_device_index,  # 输入设备索引
				stream_callback=callback  # 输出用回调函数
                )
stream.start_stream()
while stream.is_active():
	time.sleep(0.1)

目前暂时测试了.wav.mp3格式可以正常录制及播放,其它类型格式音频可以自行调用代码进行测试。

GUI窗口所需属性值代码部分

考虑到GUI窗口能较为人性化的输出及输入值,编写该部分代码,内容含音频时长及获取输入设备及输出设备。

# 音频时长
duration = wf.getnframes() / wf.getframerate()
# 获取系统目前已安装的输入输出设备
dev_info = self.get_device_info_by_index(i)
default_rate = int(dev_info['defaultSampleRate'])
if not dev_info['hostApi'] and default_rate == fps and '映射器' not in dev_info['name']:
	if dev_info['maxInputChannels']:
		print('输入设备:', dev_info['name'])
	elif dev_info['maxOutputChannels']:
		print('输出设备:', dev_info['name'])

pynput监听键盘

在这部分代码也暂时使用pynput监听键盘来对录音做中断处理。可以调用上一篇文章中的键盘监听代码。

def hotkey(self):
    """热键监听"""
    with keyboard.Listener(on_press=self.on_press) as listener:
        listener.join()

def on_press(self, key):
    try:
        if key.char == 't':  # t键,录制结束,保存音频
            self.flag = True
        elif key.char == 'k':  # k键,录制中止,删除文件
            self.flag = True
            self.kill = True
    except Exception as e:
        print(e)

功能与上一篇类似,不再赘述。

总结

以上就是使用PyAudio调用windows的音频设备进行录制及播放,整体学习了使用类及其继承相关知识,用法在这只是展示了冰山一角,还有更多的知识等待着我们一起去探索!

于二零二一年十二月二十日作

源码:

import wave
import time
from pathlib import Path
from threading import Thread
from pyaudio import PyAudio, paInt16, paContinue, paComplete
from pynput import keyboard  # pip install pynput

class AudioRecord(PyAudio):
    def __init__(self, channels=2):
        super().__init__()
        self.chunk = 1024  # 每个缓冲区的帧数
        self.format_sample = paInt16  # 采样位数
        self.channels = channels  # 声道: 1,单声道;2,双声道
        self.fps = 44100  # 采样频率
        self.input_dict = None
        self.output_dict = None
        self.stream = None
        self.filename = '~test.wav'
        self.duration = 0   # 音频时长
        self.flag = False
        self.kill = False
    def __call__(self, filename):
        """重载文件名"""
        self.filename = filename
    def callback_input(self, in_data, frame_count, time_info, status):
        """录制回调函数"""
        self.wf.writeframes(in_data)
        if not self.flag:
            return in_data, paContinue
        else:
            return in_data, paComplete
    def callback_output(self, in_data, frame_count, time_info, status):
        """播放回调函数"""
        data = self.wf.readframes(frame_count)
        return data, paContinue
    def open_stream(self, name):
        """打开录制流"""
        input_device_index = self.get_device_index(name, True) if name else None
        return self.open(format=self.format_sample,
                         channels=self.channels,
                         rate=self.fps,
                         frames_per_buffer=self.chunk,
                         input=True,
                         input_device_index=input_device_index,  # 输入设备索引
                         stream_callback=self.callback_input
                         )
    def audio_record_run(self, name=None):
        """音频录制"""
        self.wf = self.save_audio_file(self.filename)
        self.stream = self.open_stream(name)
        self.stream.start_stream()
        while self.stream.is_active():
            time.sleep(0.1)
        self.wf.close()
        if self.kill:
            Path(self.filename).unlink()
        self.duration = self.get_duration(self.wf)
        print(self.duration)
        self.terminate_run()
    def run(self, filename=None, name=None, record=True):
        """音频录制线程"""
        thread_1 = Thread(target=self.hotkey, daemon=True)
        if record:
            # 录制
            if filename:
                self.filename = filename
            thread_2 = Thread(target=self.audio_record_run, args=(name,))
            # 播放
            if not filename:
                raise Exception('未输入音频文件名,不能播放,请输入后再试!')
            thread_2 = Thread(target=self.read_audio, args=(filename, name,))
        thread_1.start()
        thread_2.start()
    def read_audio(self, filename, name=None):
        """音频播放"""
        output_device_index = self.get_device_index(name, False) if name else None
        with wave.open(filename, 'rb') as self.wf:
            self.duration = self.get_duration(self.wf)
            self.stream = self.open(format=self.get_format_from_width(self.wf.getsampwidth()),
                                    channels=self.wf.getnchannels(),
                                    rate=self.wf.getframerate(),
                                    output=True,
                                    output_device_index=output_device_index,  # 输出设备索引
                                    stream_callback=self.callback_output
                                    )
            self.stream.start_stream()
            while self.stream.is_active():
                time.sleep(0.1)
    @staticmethod
    def get_duration(wf):
        """获取音频时长"""
        return round(wf.getnframes() / wf.getframerate(), 2)
    def get_in_out_devices(self):
        """获取系统输入输出设备"""
        self.input_dict = {}
        self.output_dict = {}
        for i in range(self.get_device_count()):
            dev_info = self.get_device_info_by_index(i)
            default_rate = int(dev_info['defaultSampleRate'])
            if not dev_info['hostApi'] and default_rate == self.fps and '映射器' not in dev_info['name']:
                if dev_info['maxInputChannels']:
                    self.input_dict[dev_info['name']] = i
                elif dev_info['maxOutputChannels']:
                    self.output_dict[dev_info['name']] = i
    def get_device_index(self, name, input_in=True):
        """获取选定设备索引"""
        if input_in and self.input_dict:
            return self.input_dict.get(name, -1)
        elif not input_in and self.output_dict:
            return self.output_dict.get(name, -1)
    def save_audio_file(self, filename):
        """音频文件保存"""
        wf = wave.open(filename, 'wb')
        wf.setnchannels(self.channels)
        wf.setsampwidth(self.get_sample_size(self.format_sample))
        wf.setframerate(self.fps)
        return wf
    def terminate_run(self):
        """结束流录制或流播放"""
        if self.stream:
            self.stream.stop_stream()
            self.stream.close()
        self.terminate()
    def hotkey(self):
        """热键监听"""
        with keyboard.Listener(on_press=self.on_press) as listener:
            listener.join()
    def on_press(self, key):
        try:
            if key.char == 't':  # t键,录制结束,保存音频
                self.flag = True
            elif key.char == 'k':  # k键,录制中止,删除文件
                self.kill = True
        except Exception as e:
            print(e)
if __name__ == '__main__':
    audio_record = AudioRecord()
    audio_record.get_in_out_devices()
    # 录制
    print(audio_record.input_dict)
    audio_record.run('test.mp3')
    # 播放
    print(audio_record.output_dict)
    audio_record.run('test.mp3', record=False)

到此这篇关于Python使用PyAudio制作录音工具的文章就介绍到这了,更多相关Python PyAudio录音工具内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python音频操作工具PyAudio上手教程详解

    ​ 0.引子 当需要使用Python处理音频数据时,使用python读取与播放声音必不可少,下面介绍一个好用的处理音频PyAudio工具包. PyAudio是Python开源工具包,由名思义,是提供对语音操作的工具包.提供录音播放处理等功能,可以视作语音领域的OpenCv. 1.简介 PyAudio为跨平台音频I / O库 PortAudio 提供 Python 绑定.使用PyAudio,您可以轻松地使用Python在各种平台上播放和录制音频,例如GNU / Linux,Microsoft Wi

  • Python+opencv+pyaudio实现带声音屏幕录制

    基于个人的爱好和现实的需求,决定用Python做一个屏幕录制的脚本.因为要看一些加密的视频,每次都要登录,特别麻烦,遂决定用自己写的脚本,将加密视频的播放过程全程录制下来,这样以后看自己的录播就好了.结合近期自己学习的内容,正好用Python来练练手,巩固自己的学习效果. 经过多番搜索,决定采用Python+opencv+pyaudio来实现屏幕录制.网上搜索到的录屏,基本都是不带声音的,而我要实现的是带声音的屏幕录制.下面就开始一步一步的实现吧. 声音录制 import pyaudio imp

  • Python3.7安装pyaudio教程解析

    本人笔记本电脑安装的是 python3.7, 64位操作系统,基于x64的处理器 因为 pyaudio 暂时不支持 python3.7 和 3.8,所以若需要安装 pyaudio 需要下载 whl 文件后再离线进行安装. 首先:下载安装 pyaudio 的 whl 文件 下载网址:https://www.lfd.uci.edu/~gohlke/pythonlibs/ 然后按下 ctrl+f 输入关键字:pyaudio 本人原先选择的是第一个,但是后来发现一直提示错误:ERROR: PyAudio

  • Python人工智能之路 之PyAudio 实现录音 自动化交互实现问答

    Python 很强大其原因就是因为它庞大的三方库 , 资源是非常的丰富 , 当然也不会缺少关于音频的库 关于音频, PyAudio 这个库, 可以实现开启麦克风录音, 可以播放音频文件等等,此刻我们不去了解其他的功能,只了解一下它如何实现录音的 首先要先 pip 一个 PyAudio pip install pyaudio 一.PyAudio 实现麦克风录音 然后建立一个py文件,复制如下代码 import pyaudio import wave CHUNK = 1024 FORMAT = py

  • python调用pyaudio使用麦克风录制wav声音文件的教程

    python的pyaudio可以进行录音,播放,生成wav文件等等,WAVE是录音时用的标准的WINDOWS文件格式,文件的扩展名为WAV,数据本身的格式为PCM或压缩型,属于无损音乐格式的一种.在我们研究语音识别,自然语言处理的过程中,常常会使用到它,比如我们调用百度语音识别所以我们首先研究一下pyaudio库的安装与使用. 安装: pip install pyaudio 调用pyaudio使用麦克风录制声音: python中的pyaudio库可以直接通过麦克风录制声音,我们可以通过调用该库,

  • Python使用PyAudio制作录音工具的实现代码

    目录 应用平台 音频录制部分 音频播放部分 GUI窗口所需属性值代码部分 pynput监听键盘 总结 最近有在使用屏幕录制软件录制桌面,在用的过程中突发奇想,使用python能不能做屏幕录制工具,也锻炼下自己的动手能力.接下准备写使用python如何做屏幕录制工具的系列文章: 录制屏幕制作视频 录制音频 合成视频,音频 基于pyqt5制作可视化窗口 大概上述四个部分,希望自己能够尽快完善,上一篇文章利用opencv制作了屏幕录制部分,接下继续更新系列,使用python录制音频. 应用平台 win

  • 基于Python实现千图成像工具的示例代码

    目录 前置 GUI制作 GUI界面设计 逻辑设计 图片处理 修改底图大小 修改组图大小 计算图片填充次数 组图合成 图片合成 GUI打包 千图成像也就是用N张图片组成一张图片的效果.制作方法有很多的,最常见的如用ps.懒人图云.foto-mosaik-edda这些制作. 千图成像的效果我大致分为两类:一为直接用N张图片根据底图的像素颜色.大小,一张张的组成底图,如foto-mosaik-edda:二为用N张图片根据底图的像素大小,组成一张与底图大小相仿的图片,再把二者合成,经调整透明度而成的图片

  • 由Python编写的MySQL管理工具代码实例

    本文实例为大家分享了由Python编写的MySQL管理工具的具体代码,供大家参考,具体内容如下 import pymysql import pandas as pd from tkinter import Label,StringVar,Entry,Tk,Button from tkinter.simpledialog import askstring def Entry_address(): #输入数据库地址 root=Tk() l1=Label(root,text='服务器:').grid(

  • python gui开发——制作抖音无水印视频下载工具(附源码)

    hello,大家好啊,失踪人口回归了 [捂脸]!本次使用tkinter撰写一篇 抖音无水印视频下载,目的很纯粹,就是为了设置 微信状态视频.本篇博文中,我会写下我的代码撰写思路以及想写设计流程,代码放在了第四节,工具打包好放在了 蓝奏云,慢慢看,后面有链接. 一.准备工作 本次要用到以下依赖库:re json os random tkinter threading requests pillow 其中后两个需要安装后使用 二.预览 0.复制抖音分享短链接 1.启动 2.运行 3.结果 (小姐姐挺

  • python基于tkinter制作无损音乐下载工具(附源码)

    继续写GUI,本次依然使用Tkinter设计一款图形界面,使用Tkinter做一款音乐下载软件,听起来听平常的,但是我这款软件能够下载 无损音乐下载软件,听起来不错吧,Let`s go! 一.准备工作 python Tkinter 二.预览 1.搜索 2.下载 3.结果 无损音乐就这样下载完了. 三.详细设计 这里仅展示我设计的整体思路. 四.源代码 4.1 Music_Search-v1.0.py from tkinter import * from tkinter import ttk fr

  • python基于tkinter制作m3u8视频下载工具

    这是我为了学习tkinter用python 写的一个下载m3u8视频的小程序,程序使用了多线程下载,下载后自动合并成一个视频文件,方便播放. 目前的众多视频都是m3u8的播放类型,只要知道视频的m3u8地址,就可以完美下载整个视频. m3u8地址获取 打开浏览器,点开你要获取地址的视频 重要的来了,右键>>审查元素或者按F12也可以 根据开发或测试的实际环境选择相应的设备,选择iphone6 plus 选择好了以后,刷新页面,点击漏斗,选择media,一定刷新之后再点击,没出来的话切换几下选项

  • python基于tkinter制作下班倒计时工具

    你有过摸鱼时间吗 在互联网圈子里,常常说996上班制,但是也不乏965的,更甚有007的,而007则就有点ICU的感觉了,所以,大家都会忙里偷闲,偶尔摸摸鱼,摸鱼的方式多种多样的,你有过上班摸鱼吗?你的摸鱼时间都干了些什么呢?如果你早早的完成了当天的任务,坐等下班的感觉是不是很爽呢?我想说这时间还是很难熬的,还不如找点事情做来得快呢,那做点什么呢?写个下班倒计时吧,就这么愉快的决定了-- 实现思路 倒计时的时间刷新,肯定得需要图形界面,也就是需要GUI编程,这里我用的是tkinter实现本地窗口

  • Python利用PaddleOCR制作个搜题小工具

    目录 介绍 安装 安装PaddlePaddle飞桨框架 安装PaddleOCR 代码使用 搜题小工具 安装ADB 截图并保存题目区域图片 OCR识别,获取题目 打开浏览器搜索 完整代码 介绍 PaddleOCR 是一个基于百度飞桨的OCR工具库,包含总模型仅8.6M的超轻量级中文OCR,单模型支持中英文数字组合识别.竖排文本识别.长文本识别.同时支持多种文本检测.文本识别的训练算法. 本教程将介绍PaddleOCR的基本使用方法以及如何使用它开发一个自动搜题的小工具. 项目地址 OR 安装 虽然

  • python开发一款翻译工具

    最近,某水果手机厂在万众期待中开了一场没有发布万众期待的手机产品的发布会,发布了除手机外的其他一些产品,也包括最新的水果14系统.几天后,更新了系统的吃瓜群众经过把玩突然发现新系统里一个超有意思的功能--翻译,比如这种: 奇怪的翻译知识增加了! 相比常见的翻译工具,同声翻译工具更具有实用价值,想想不精通其他语言就能和歪果朋友无障碍交流的场景,真是一件美事,不如自己动手实现个工具备用!一个同声翻译工具,逻辑大概可以是先识别,而后翻译,翻译能否成功,识别的准确率是个关键因素.为了降低难度,我决定分两

随机推荐