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 ...
随机推荐
- Windows 10 共享需要网络凭据的问题
如果Windows在资源管理器的网络中双击其他的网络设备,提示要输入网络凭据的解决办法: 打开"网络共享中心" -> "更改高级共享设置"->&qu ...
- vuecli3.0 webpack4 配置vuex
废话不说,直接写步骤 1. npm install vux --save 2. npm install less less-loader --save-dev 3. npm install @vux/ ...
- Leetcode题目160.相交链表(简单)
题目描述 编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = ...
- vue-图片预览,查看大图
[前言] 在 vue 项目中经常碰到图片预览需求,也就是点击小图查看大图.也有一些这样的第三方插件,如 vue-preview 等.但使用起来感觉版本经常变,而且有时 UI 需要在预览页面上加更多的东 ...
- 9Patch图
NinePatch是一种很有用的PNG图片格式,它可以在特定区域随文字大小进行缩放. - 上边线控制水平拉伸- 左边线控制竖直拉伸- 右边线和下边线控制内容区域 如下: 背景图片的中间区域会随着文字的 ...
- monkey 查找闪退页面的方法
使用了命令 adb shell monkey --pct-touch 100 -v -p com.iBer.iBerAppV2 5000 >/Users/kaibinliu/Desktop ...
- [Kaggle] How to handle big data?
上一篇,[Kaggle] How to kaggle?[方法导论] 这里再做一点进阶学习. 写在前面 "行业特征" 的重要性 Ref: Kaggle2017—1百万美金的肺癌检测竞 ...
- 【转】ffluos编译
FluffOS是在MUDOS基础上更新完成的.进行了许多新功能和bug修复. 针对LPC有很好的兼容性,如果你的MUD运行MUDOS V22+版本,可以很容易运行在fluffos上. 系统环境: Cn ...
- WMPageController设置menuView的左右视图
效果图如下: 绿色的是自定义的emenuView的rightView哟!!! 代码实现如下: // // CategoryVC.m // JSHui // // Created by Apple on ...
- k8s 工具集
Volcano 资源调度器 apollo 配置中心 spinnaker 持续部署系统 jaeger 分布式跟踪系统.它用于监视和诊断基于微服务的分布式系统,包括: 分布式上下文传播 分布式交易监控 根 ...