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()
python + Pyglet ---播放视频的更多相关文章
- 用Python实现检测视频真伪?
译者注:本文以一段自打24小时耳光的视频为例子,介绍了如何利用均值哈希算法来检查重复视频帧.以下是译文. 有人在网上上传了一段视频,他打了自己24个小时的耳光.他真的这么做了吗?看都不用看,肯定没有! ...
- 利用PyQt GUI显示图片、实时播放视频
---作者吴疆,未经允许,严禁转载,违权必究--- ---欢迎指正,需要源码和文件可站内私信联系--- -----------点击此处链接至博客园原文----------- 功能说明:PyQt界面程序 ...
- Python爬取视频指南
摘自:https://www.jianshu.com/p/9ca86becd86d 前言 前两天尔羽说让我爬一下菜鸟窝的教程视频,这次就跟大家来说说Python爬取视频的经验 正文 https://w ...
- 嵌入式 vlc从接收到数据流到播放视频的过程分析(经典)
个人整理: Vlc流播放流程 vlc源码目录树: 目录名称 说明 bindings Java, CIL 和Python绑定 doc 帮助文档 (不是更新的) extras 另叙. include VL ...
- AVAssetReader+AVAssetReaderTrackOutput播放视频
该文章引用自:http://www.jianshu.com/p/3d5ccbde0de1 IOS 微信聊天发送小视频的秘密(AVAssetReader+AVAssetReaderTrackOutput ...
- Android实现播放视频
转载:http://www.bdqn.cn/news/201311/12100.shtml 使用VideoView播放视频 VideoView,用于播放一段视频媒体,它继承了SurfaceView,位 ...
- Android使用TextureView播放视频
1.引言 如果你想显示一段在线视频或者任意的数据流比如视频或者OpenGL 场景,你可以用android中的TextureView做到. 1).TextureView的兄弟SurfaceView 应用 ...
- WPF播放视频
在现在的项目中需要使用到播放视频的功能,本来打算使用VLC来做的.后来发现WPF 4.0之后新增了MediaElement类,可以实现视频播放. <Grid> <Grid.RowDe ...
- Cocos2dx3.11.1Android播放视频,后台 黑屏,无法记忆播放bug修改
/* * Copyright (C) 2006 The Android Open Source Project * Copyright (c) 2014 Chukong Technologies In ...
随机推荐
- moveUp()
这个函数内容有点多,想讲一下大概思路: 向上移有两种情况1.前面为空白 这种情况有两个步骤 (1)将人当前的位置设置为空白(0), (2)再讲人前面的位置设置为人(2)2.前面为箱子 当前面为箱子时有 ...
- 预处理、const、static与sizeof-sizeof与strlen有哪些区别
1:它们的区别如下: (1)sizeof是操作符,strlen是函数. (2)sizeof操作符的结果类型是size_t,它在头文件中typedef为unsignedint类型,该类型保证能容纳实现所 ...
- android data binding jetpack VII @BindingAdapter
android data binding jetpack VIII BindingConversion android data binding jetpack VII @BindingAdapter ...
- pytorch-mnist神经网络训练
在net.py里面构造网络,网络的结构为输入为28*28,第一层隐藏层的输出为300, 第二层输出的输出为100, 最后一层的输出层为10, net.py import torch from torc ...
- Nginx作为静态资源web服务-跨站访问
一.跨域访问 1.什么是跨域? 参看我的另一篇博客(https://www.cnblogs.com/chrdai/p/11280895.html) 2.为什么浏览器禁止跨域访问? 不安全,容易出现CS ...
- jenkins 基于角色的权限管理
如何给不同的用户分配不同的项目权限呢,今天来介绍这个 1 (全局安全设置)启用角色->2新建用户->3新建jenkins 全局角色 builder 并分配如下图3中所示权限(并分配Ove ...
- PCB Layout初学者必会知识总结(转)
PCB是印刷电路板(即Printed Circuit Board)的简称.印刷电路板是组装电子零件用的基板,是在通用基材上按预定设计形成点间连接及印制元件的印制板.该产品的主要功能是使各种电子零组件形 ...
- jeecg随笔
1.根据数据字典code查找该字典下的元素: SELECT typecode,typename from t_s_type where typegroupid=(select id from t_s_ ...
- LeetCode 1154. 一年中的第几天
给你一个按 YYYY-MM-DD 格式表示日期的字符串 date,请你计算并返回该日期是当年的第几天. 通常情况下,我们认为 1 月 1 日是每年的第 1 天,1 月 2 日是每年的第 2 天,依此类 ...
- substr 字符串截取
<!DOCTYPE html> <html> <body> <?php echo substr("Hello world",0,10).& ...