最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python使用PyAudio制作錄音工具的實(shí)現(xiàn)代碼

 更新時(shí)間:2022年04月22日 12:03:58   作者:宿者朽命  
這篇文章主要介紹了Python使用PyAudio制作錄音工具,音頻錄制與視頻錄制相似,也是以數(shù)據(jù)幀的方式錄制保存,這次使用強(qiáng)大的第三方包PyAudio和內(nèi)置的wave模塊編寫,需要的朋友可以參考下

最近有在使用屏幕錄制軟件錄制桌面,在用的過程中突發(fā)奇想,使用python能不能做屏幕錄制工具,也鍛煉下自己的動(dòng)手能力。
接下準(zhǔn)備寫使用python如何做屏幕錄制工具的系列文章:

錄制屏幕制作視頻 

錄制音頻   

合成視頻,音頻

基于pyqt5制作可視化窗口

大概上述四個(gè)部分,希望自己能夠盡快完善,上一篇文章利用opencv制作了屏幕錄制部分,接下繼續(xù)更新系列,使用python錄制音頻。

應(yīng)用平臺(tái)

  • windows 10
  • python 3.7

音頻錄制部分

音頻錄制與視頻錄制相似,也是以數(shù)據(jù)幀的方式錄制保存,這次使用強(qiáng)大的第三方包PyAudio和內(nèi)置的wave模塊編寫主要部分代碼:

pip install PyAudio

如果出現(xiàn)安裝失敗,可點(diǎn)擊去此處下載對應(yīng).whl文件,cp37代表python3.7環(huán)境,64代表64位操作系統(tǒng)。
假如不是下載對應(yīng)的whl包會(huì)導(dǎo)致安裝失敗,下載完成后,cmd窗口下進(jìn)入whl的所在目錄,使用pip install PyAudio-xx.whl即可完成安裝。

pyaudio.whl

音頻錄制主要代碼:

from pyaudio import PyAudio, paInt16, paContinue, paComplete

# 設(shè)置固定參數(shù)
chunk = 1024  # 每個(gè)緩沖區(qū)的幀數(shù)
format_sample = paInt16  # 采樣位數(shù)
channels = 2  # 聲道: 1,單聲道;2,雙聲道
fps = 44100  # 采樣頻率
# 這里采用回調(diào)的方式錄制音頻
def callback(in_data, frame_count, time_info, status):
    """錄制回調(diào)函數(shù)"""
    wf.writeframes(in_data)
    if xx:  # 當(dāng)某某條件滿足時(shí)
        return in_data, paContinue
    else:
        return in_data, paComplete
# 實(shí)例化PyAudio
p = PyAudio()
stream = p.open(format=format_sample,
				channels=channels,
				rate=fps,
                frames_per_buffer=chunk,
                input=True,
                input_device_index=None,  # 輸入設(shè)備索引, None為默認(rèn)設(shè)備
                stream_callback=callback   # 回調(diào)函數(shù)
                )
# 開始流錄制
stream.start_stream()
# 判斷流是否活躍
while stream.is_active():
	time.sleep(0.1)    # 0.1為靈敏度
# 錄制完成,關(guān)閉流及實(shí)例
stream.stop_stream()
stream.close()
p.terminate()

采取流式并用回調(diào)函數(shù)錄制,需要先定義保存音頻文件,用wave新建音頻二進(jìn)制文件:

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

為了后續(xù)代碼可以很好的與之結(jié)合復(fù)用,將上面的代碼包裝成類

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

源碼于文末補(bǔ)充。

音頻播放部分

播放部分代碼與錄制部分代碼相差不大,核心部分:

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,  # 輸入設(shè)備索引
				stream_callback=callback  # 輸出用回調(diào)函數(shù)
                )
stream.start_stream()
while stream.is_active():
	time.sleep(0.1)

目前暫時(shí)測試了.wav.mp3格式可以正常錄制及播放,其它類型格式音頻可以自行調(diào)用代碼進(jìn)行測試。

GUI窗口所需屬性值代碼部分

考慮到GUI窗口能較為人性化的輸出及輸入值,編寫該部分代碼,內(nèi)容含音頻時(shí)長及獲取輸入設(shè)備及輸出設(shè)備。

# 音頻時(shí)長
duration = wf.getnframes() / wf.getframerate()
# 獲取系統(tǒng)目前已安裝的輸入輸出設(shè)備
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('輸入設(shè)備:', dev_info['name'])
	elif dev_info['maxOutputChannels']:
		print('輸出設(shè)備:', dev_info['name'])

pynput監(jiān)聽鍵盤

在這部分代碼也暫時(shí)使用pynput監(jiān)聽鍵盤來對錄音做中斷處理??梢哉{(diào)用上一篇文章中的鍵盤監(jiān)聽代碼。

def hotkey(self):
    """熱鍵監(jiān)聽"""
    with keyboard.Listener(on_press=self.on_press) as listener:
        listener.join()

def on_press(self, key):
    try:
        if key.char == 't':  # t鍵,錄制結(jié)束,保存音頻
            self.flag = True
        elif key.char == 'k':  # k鍵,錄制中止,刪除文件
            self.flag = True
            self.kill = True
    except Exception as e:
        print(e)

功能與上一篇類似,不再贅述。

總結(jié)

以上就是使用PyAudio調(diào)用windows的音頻設(shè)備進(jìn)行錄制及播放,整體學(xué)習(xí)了使用類及其繼承相關(guān)知識(shí),用法在這只是展示了冰山一角,還有更多的知識(shí)等待著我們一起去探索!

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

源碼:

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  # 每個(gè)緩沖區(qū)的幀數(shù)
        self.format_sample = paInt16  # 采樣位數(shù)
        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   # 音頻時(shí)長
        self.flag = False
        self.kill = False
    def __call__(self, filename):
        """重載文件名"""
        self.filename = filename
    def callback_input(self, in_data, frame_count, time_info, status):
        """錄制回調(diào)函數(shù)"""
        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):
        """播放回調(diào)函數(shù)"""
        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,  # 輸入設(shè)備索引
                         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,  # 輸出設(shè)備索引
                                    stream_callback=self.callback_output
                                    )
            self.stream.start_stream()
            while self.stream.is_active():
                time.sleep(0.1)
    @staticmethod
    def get_duration(wf):
        """獲取音頻時(shí)長"""
        return round(wf.getnframes() / wf.getframerate(), 2)
    def get_in_out_devices(self):
        """獲取系統(tǒng)輸入輸出設(shè)備"""
        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):
        """獲取選定設(shè)備索引"""
        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):
        """結(jié)束流錄制或流播放"""
        if self.stream:
            self.stream.stop_stream()
            self.stream.close()
        self.terminate()
    def hotkey(self):
        """熱鍵監(jiān)聽"""
        with keyboard.Listener(on_press=self.on_press) as listener:
            listener.join()
    def on_press(self, key):
        try:
            if key.char == 't':  # t鍵,錄制結(jié)束,保存音頻
                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)

到此這篇關(guān)于Python使用PyAudio制作錄音工具的文章就介紹到這了,更多相關(guān)Python PyAudio錄音工具內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python2.7:使用Pyhook模塊監(jiān)聽鼠標(biāo)鍵盤事件-獲取坐標(biāo)實(shí)例

    Python2.7:使用Pyhook模塊監(jiān)聽鼠標(biāo)鍵盤事件-獲取坐標(biāo)實(shí)例

    這篇文章主要介紹了Python2.7:使用Pyhook模塊監(jiān)聽鼠標(biāo)鍵盤事件-獲取坐標(biāo)實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Python 字典與字符串的互轉(zhuǎn)實(shí)例

    Python 字典與字符串的互轉(zhuǎn)實(shí)例

    下面小編就為大家?guī)硪黄狿ython 字典與字符串的互轉(zhuǎn)實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01
  • pytorch更新tensor中指定index位置的值scatter_add_問題

    pytorch更新tensor中指定index位置的值scatter_add_問題

    這篇文章主要介紹了pytorch更新tensor中指定index位置的值scatter_add_問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • python 給圖像添加透明度(alpha通道)

    python 給圖像添加透明度(alpha通道)

    這篇文章主要介紹了python 給圖像添加透明度,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Python使用pylab庫實(shí)現(xiàn)繪制直方圖功能示例

    Python使用pylab庫實(shí)現(xiàn)繪制直方圖功能示例

    這篇文章主要介紹了Python使用pylab庫實(shí)現(xiàn)繪制直方圖功能,結(jié)合實(shí)例形式分析了Python數(shù)據(jù)讀取、遍歷以及基于pylab庫繪制直方圖的相關(guān)操作技巧,需要的朋友可以參考下
    2018-06-06
  • python 時(shí)間的訪問和轉(zhuǎn)換 time示例小結(jié)

    python 時(shí)間的訪問和轉(zhuǎn)換 time示例小結(jié)

    Python 的 time 模塊提供了各種與時(shí)間處理相關(guān)的功能,包括獲取當(dāng)前時(shí)間、操作日期/時(shí)間以及執(zhí)行與時(shí)間相關(guān)的各種其它功能,這篇文章主要介紹了python 時(shí)間的訪問和轉(zhuǎn)換 time,需要的朋友可以參考下
    2024-05-05
  • Python進(jìn)程的通信Queue、Pipe實(shí)例分析

    Python進(jìn)程的通信Queue、Pipe實(shí)例分析

    這篇文章主要介紹了Python進(jìn)程的通信Queue、Pipe,結(jié)合實(shí)例形式分析了Python進(jìn)程通信Queue、Pipe基本概念、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • 一維信號(hào)小波去噪原理解析及python實(shí)現(xiàn)方式

    一維信號(hào)小波去噪原理解析及python實(shí)現(xiàn)方式

    這篇文章主要介紹了一維信號(hào)小波去噪原理解析及python實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Django與FastAPI的選擇區(qū)別深入剖析

    Django與FastAPI的選擇區(qū)別深入剖析

    這篇文章主要為大家介紹了Django與FastAPI的選擇區(qū)別深入剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • pandas中DataFrame重置索引的幾種方法

    pandas中DataFrame重置索引的幾種方法

    在pandas中,經(jīng)常對數(shù)據(jù)進(jìn)行處理 而導(dǎo)致數(shù)據(jù)索引順序混亂,從而影響數(shù)據(jù)讀取、插入等,所以小編總結(jié)了幾種索引重置的方法,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評(píng)論

修水县| 盐池县| 霍州市| 乐东| 平泉县| 汤原县| 民县| 宜昌市| 潍坊市| 镇沅| 赤水市| 清徐县| 阿拉善左旗| 彭山县| 库尔勒市| 德兴市| 南开区| 抚州市| 大名县| 普陀区| 八宿县| 琼结县| 怀仁县| 汕尾市| 宁强县| 泽库县| 静宁县| 博客| 双城市| 仙游县| 张家港市| 清丰县| 宜阳县| 方城县| 襄城县| 察隅县| 肃北| 新乡市| 张掖市| 金溪县| 德庆县|