Я пытаюсь сделать аудиоплеер с движущимся курсором. Я хочу иметь возможность изменить звук, прекратить воспроизведение, перемещая курсор, нажимая.
Прямо сейчас, пока он играет, я могу перемещать курсор, взаимодействовать с другими кнопками на GUI (просмотрите файл et c.). Я могу воспроизвести его снова или выйти из программы ПОСЛЕ окончания звукового потока. Проблема в том, что когда я пытаюсь остановить потоковую передачу или выйти из нее, программа останавливается.
Я нашел этот пример, где для потоковой передачи используется многопроцессорная обработка. Я видел другие примеры с потоками тоже. Но, поскольку я могу взаимодействовать с GUI во время потоковой передачи, я подумал, что тоже смогу остановить поток без проблем. Это правильно? Если мне нужно использовать многопоточность, могу ли я избежать инициализации потока каждый раз, когда я играю?
Я проверил этот тоже для блиттинга и событий, но нет функции остановки.
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pyaudio
import wave
import tkinter as tk
from tkinter import *
from tkinter import filedialog as tkFileDialog
from tkinter import messagebox as tkMessageBox
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.backend_bases import Event
class myGUI:
def __init__(self,parent):
self.parent = parent
self.initUI()
def initUI(self):
self.inputFile = '/sounds/mysound.wav'
self.quitbutton = Button(self.parent, text="Quit", command=self.quit)
self.quitbutton.grid(row=4,column=4, sticky=W)
self.play_mode = False
self.playbutton = Button(self.parent, text="Play", command=self.playsound)
self.playbutton.grid(row=1, column=0, sticky=W, padx=(750, 6))
self.p = pyaudio.PyAudio()
# initialization for plotting
fig = plt.figure(figsize=(15,2), dpi=100)
self.a = fig.add_subplot(111)
self.canvas = FigureCanvasTkAgg(fig, self.parent)
self.canvaswidget = self.canvas.get_tk_widget()
self.canvaswidget.grid(row=2,column=0,sticky=W, padx=10)
toolbarFrame = Frame(master=self.parent)
toolbarFrame.grid(row=3,column=0)
self.toolbar = NavigationToolbar2TkAgg(self.canvas, toolbarFrame)
self.toolbar.update()
self.canvas._tkcanvas.grid(row=2,column=0,sticky=W, padx=10)
self.background = self.canvas.copy_from_bbox(self.a.bbox)
self.cursor = self.a.axvline(color="y", animated=True)
self.cursor.set_xdata(0)
cid1 = self.canvas.mpl_connect('playback_move_event', self.playbackMove)
self.playbackmoveevent = Event('playback_move_event',self)
self.plot()
def plot(self):
self.wf = wave.open(self.inputFile,'rb')
self.x = np.fromstring(self.wf.readframes(self.wf.getnframes()), dtype=np.int16)
self.wf.rewind()
self.a.clear()
self.a.plot(self.x)
self.cursor.set_xdata(0)
self.canvas.draw()
self.background = self.canvas.copy_from_bbox(self.a.bbox)
self.canvaswidget.focus_set()
def quit(self):
try:
self.stream.stop_stream()
self.stream.close()
self.wf.close()
self.p.terminate()
except:
print("no stream to close")
finally:
self.parent.destroy()
def playbackMove(self,event):
# move cursor by audio chunk size
self.cursor.set_xdata(self.cursor.get_xdata()+1024)
self.updateCursor()
def updateCursor(self):
self.canvas.restore_region(self.background)
self.a.draw_artist(self.cursor)
self.canvas.blit(self.a.bbox)
def initStream(self):
def _callbackstream(in_data, frame_count, time_info, status):
data = self.wf.readframes(frame_count)
self.canvas.callbacks.process('playback_move_event',self.playbackmoveevent)
return (data, pyaudio.paContinue)
self.stream = self.p.open(format=self.p.get_format_from_width(self.wf.getsampwidth()),
channels=self.wf.getnchannels(),
rate=self.wf.getframerate(),
output=True,
stream_callback=_callbackstream)
def playsound(self): # play/stop button
if self.play_mode == True:
self.playbutton.config(text="Play")
self.stream.stop_stream()
self.stream.close() # tried without closing too
print("stopping stream")
self.play_mode = False
else:
self.initStream()
self.play_mode = True
self.playbutton.config(text="Stop")
print("starting stream")
self.stream.start_stream()
root = Tk()
gui = myGUI(root)
root.mainloop()
Спасибо за ваше время и помощь!