SoFunction
Updated on 2024-11-17

A complete example of a Python implementation of the video player functionality

This article example tells about the video player function implemented in Python. Shared for your reference, as follows:

# -*- 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  import *
import pyglet
from  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():
  x = y = 0
  width = height = 10
  def __init__(self, parent):
    super(Control, self).__init__()
     = parent
  def hit_test(self, x, y):#Point in the control
    return ( < x <  +  and 
         < y <  + )
  def capture_events(self):
    .push_handlers(self)
  def release_events(self):
    .remove_handlers(self)
class Button(Control):
  charged = False
  def draw(self):
    if :
      glColor3f(0, 1, 0)
    draw_rect(, , , )
    glColor3f(1, 1, 1)
    self.draw_label()
  def on_mouse_press(self, x, y, button, modifiers):
    self.capture_events()
     = True
  def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
     = 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')
     = False
Button.register_event_type('on_press')#Registered Events
class TextButton(Button):
  def __init__(self, *args, **kwargs):
    super(TextButton, self).__init__(*args, **kwargs)
    self._text = ('', anchor_x='center', anchor_y='center')
  def draw_label(self):
    self._text.x =  +  / 2
    self._text.y =  +  / 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 =  +  / 2
    draw_rect(, center_y - self.GROOVE_HEIGHT / 2, 
         , self.GROOVE_HEIGHT)
    pos =  +  *  / ( - )
    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):# Change the progress
    return float(x - ) /  * ( - ) + 
  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.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():
  GUI_WIDTH = 400
  GUI_HEIGHT = 40
  GUI_PADDING = 4#Button Interval
  GUI_BUTTON_HEIGHT = 16
  def __init__(self, player):
    super(PlayerWindow, self).__init__(caption='Media Player',
                      visible=False, 
                      resizable=True)
     = player
    .push_handlers(self)
    .eos_action = .EOS_PAUSE
     = Slider(self)
     = self.GUI_PADDING# Class variables
     = self.GUI_PADDING * 2 + self.GUI_BUTTON_HEIGHT
    .on_begin_scroll = lambda: ()
    .on_end_scroll = lambda: ()
    .on_change = lambda value: (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# It's got its own magic
    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)# Be careful not to write self
     = [
      , 
      self.play_pause_button,
      self.window_button,
    ]
    x = self.window_button.x + self.window_button.width + self.GUI_PADDING
    i = 0
    for screen in .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)
      (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 :
      source = 
       = 0.
       = 
    self.gui_update_state()
  def gui_update_state(self):
    if :
      self.play_pause_button.text = 'Pause'
    else:
      self.play_pause_button.text = 'Play'
  def get_video_size(self):
    if not  or not .video_format:
      return 0, 0
    video_format = .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)
     = 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 :
      if control.hit_test(x, y):
        control.on_mouse_press(x, y, button, modifiers)
  def on_key_press(self, symbol, modifiers):
    if symbol == :
      self.on_play_pause()
    elif symbol == :
      self.dispatch_event('on_close')
  def on_close(self):
    ()
    ()
  def on_play_pause(self):
    if :
      ()
    else:
      if  >= :#If it's done
        (0)
      ()
    self.gui_update_state()
  def on_draw(self):
    ()
    # Video
    if  and .video_format:
      .get_texture().blit(self.video_x,
                      self.video_y,
                      width=self.video_width,
                      height=self.video_height)
    # GUI
     = 
    for control in :
      ()
if __name__ == '__main__':
  if len() < 2:
    print('Usage: media_player.py <filename> [<filename> ...]')
    (1)
  for filename in [1:]:
    player = ()
    window = PlayerWindow(player)
    source = (filename)
    (source)
    window.gui_update_source()
    window.set_default_video_size()
    window.set_size(400,400)
    window.set_visible(True)
    window.gui_update_state()
    ()
  ()

Note: The pyglet library used here can be downloaded by clicking here/~gohlke/pythonlibs/#pyglet

Readers interested in more Python related content can check out this site's topic: theSummary of Python file and directory manipulation techniques》、《Summary of Python text file manipulation techniques》、《Python Data Structures and Algorithms Tutorial》、《Python Socket Programming Tips Summary》、《Summary of Python function usage tips》、《Summary of Python string manipulation techniquesand thePython introductory and advanced classic tutorials

I hope that what I have said in this article will help you in Python programming.