Python实现的视频播放器功能完整示例

本文实例讲述了Python实现的视频播放器功能。分享给大家供大家参考,具体如下:

# -*- coding:utf-8 -*-

#! python3

# ----------------------------------------------------------------------------

# 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()

注:这里用到的pyglet库,可点击此处下载https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyglet

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python文件与目录操作技巧汇总》、《Python文本文件操作技巧汇总》、《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。

以上是 Python实现的视频播放器功能完整示例 的全部内容, 来源链接: utcz.com/z/351028.html

回到顶部