pymedia & wxpython 制作播放器播放时主窗口卡住



 #!/usr/bin/env python
# -*- coding: utf-8 -*-
import wx
import mp3

class myplayerframe(wx.Frame):

    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title.decode('utf-8'), pos= (500, 150),size= (300, 500), style= wx.DEFAULT_FRAME_STYLE^(wx.MAXIMIZE_BOX|wx.MINIMIZE_BOX))

        self.bitmap= {'play_before' : wx.Bitmap('play_before.png', wx.BITMAP_TYPE_PNG),\
                    'play_after' : wx.Bitmap('play_after.png', wx.BITMAP_TYPE_PNG),\
                    'pause_before' : wx.Bitmap('pause_before.png', wx.BITMAP_TYPE_PNG), \
                    'pause_after' : wx.Bitmap('pause_after.png', wx.BITMAP_TYPE_PNG),\
                    'stop_before' : wx.Bitmap('stop_before.png', wx.BITMAP_TYPE_PNG),\
                    'stop_after' : wx.Bitmap('stop_after.png', wx.BITMAP_TYPE_PNG)}

        self.panel= wx.Panel(self)
        self.panel.SetBackgroundColour('Pink')
        self.bt_play= wx.BitmapButton(self.panel, -1, self.bitmap['play_before'], pos= (120, 10), size= (50, 50))
        self.bt_pause= wx.BitmapButton(self.panel, -1, self.bitmap['pause_before'], pos= (60, 10), size= (50, 50))
        self.bt_stop= wx.BitmapButton(self.panel, -1, self.bitmap['stop_before'], pos= (180, 10), size= (50, 50))

        self.open_dlg= wx.FileDialog(self, message= "Open", style= wx.OPEN)

        self.bt_play.Bind(wx.EVT_LEFT_DOWN, self.play_after)
        self.bt_pause.Bind(wx.EVT_LEFT_DOWN, self.pause_after)
        self.bt_stop.Bind(wx.EVT_LEFT_DOWN, self.stop_after)


    def openfile(self, event):
        self.open_dlg.ShowModal()

    def play_after(self, event):
        file= 'i cry.mp3'
        mp3.playms(file)        
        self.bt_play= wx.BitmapButton(self.panel, -1, self.bitmap['play_after'], pos= (120, 10), size= (50, 50))
        event.Skip()        

    def pause_after(self, event):
        self.bt_pause= wx.BitmapButton(self.panel, -1, self.bitmap['pause_after'], pos= (60, 10), size= (50, 50))
        event.Skip()

    def stop_after(self, event):
        self.bt_stop= wx.BitmapButton(self.panel, -1, self.bitmap['stop_after'], pos= (180,10), size= (50, 50))
        event.Skip()

class myplayer(wx.App):
    def OnInit(self):
        myplayerframe(parent= None, id= -1, title= 'SPlayer').Show()
        return True

if __name__ == '__main__':
    myplayer().MainLoop()

接下来是mp3.py


 #-*-coding: utf-8-*-
import pymedia
import pymedia.muxer as muxer
import pymedia.audio.acodec as acodec
import pymedia.audio.sound as sound
import time

def check_types(f):
    sound_type = f.split('.')[-1]
    print sound_type
    return sound_type

def playms(file):
    #1.二进制方法读取前 10000 个字节,保证能读到第一帧音频数据
    ms = open(file, 'rb')
    data = ms.read(100000)
    #2.创建合成器对象,解析出最初的几帧音频数据
    dm = muxer.Demuxer(check_types(file))
    frames = dm.parse(data)
    #3.根据解析出来的 Mp3 编码信息,创建解码器对象
    dec = acodec.Decoder(dm.streams[0])
    #像下面这样也行
    #params = {'id': acodec.getCodecID('mp3'), 'bitrate': 128000, 'sample_rate': 44100, 'ext': 'mp3', 'channels': 2}
    #dec= acodec.Decoder(params)

    #4.解码第一帧音频数据
    frame = frames[0]
    #音频数据在 frame 数组的第二个元素中
    r = dec.decode(frame[1])
    #注意:这一步可以直接解码 r=dec.decode( data),而不用读出第一帧音频数据
    #但是开始会有一下噪音,如果是网络流纯音频数据,不包含标签信息,则不会出现杂音

    #5.创建音频输出对象
    snd = sound.Output(r.sample_rate, r.channels, sound.AFMT_S16_LE)
    #6.播放
    if r:
        snd.play(r.data)
    #7.继续读取、解码、播放
        while True:
            data = ms.read(512)
            if len(data) > 0:
                r = dec.decode(data)
                if r:
                    snd.play(r.data)
            else:
                break
    #8.延时,直到播放完毕
    while snd.isPlaying():
        time.sleep(.5)

但是播放时主窗口卡住,只有播放完毕之后才可以再对窗体操作
请问各位这个怎么解决

python wxpython pymedia

永远的毛玉 11 years, 2 months ago

多线程?

带风扇去上课 answered 11 years, 2 months ago

Your Answer