Pyglet не останавливается после воспроизведения mp3

Я искал решение для воспроизведения mp3-файлов в python, и многие ответы на stackoverflow (на другие вопросы), похоже, рекомендовали pyglet. Я пишу программу, которая берет фрагмент текста, разбивает его на отдельные слова, а затем загружает mp3-файлы этих слов (если они еще не загружены) с помощью gTT и воспроизводит их.

from pyglet import media, app, clock
from gtts import gTTS
import os
import time
from num2words import num2words

cwd = os.getcwd()
beep = media.load('beep.mp3', streaming = False)

def get_mp3(text):
    player = media.Player()
    lowertext = text.lower()    
    words = lowertext.split()    
    player.queue(beep)
    for word in words:
        save_path = cwd + '\\tts_downloads\\{}.mp3'.format(word)
        if os.path.isfile(save_path) == False:
            tts = gTTS(word, 'en-us')
            tts.save(save_path)
        mp3 = media.load(save_path)
        player.queue(mp3)
    player.queue(beep)
    player.play()
    app.run()

Однако я обнаружил, что после воспроизведения файлов pyglet не позволяет моей программе работать. Как я могу выйти из приложения pyglet после завершения воспроизведения, чтобы мой код мог продолжить работу?

В качестве альтернативы есть ли другой способ воспроизведения mp3-файлов в python?


person Jo-dan    schedule 20.04.2016    source источник


Ответы (1)


Это очень важно, потому что app.run() — это бесконечный цикл для поддержания жизни контекста GL. Есть только один способ обойти это — создать собственный класс, наследующий свойства Pyglet.

Я дам вам пример кода, и если у вас есть какие-либо вопросы, не стесняйтесь спрашивать.

import pyglet
from pyglet.gl import *

# Optional audio outputs (Linux examples):
# pyglet.options['audio'] = ('alsa', 'openal', 'silent')
key = pyglet.window.key

class main(pyglet.window.Window):
    def __init__ (self):
        super(main, self).__init__(800, 800, fullscreen = False)
        self.x, self.y = 0, 0

        self.bg = pyglet.sprite.Sprite(pyglet.image.load('background.jpg'))
        self.sprites = {}
        self.player = pyglet.media.Player()
        self.alive = 1

    def on_draw(self):
        self.render()

    def on_close(self):
        self.alive = 0

    def on_key_press(self, symbol, modifiers):
        # Do something when a key is pressed?
        # Pause the audio for instance?
        # use `if symbol == key.SPACE: ...`

        # This is just an example of how you could load the audio.
        # You could also do a standard input() call and enter a string
        # on the command line.
        if symbol == key.ENTER:
            self.player.queue(media.load('beep.mp3', streaming = False))
            if nog self.player.playing:
                self.player.play()
        if symbol == key.ESC: # [ESC]
            self.alive = 0

    def render(self):
        self.clear()
        self.bg.draw()

        # self.sprites is a dictionary where you store sprites
        # to be rendered, if you have any.
        for sprite_name, sprite in self.sprites.items():
            sprite.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()
        self.player.delete() # Free resources. (Not really needed but as an example)

x = main()
x.run()

Это самый простой пример того, как загружать аудиоисточники и воспроизводить их. Вы нажимаете Enter, и это вызывает beep.mp3.

Обычно вы также хотите подключить функцию к self.player.eos(), который что-то делает, когда у вас заканчиваются исходники.

Также обратите внимание, что он вызывает play() только один раз, если он еще не воспроизводится. Это атрибуты, которые вы хотите уважать.

Ah и Escape закрывает приложение.

person Torxed    schedule 26.04.2016