python + Pyglet ---播放视频

 

记得安装pyglet 包,AVbin(http://avbin.github.io/AVbin/Download.html)

参考链接:

Pyglet教程

http://www.hawstein.com/posts/pyglet-tutorial.html

代码示例1:

import pyglet
from pyglet.media import *
window=pyglet.window.Window()
player=Player()
source=load('test.mp4')
player.queue(source)
player.play()
print(player.get_texture())
@window.event
def on_draw():
    window.clear()
    player.get_texture().blit(20,100)
    
pyglet.app.run()

代码示例2:

#coding=utf-8
# ----------------------------------------------------------------------------
# pyglet
# Copyright (c) 2006-2008 Alex Holkner
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
#  * Neither the name of pyglet nor the names of its
#    contributors may be used to endorse or promote products
#    derived from this software without specific prior written
#    permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# ----------------------------------------------------------------------------
 
'''Audio and video player with simple GUI controls.
'''
 
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
 
import sys
 
from pyglet.gl import *
import pyglet
from pyglet.window import key
 
def draw_rect(x, y, width, height):
    glBegin(GL_LINE_LOOP)
    glVertex2f(x, y)
    glVertex2f(x + width, y)
    glVertex2f(x + width, y + height)
    glVertex2f(x, y + height)
    glEnd()
 
class Control(pyglet.event.EventDispatcher):
    x = y = 0
    width = height = 10
 
    def __init__(self, parent):
        super(Control, self).__init__()
        self.parent = parent
 
    def hit_test(self, x, y):#点中控件
        return (self.x < x < self.x + self.width and 
                self.y < y < self.y + self.height)
 
    def capture_events(self):
        self.parent.push_handlers(self)
 
    def release_events(self):
        self.parent.remove_handlers(self)
 
class Button(Control):
    charged = False
 
    def draw(self):
        if self.charged:
            glColor3f(0, 1, 0)
        draw_rect(self.x, self.y, self.width, self.height)
        glColor3f(1, 1, 1)
        self.draw_label()
 
    def on_mouse_press(self, x, y, button, modifiers):
        self.capture_events()
        self.charged = True
 
    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        self.charged = self.hit_test(x, y)
 
    def on_mouse_release(self, x, y, button, modifiers):
        self.release_events()
        if self.hit_test(x, y):
            self.dispatch_event('on_press')
        self.charged = False
 
Button.register_event_type('on_press')#注册事件
     
class TextButton(Button):
    def __init__(self, *args, **kwargs):
        super(TextButton, self).__init__(*args, **kwargs)
        self._text = pyglet.text.Label('', anchor_x='center', anchor_y='center')
 
    def draw_label(self):
        self._text.x = self.x + self.width / 2
        self._text.y = self.y + self.height / 2
        self._text.draw()
 
    def set_text(self, text):
        self._text.text = text
 
    text = property(lambda self: self._text.text,
                    set_text)
 
class Slider(Control):
    THUMB_WIDTH = 6
    THUMB_HEIGHT = 10
    GROOVE_HEIGHT = 2
 
    def draw(self):
        center_y = self.y + self.height / 2
        draw_rect(self.x, center_y - self.GROOVE_HEIGHT / 2,
                  self.width, self.GROOVE_HEIGHT)
        pos = self.x + self.value * self.width / (self.max - self.min)
        draw_rect(pos - self.THUMB_WIDTH / 2, center_y - self.THUMB_HEIGHT / 2,
                  self.THUMB_WIDTH, self.THUMB_HEIGHT)
 
    def coordinate_to_value(self, x):#改变进度
        return float(x - self.x) / self.width * (self.max - self.min) + self.min
 
    def on_mouse_press(self, x, y, button, modifiers):
        value = self.coordinate_to_value(x)
        self.capture_events()
        self.dispatch_event('on_begin_scroll')
        self.dispatch_event('on_change', value)
 
    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        value = min(max(self.coordinate_to_value(x), self.min), self.max)
        self.dispatch_event('on_change', value)
     
    def on_mouse_release(self, x, y, button, modifiers):
        self.release_events()
        self.dispatch_event('on_end_scroll')
 
Slider.register_event_type('on_begin_scroll')
Slider.register_event_type('on_end_scroll')
Slider.register_event_type('on_change')
 
class PlayerWindow(pyglet.window.Window):
    GUI_WIDTH = 400
    GUI_HEIGHT = 40
    GUI_PADDING = 4#按钮间隔
    GUI_BUTTON_HEIGHT = 16
 
    def __init__(self, player):
        super(PlayerWindow, self).__init__(caption='Media Player',
                                           visible=False,
                                           resizable=True)
        self.player = player
        self.player.push_handlers(self)
        #self.player.eos_action = self.player.EOS_PAUSE
 
        self.slider = Slider(self)
        self.slider.x = self.GUI_PADDING#类变量
        self.slider.y = self.GUI_PADDING * 2 + self.GUI_BUTTON_HEIGHT
        self.slider.on_begin_scroll = lambda: player.pause()
        self.slider.on_end_scroll = lambda: player.play()
        self.slider.on_change = lambda value: player.seek(value)
 
        self.play_pause_button = TextButton(self)
        self.play_pause_button.x = self.GUI_PADDING
        self.play_pause_button.y = self.GUI_PADDING
        self.play_pause_button.height = self.GUI_BUTTON_HEIGHT
        self.play_pause_button.width = 45
        self.play_pause_button.on_press = self.on_play_pause
 
        win = self#自有妙用
        self.window_button = TextButton(self)
        self.window_button.x = self.play_pause_button.x + \
                               self.play_pause_button.width + self.GUI_PADDING
        self.window_button.y = self.GUI_PADDING
        self.window_button.height = self.GUI_BUTTON_HEIGHT
        self.window_button.width = 90
        self.window_button.text = 'Windowed'
        self.window_button.on_press = lambda: win.set_fullscreen(False)#注意不能写self
 
        self.controls = [
            self.slider,
            self.play_pause_button,
            self.window_button,
        ]
 
        x = self.window_button.x + self.window_button.width + self.GUI_PADDING
        i = 0
        for screen in self.display.get_screens():
            screen_button = TextButton(self)
            screen_button.x = x
            screen_button.y = self.GUI_PADDING
            screen_button.height = self.GUI_BUTTON_HEIGHT
            screen_button.width = 80
            screen_button.text = 'Screen %d' % (i + 1)
            screen_button.on_press = \
                (lambda s: lambda: win.set_fullscreen(True, screen=s))(screen)
            self.controls.append(screen_button)
            i += 1
            x += screen_button.width + self.GUI_PADDING
 
 
    def on_eos(self):
        self.gui_update_state()
 
    def gui_update_source(self):
        if self.player.source:
            source = self.player.source
            self.slider.min = 0.
            self.slider.max = source.duration
        self.gui_update_state()
 
    def gui_update_state(self):
        if self.player.playing:
            self.play_pause_button.text = 'Pause'
        else:
            self.play_pause_button.text = 'Play'
 
    def get_video_size(self):
        if not self.player.source or not self.player.source.video_format:
            return 0, 0
        video_format = self.player.source.video_format
        width = video_format.width
        height = video_format.height
        if video_format.sample_aspect > 1:
            width *= video_format.sample_aspect
        elif video_format.sample_aspect < 1:
            height /= video_format.sample_aspect
        return width, height
 
    def set_default_video_size(self):
        '''Make the window size just big enough to show the current
        video and the GUI.'''
        width = self.GUI_WIDTH
        height = self.GUI_HEIGHT
        video_width, video_height = self.get_video_size()
        width = max(width, video_width)
        height += video_height
        self.set_size(int(width), int(height))
 
    def on_resize(self, width, height):
        '''Position and size video image.'''
        super(PlayerWindow, self).on_resize(width, height)
 
        self.slider.width = width - self.GUI_PADDING * 2
 
        height -= self.GUI_HEIGHT
        if height <= 0:
            return
 
        video_width, video_height = self.get_video_size()
        if video_width == 0 or video_height == 0:
            return
 
        display_aspect = width / float(height)
        video_aspect = video_width / float(video_height)
        if video_aspect > display_aspect:
            self.video_width = width
            self.video_height = width / video_aspect
        else:
            self.video_height = height
            self.video_width = height * video_aspect
        self.video_x = (width - self.video_width) / 2
        self.video_y = (height - self.video_height) / 2 + self.GUI_HEIGHT
 
    def on_mouse_press(self, x, y, button, modifiers):
        for control in self.controls:
            if control.hit_test(x, y):
                control.on_mouse_press(x, y, button, modifiers)
 
    def on_key_press(self, symbol, modifiers):
        if symbol == key.SPACE:
            self.on_play_pause()
        elif symbol == key.ESCAPE:
            self.dispatch_event('on_close')
 
    def on_close(self):
        self.player.pause()
        self.close()
 
    def on_play_pause(self):
        if self.player.playing:
            self.player.pause()
        else:
            if self.player.time >= self.player.source.duration:#如果放完了
                self.player.seek(0)
            self.player.play()
        self.gui_update_state()
 
    def on_draw(self):
        self.clear()
         
        # Video
        if self.player.source and self.player.source.video_format:
            self.player.get_texture().blit(self.video_x,
                                           self.video_y,
                                           width=self.video_width,
                                           height=self.video_height)
 
        # GUI
        self.slider.value = self.player.time
        for control in self.controls:
            control.draw()
 
if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: media_player.py <filename> [<filename> ...]")
        sys.exit(1)
         
    for filename in sys.argv[1:]:
        player = pyglet.media.Player()
        window = PlayerWindow(player)
 
        source = pyglet.media.load(filename)
        player.queue(source)
 
        window.gui_update_source()
        window.set_default_video_size()
        window.set_size(400,400)
        window.set_visible(True)
 
        window.gui_update_state()
        player.play()
 
    pyglet.app.run()

  

 

How to use pause method in pyglet package

#This should play the video then pause after 12 seconds of
# play. Stay paused for 4 seconds and play again.
#Note AVbin7 needs to be installed to play mp4s

import pyglet
from time import sleep
vidPath="test.mp4"
window = pyglet.window.Window()
player = pyglet.media.Player()
source = pyglet.media.StreamingSource()
MediaLoad = pyglet.media.load(vidPath)
pt = 0
player.queue(MediaLoad)
player.play()

@window.event
def on_draw():
    global pt
    window.clear()
    if player.source and player.source.video_format:
        player.get_texture().blit(0,0)
        if player.time >= 12 and pt == 0:
            print("pausing")
            player.pause()
            sleep(4)
            player.play()
            pt = 1

pyglet.app.run()

  

uses SPACE to pause/resume video playing:

import pyglet
from pyglet.window import key

source = pyglet.media.load("test.mp4")
fmt = source.video_format

player = pyglet.media.Player()
player.queue(source)
player.play()

window = pyglet.window.Window(width=fmt.width, height=fmt.height)

@window.event
def on_draw():
    player.get_texture().blit(0, 0)

@window.event
def on_key_press(symbol, modifiers):
    if symbol == key.SPACE:
        if player.playing:
            player.pause()
        else:
            player.play()
        
pyglet.app.run()

  

 

posted on 2016-12-07 10:03  清明-心若淡定  阅读(2502)  评论(1编辑  收藏  举报