问题
I was looking for a solution to play mp3 files in python and many stackoverflow answers (to other questions) seemed to recommend pyglet. I am writing a program that takes a piece of text, breaks it into individual words and then downloads mp3s of those words (if they aren't already downloaded) using gTTs and plays them.
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()
However I find that after playing the files pyglet won't let my program progress. How can I exit the pyglet app after playback has finished, so that my code can progress?
Alternatively is there some other way that I can play mp3 files in python?
回答1:
This is souly because app.run()
is a never-ending loop in order to keep the GL context alive. There's only one way around this and that is to create your own class that inherits the Pyglet properties.
I'll give you a sample code and if you have any questions feel free to ask away.
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()
Now this is just the most basic example of how to load audio sources and play them. You press Enter and that triggers beep.mp3
.
Normally, you'd also want to hook a function to self.player.eos() that does something when you run out of sources.
Also note that it only calls play()
once if it's not already playing. These are attributes you want to honor.
Ah and Escape exits the application.
来源:https://stackoverflow.com/questions/36737455/pyglet-wont-quit-after-playing-mp3