在录制音频的同时更新 Tkinter 中的进度条 Python3

Updating progress bar in Tkinter simultaneously while recording audio Python3

我对这个简单程序的目标是能够显示麦克风录音时间的进度条(范围从 0 - 30 秒)。我正在使用 Tkinter 库、Python 3.6 和 PyAudio 进行录制。

我写完了各个部分的代码(记录+更新进度条)但我不知道如何更改代码以便它们同时发生(而不是一个接一个)。此外,我意识到在录制时,GUI 冻结(我无法单击或调整按钮大小),我也想知道如何解决此问题。在做了更多研究之后,我觉得答案在于多线程或 root.update() 但我不确定。

我正在寻找录制音频的代码示例我同时更新进度条。

这是一个例子:

from tkinter import *
from tkinter import ttk
import tkinter as tk
import pyaudio
import numpy as np
np.random.seed(123)  # for reproducibility
import matplotlib
matplotlib.use('Agg')  # No pictures displayed


class Test_GUI(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        root = self

        label_title = Label(root, text="Progress Bar Recording Sample")
        label_title.pack(fil="x")

        topFrame = Frame(root)
        topFrame.pack(side=TOP)

        self.recordButton = Button(topFrame, text="Record", command=self.start)
        self.recordButton.pack(side=LEFT)

        self.progress = ttk.Progressbar(topFrame, orient="horizontal",
                                        length=200, mode="determinate")
        self.min = 0
        self.maxMin = 0
        self.progress.pack(side=RIGHT)

        # recording attributes.
        self.CHUNK = 1024
        self.FORMAT = pyaudio.paInt16
        self.CHANNELS = 2
        self.RATE = 44100
        self.RECORD_SECONDS = 15
        self.WAVE_OUTPUT_FILENAME = "/Users/Sree/Desktop/PythonPrograms/audio_output_test.wav"

    def start(self):
        print("here")

        self.progress["value"] = 0
        self.maxMin = 30
        self.progress["maximum"] = 30


        '''
        I need the following 2 lines to happen at the same time
        the progress bar needs to update from 1-30 seconds(which is the time I am recording)
        '''
        self.record()
        self.update_progress() #The progress bar is from 0 sec to 30 sec indicating what percentage of the time the mic has been recording for. 

    def update_progress(self):
        self.min += 0.1
        self.progress["value"] = self.min
        if self.min < self.maxMin:
            # update after 100 ms
            self.after(100, self.update_progress)

    def record(self):
        p = pyaudio.PyAudio()
        stream = p.open(format=self.FORMAT,
                             channels=self.CHANNELS,
                             rate=self.RATE,
                             input=True,
                             frames_per_buffer=self.CHUNK)

        print("* recording")

        frames = []

        for i in range(0, int(self.RATE / self.CHUNK * self.RECORD_SECONDS)):
            data = stream.read(self.CHUNK)
            frames.append(data)

        print("* done recording")

        stream.stop_stream()
        stream.close()
        p.terminate()

        wf = wave.open(self.WAVE_OUTPUT_FILENAME, 'wb')
        wf.setnchannels(self.CHANNELS)
        wf.setsampwidth(p.get_sample_size(self.FORMAT))
        wf.setframerate(self.RATE)
        wf.writeframes(b''.join(frames))
        wf.close()


app = Test_GUI()
app.mainloop()

为了防止 GUI 在录制时冻结,您需要在单独的线程中启动录制。为此,您可以使用 threading 模块,并将 start 方法中的 self.record() 替换为:

record_thread = threading.Thread(target=self.record, daemon=True)
record_thread.start()