Воспроизведение музыки с Pyglet и Tkinter в Python

Я хотел создать простой gui с кнопкой воспроизведения и остановки, чтобы воспроизвести mp3-файл в python. Я создал очень простой gui, используя Tkinter, который состоит из двух кнопок (остановка и воспроизведение).

Я создал функцию, которая выполняет следующие действия:

def playsound () : sound = pyglet.media.load('music.mp3') sound.play() pyglet.app.run() 

Я добавил эту функцию как команду для воспроизведения кнопки. Я также сделал другую функцию, чтобы остановить музыку:

 def stopsound (): pyglet.app.exit 

Я добавил эту функцию в качестве команды ко второй кнопке. Но проблема в том, что когда я нажимаю игру, питон и зависание gui. Я могу попытаться закрыть окно, но он не закрывается, и кнопка остановки не реагирует. Я понимаю, что это происходит потому, что pyglet.app.run () выполняется до тех пор, пока песня не закончится, но как именно я могу это предотвратить? Я хочу, чтобы gui остановил музыку, когда я нажимаю кнопку. Любые идеи о том, где я могу найти решение?

Вы смешиваете две библиотеки пользовательского интерфейса вместе – это не так уж и плохо, но есть некоторые проблемы. Примечательно, что для того, чтобы обрабатывать свои события, им нужна основная петля. TKinter использует его для связи с настольными и пользовательскими событиями, и в этом случае пиглет использует его для воспроизведения вашей музыки.

Каждая из этих циклов предотвращает нормальный поток программы «сверху вниз», как мы привыкли, когда мы изучаем программирование без GUI, и программа должна в основном выполнять обратные вызовы из основных циклов. В этом случае, в середине обратного вызова Tkinter, вы помещаете mainloop pyglet (вызов pyglet.app.run ) в движение, и элемент управления никогда не возвращается в библиотеку Tkinter.

Иногда циклы разных библиотек могут сосуществовать в одном и том же процессе, без конфликтов, но, конечно, вы будете либо запускать один из них, либо другой. Если это так, может быть возможно запустить mainloop каждой библиотеки в другом потоке Python.

Если они не могут существовать вместе, вам придется иметь дело с каждой библиотекой в ​​другом процессе.

Таким образом, один из способов заставить музыкальный плеер начать в другом потоке:

 from threading import Thread def real_playsound () : sound = pyglet.media.load('music.mp3') sound.play() pyglet.app.run() def playsound(): global player_thread player_thread = Thread(target=real_playsound) player_thread.start() 

Если Tkinter и pyglet могут сосуществовать, этого должно быть достаточно, чтобы начать вашу музыку. Однако, чтобы иметь возможность управлять им, вам нужно будет реализовать еще пару вещей. Мое предложение состоит в том, чтобы иметь обратный вызов в потоке пиглета, который вызывается pyglet каждую секунду или около того – этот обратный вызов проверяет состояние некоторых глобальных переменных, и на их основе выбирает остановить музыку, изменить воспроизводимый файл и так далее на.

В документации pyglet реализована реализация медиаплеера:

http://www.pyglet.org/doc/programming_guide/playing_sounds_and_music.html

Сценарий, на который вы должны обратить внимание, – media_player.py

Надеюсь, это поможет вам начать

Я бы сделал что-то вроде:

 import pyglet from pyglet.gl import * class main (pyglet.window.Window): def __init__ (self): super(main, self).__init__(800, 600, fullscreen = False) self.button_texture = pyglet.image.load('button.png') self.button = pyglet.sprite.Sprite(self.button_texture) self.sound = pyglet.media.load('music.mp3') self.sound.play() self.alive = 1 def on_draw(self): self.render() def on_close(self): self.alive = 0 def on_mouse_press(self, x, y, button, modifiers): if x > self.button.x and x < (self.button.x + self.button_texture.width): if y > self.button.y and y < (self.button.y + self.button_texture.height): self.alive = 0 def on_key_press(self, symbol, modifiers): if symbol == 65307: # [ESC] self.alive = 0 def render(self): self.clear() self.button.draw() self.flip() def run(self): while self.alive == 1: self.render() # -----------> This is key <---------- # This is what replaces pyglet.app.run() # but is required for the GUI to not freeze # event = self.dispatch_events() x = main() x.run() 

Это решение является самым простым:

 import pyglet foo=pyglet.media.load("/data/Me/Music/Goo Goo Dolls/[1998] Dizzy Up The Girl/11 - Iris.mp3") foo.play() def exiter(dt): pyglet.app.exit() print "Song length is: %f" % foo.duration # foo.duration is the song length pyglet.clock.schedule_once(exiter, foo.duration) pyglet.app.run() 

источник: http://ubuntuforums.org/showthread.php?t=1651906

Interesting Posts