Thread em Python

Comecei a fazer uma GUI usando o wxPython para tocar um arquivo de música com o código de ontem. Implementei o botão de seleção do arquivo, que até filtra os arquivos a serem mostrados de acordo com as extensões especificadas. No meu caso, *.mp3 e *.ogg.

Só que selecionado o arquivo, a interface travava. Pesquisando no Google, achei como abrir uma thread usando Python. Basta usar o módulo (surpresa) thread ou o threading. A diferença é que o módulo thread é mais baixo-nível (como em low-level, e não que ele te xingue :)), enquanto o módulo threading abstrai o uso e oferece mais opções.

Para usar o threading você deve herdá-lo na sua classe. Como nem sequer era uma classe meu código de ontem, mudei um pouco as coisas. A declaração ficou assim:

class playFile(threading.Thread):

No mais, três métodos novos: __init__() que também começa o threading, run() para tocar o som com o Pymedia, e stop(), para parar o aúdio. No meu caso, com wxPython, chamo o stop() quando um novo arquivo é selecionado.

A classe nova, finalizada:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class playFile(threading.Thread):
    def __init__(self, file_name):
        threading.Thread.__init__ (self)
 
        self.keepGoing = True
 
        file_extension = file_name.split('.' )[ -1 ].lower()
        parms = {'id': acodec.getCodecID(file_extension), 'ext': file_extension}
        self.decoder = acodec.Decoder(parms)
        self.f = open(file_name, 'rb')
        self.s = self.f.read(8192)
        self.r = self.decoder.decode(self.s)
 
        self.snd = sound.Output(self.r.sample_rate, self.r.channels, sound.AFMT_S16_LE)
 
    def run(self):       
        while len(self.s) > 0 and self.keepGoing:
            if self.r and self.keepGoing:
                self.snd.play(self.r.data)            
            self.s = self.f.read(512)
            self.r = self.decoder.decode(self.s)
 
        while self.snd.isPlaying():
            time.sleep(.05)
 
    def stop(self):
        self.snd.stop()
        self.keepGoing = False

Para começar a tocar um arquivo de música em uma thread nova:

play_file = playFile(“arquivo.mp3”)
play_file.start()

O método start() vêm do threading.Thread, e chama o run() automaticamente.

Mas vamos testar se funciona… Tocar um arquivo .mp3, esperar 5 segundos, e tocar de novo, sem parar o som já tocando, provavelmente travando o PC no meio do caminho 🙂

1
2
3
4
for i in range(5):
    play_file = playFile("arquivo.mp3")    
    play_file.start()
    time.sleep(5)

Post a Comment

Your email is never shared.