Python实现的视频播放器功能完整示例
作者:jacklulu2010 发布时间:2023-05-04 06:33:56
标签: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程序设计有所帮助。
0
投稿
猜你喜欢
- var obj=document.getElementById("id");得到的是dom对象,对该对象进行操作的时候使
- 上次还是CSDN里的朋友回答的,我复制了下来。原文如下 =========================== 利用统计文章字数,然后达到一
- PyQt5布局控件QVBoxLayout简介采用QVBoxLayout类,按照从上到下的顺序添加控件本节内容较少,演示两个实例,便于明白QV
- 如何导入数据数据可能有各种格式,虽然常见的是HDFS,但是因为在Python爬虫中数据库用的比较多的是MongoDB,所以这里会重点说说如何
- 本文实例讲述了Python实现的企业粉丝抽奖功能。分享给大家供大家参考,具体如下:一 代码def scode9(schoice): &nbs
- 在Web开发中,JavaScript的一个很重要的作用就是对DOM进行操作,可你知道么?对DOM的操作是非常昂贵的,因为这会导致浏览器执行回
- 删除备份和还原历史记录表中所有早于 oldest_date 的备份集的项目。由于执行备份或还原操作时会在备份和还原历史记录表中添加行,sp_
- 利用图标工具(有很多)制作图标文件(favicon.ico)上传到网站所在的服务器的根目录下,这个文件必须是16*16大小的图标文件。当然,
- JavaScript图片水平翻转后垂直翻反转的特效一:<!--把下列代码加到body区域内--><SCRIPT langu
- 分析我们都知道一个可迭代对象可以通过iter()可以返回一个迭代器。如果想要一个对象称为可迭代对象,即可以使用for,那么必须实现__ite
- 在这个abc.php文件中写入如下代码。<?php phpinfo(); ?>你将会看到一个网页,网页内容通常,如下图所示:用中
- 如下所示:# u [32,30,200]# u_logits [400,32,30]q_j_400 = [] for j in range(
- 题目:反转一个单链表。示例:输入: 1->2->3->4->5->NULL输出: 5->4->3-
- 在团队意见PK中,运用对方的知识背景说服对方,这就是技术性击倒。这样通常能把对方驳得哑口无言,我经常被这样击倒,甚至觉得怎么那么多牛逼的设计
- JavaScript中的XMLHttpRequest和XML DOM首先,我们需要建立一些规则。特殊的XMLHttpRequest对象和一般
- 在有些使用 javascript 来渲染数据的时候,为了能动态获取不同的数据,并且保持 javascript&
- 让我们描绘一下本文的情节:假设您要在本地机器上运行一个进程,而部分程序逻辑却在另一处。让我们特别假设这个程序逻辑会不时更新, 而您运行进程时
- PL/SQL是ORACLE对标准数据库语言的扩展,ORACLE公司已经将PL/SQL整合到ORACLE 服务器和其他工具中了,近几年中更多的
- 实例如下所示:import numpy as npW_val, b_val = sess.run([weights_tensor, bias
- 不知上过ChinaRen校友录的朋友们有没有注意,ChinaRen在改版后很多方面都进行了较大的改动。例如留言与回复方面已经不再像以前那样,