pythonaudiotkinterpyaudiorecording

Tkinter start/stop button for recording audio in Python


I am writing a program to record audio with the use of a Tkinter GUI. For recording audio itself, I use this code: https://gist.github.com/sloria/5693955 in nonblocking mode.

Now I want to implement something like a start/stop button, but feel like I am missing out on something. Following suppositions:

  1. I can't use a while Truestatement either a time.sleep()function because it's going to break the Tkinter mainloop()

  2. As a result, I will probably have to use a global bool to check whether my start_recording()function is running

  3. I will have to call stop_recording in the same function as start_recordingbecause both have to use the same object

  4. I can not use root.after() call because I want the recording to be user-defined.

Find a code snippet of the problem below:

import tkinter as tk
from tkinter import Button
import recorder

running = False

button_rec = Button(self, text='Aufnehmen', command=self.record)
button_rec.pack()

button_stop = Button(self, text='Stop', command=self.stop)
self.button_stop.pack()

rec = recorder.Recorder(channels=2)

def stop(self):
    self.running = False

def record(self):
    running = True
    if running:
        with self.rec.open('nonblocking.wav', 'wb') as file:
            file.start_recording()
            if self.running == False:
                file.stop_recording()

root = tk.Tk()
root.mainloop()

I know there has to be a loop somewhere, but I don't know where (and how).


Solution

  • Instead of with I would use normal

    running = rec.open('nonblocking.wav', 'wb')
    
    running.stop_recording()
    

    so I would use it in two functions - start and stop - and I wouldn't need any loop for this.

    I would need only global variable running to have access to recorder in both functions.

    import tkinter as tk
    import recorder
    
    # --- functions ---
    
    def start():
        global running
    
        if running is not None:
            print('already running')
        else:
            running = rec.open('nonblocking.wav', 'wb')
            running.start_recording()
    
    def stop():
        global running
    
        if running is not None:
            running.stop_recording()
            running.close()
            running = None
        else:
            print('not running')
    
    # --- main ---
    
    rec = recorder.Recorder(channels=2)
    running = None
    
    root = tk.Tk()
    
    button_rec = tk.Button(root, text='Start', command=start)
    button_rec.pack()
    
    button_stop = tk.Button(root, text='Stop', command=stop)
    button_stop.pack()
    
    root.mainloop()