pyglet -- 视频播放器 (简单实现,效果不是太好,切换资源会卡死)(三)

实现一个简单的视频播放器,效果不是很好。这里不多说,直接贴代码了。

  1 #-*- coding:gbk -*-
  2 import pyglet
  3 import os
  4 from pyglet.gl import *
  5 
  6 def draw_rec(x,y,width,height):
  7     """
  8     矩形
  9     """
 10     glLoadIdentity()
 11     glPushMatrix()
 12     glBegin(GL_LINE_LOOP)
 13     glVertex2f(x,y)
 14     glVertex2f(x+width,y)
 15     glVertex2f(x+width,y+height)
 16     glVertex2f(x,y+height)
 17     glEnd()
 18     glPopMatrix()
 19 
 20 
 21 class Button(pyglet.event.EventDispatcher):
 22 
 23     def __init__(self):
 24         super(Button,self).__init__()
 25         self.x=y=0  #按钮的位置以及大小
 26         self.width=height=10
 27         self.hit=False  #按钮是否被鼠标点击
 28         self._text=pyglet.text.Label('',anchor_x='center',anchor_y='center')   #初始化是必要的,必须写在__init__中,不然给他赋文本值会当成全局量,最终显示的按钮的文本是最后一个赋值(即,作为私有量)
 29     
 30     def draw(self):
 31         """
 32         画按钮
 33         """
 34         if self.hit:
 35             glColor3f(0.0,1.0,0.0)
 36         draw_rec(self.x,self.y,self.width,self.height)
 37         glColor3f(1.0,1.0,1.0)
 38         self.draw_label()
 39     def set_text(self,button_text):
 40         """
 41         改变按钮的文本
 42         """
 43         self._text.text=button_text
 44     button_text=property(lambda self: self._text.text,set_text)
 45     def set_size(self,x,y,width,height):
 46         """
 47         改变按钮的位置和大小
 48         """
 49         self.x=x
 50         self.y=y
 51         self.width=width
 52         self.height=height
 53 
 54     def on_mouse_press(self,x,y,button,modifiers):
 55         self.dispatch_event('on_press')   #调度事件
 56         self.hit=True  #鼠标点击,颜色变化
 57     def on_mouse_drag(self,x,y,dx,dy,button,modifiers):
 58         """
 59         拖动
 60         """
 61         self.dispatch_event('on_value_change')
 62     def on_mouse_release(self,x,y,button,modifiers):
 63         self.dispatch_event('on_release')
 64         self.hit=False  #释放鼠标,恢复颜色
 65     def draw_label(self):
 66         """
 67         添加标签
 68         """
 69         self._text.x=self.x+self.width/2
 70         self._text.y=self.y+self.height/2
 71         self._text.draw()
 72     def hit_test(self,x,y):
 73         return (self.x<x<self.x+self.width and self.y < y < self.y+self.height)
 74         
 75 
 76         
 77 #注册事件类型
 78 Button.register_event_type('on_press')
 79 Button.register_event_type('on_value_change')
 80 Button.register_event_type('on_release')
 81 
 82 
 83 class Player(pyglet.media.Player):
 84     x=y=0
 85     width=height=10
 86 
 87     def load_source(self,path):
 88         """
 89         载入视频资源
 90         """
 91         resource_path=[path]
 92         pyglet.resource.path=resource_path
 93         pyglet.resource.reindex()
 94         if path:
 95             for root,dirname,files in os.walk(path):
 96                 for f in files:
 97                     source=pyglet.resource.media(f)
 98                     self.queue(source)
 99     def set_locate(self,x,y):
100         """
101         设置播放器的位置
102         """
103         self.x=x
104         self.y=y
105     def get_and_set_video_size(self):
106         """
107         获取视频的大小并设置播放器的长宽
108         """
109         if self.source and self.source.video_format:
110             self.width=self.source.video_format.width
111             self.height=self.source.video_format.height
112         if self.source.video_format.sample_aspect>1:
113             self.width*=self.source.video_format.sample_aspect
114         else:
115             self.height/=self.source.video_format.sample_aspect
116     
117         
118         
119 class MyPlayer(pyglet.window.Window):
120     def __init__(self,caption):
121         super(MyPlayer,self).__init__(caption=caption,resizable=True)
122         self.padding=10  #默认的间距以及长宽
123         self.width=50
124         self.height=30
125 
126         #下面列出要显示的列表
127         self.drawable=[]  #显示列表
128 
129         #播放器
130         self.player=Player()
131         self.player.load_source('E:music')
132         self.player.set_locate(0,self.padding*2+30)  #播放器显示位置
133         self.player.get_and_set_video_size()  #得到视频的大小并设置
134         self.player.EOS_NEXT='next'  #按顺序进行播放
135         self.player.push_handlers(self)
136 
137         #播放/暂停控制按钮
138         self.play_pause_control=Button()
139         self.play_pause_control.width=50
140         self.play_pause_control.height=30
141         self.play_pause_control.set_size(self.padding,self.padding,self.play_pause_control.width,self.play_pause_control.height)  #位置以及大小
142         self.play_pause_control.button_text='play'  #文本设置
143         self.play_pause_control.on_press=lambda:self.on_play_pause()
144         self.drawable.append(self.play_pause_control)  #将这个按钮加入到显示列表中
145 
146         #全屏控制按钮
147         self.isscreenfull=Button()
148         self.isscreenfull.width=50
149         self.isscreenfull.height=30
150         self.isscreenfull.set_size(self.padding*2+self.play_pause_control.width,self.padding,self.isscreenfull.width,self.isscreenfull.height)
151         self.isscreenfull.button_text='全屏'
152         self.isscreenfull.on_press=lambda: self.set_fullscreen(True)
153         self.drawable.append(self.isscreenfull)
154 
155     def on_draw(self):
156         self.clear()
157         #显示播放器
158         if self.player.source and self.player.source.video_format: 
159             self.player.get_texture().blit((self.width-self.player.width)/2,self.player.y,width=self.player.width,height=self.player.height) #注意这里width=,height=不能省略,否则画面不会出现的
160             
161 
162         #画列表中所有的控制按钮
163         if self.drawable:
164             for draw_c in self.drawable:
165                 draw_c.draw()
166     def on_mouse_press(self,x,y,button,modifiers):
167         for dc in self.drawable:
168             if dc.hit_test(x,y):
169                 dc.on_mouse_press(x,y,button,modifiers)
170     def on_play_pause(self):
171         if self.player.playing:
172             self.player.pause()
173             self.play_pause_control.set_text('pause')    
174         else:
175             if self.player.time > self.player.source.duration:
176                 self.player.seek(0)
177             self.player.play()
178             self.play_pause_control.set_text('play')
179     def on_mouse_release(self,x,y,button,modifiers):
180         for dc in self.drawable:
181             if dc.hit_test(x,y):
182                 dc.on_mouse_release(x,y,button,modifiers)
183     def on_resize(self,width,height):
184         super(MyPlayer,self).on_resize(width,height)
185         if self.player.source:
186             video_width,video_height=self.player.width,self.player.height
187             
188         display_aspect=width/float(height)
189         video_aspect=video_width/float(video_height)
190 
191         if video_aspect>display_aspect:
192             self.player.width=width
193             self.player.height=width/video_aspect
194         else:
195             self.player.height=height
196             self.player.width=height * video_aspect
197         self.player.x=(width-self.player.width)/2
198         self.player.y=(height-self.player.height)/2
199 
200 if __name__ == "__main__":
201     wn=MyPlayer('my player')
202     wn.set_size(int(wn.player.width),int(wn.player.height)) #将窗口的大小设置的和视频一样大小
203     wn.set_visible(True)  #可见
204     wn.player.play()
205 pyglet.app.run()
206