/usr/lib/python2.7/dist-packages/pympg.py is in python-pykaraoke 0.7.5-1.2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | # pympg - MPEG Karaoke Player
#
# Copyright (C) 2010 Kelvin Lawson (kelvinl@users.sourceforge.net)
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from pykconstants import *
from pykplayer import pykPlayer
from pykenv import env
from pykmanager import manager
import pygame, sys, os, string, subprocess
import threading
# OVERVIEW
#
# pympg is an MPEG player built using python. It was written for the
# PyKaraoke project but is in fact a general purpose MPEG player that
# could be used in other python projects requiring an MPEG player.
#
# The player uses the pygame library (www.pygame.org), and can therefore
# run on any operating system that runs pygame (currently Linux, Windows
# and OSX).
#
# You can use this file as a standalone player, or together with
# PyKaraoke. PyKaraoke provides a graphical user interface, playlists,
# searchable song database etc.
#
# For those writing a media player or similar project who would like
# MPG support, this module has been designed to be easily incorporated
# into such projects and is released under the LGPL.
# REQUIREMENTS
#
# pympg requires the following to be installed on your system:
# . Python (www.python.org)
# . Pygame (www.pygame.org)
# USAGE INSTRUCTIONS
#
# To start the player, pass the MPEG filename/path on the command line:
# python pympg.py /songs/theboxer.mpg
#
# You can also incorporate a MPG player in your own projects by
# importing this module. The class mpgPlayer is exported by the
# module. You can import and start it as follows:
# import pympg
# player = pympg.mpgPlayer("/songs/theboxer.mpg")
# player.Play()
# If you do this, you must also arrange to call pympg.manager.Poll()
# from time to time, at least every 100 milliseconds or so, to allow
# the player to do its work.
#
# The class also exports Close(), Pause(), Rewind(), GetPos().
#
# There are two optional parameters to the initialiser, errorNotifyCallback
# and doneCallback:
#
# errorNotifyCallback, if provided, will be used to print out any error
# messages (e.g. song file not found). This allows the module to fit
# together well with GUI playlist managers by utilising the same GUI's
# error popup window mechanism (or similar). If no callback is provided,
# errors are printed to stdout. errorNotifyCallback should take one
# parameter, the error string, e.g.:
# def errorPopup (ErrorString):
# msgBox (ErrorString)
#
# doneCallback can be used to register a callback so that the player
# calls you back when the song is finished playing. The callback should
# take no parameters, e.g.:
# def songFinishedCallback():
# msgBox ("Song is finished")
#
# To register callbacks, pass the functions in to the initialiser:
# mpgPlayer ("/songs/theboxer.mpg", errorPopup, songFinishedCallback)
# These parameters are optional and default to None.
#
# If the initialiser fails (e.g. the song file is not present), __init__
# raises an exception.
# IMPLEMENTATION DETAILS
#
# pympg is implemented as a handful of python modules. Pygame provides
# all of the MPEG decoding and display capabilities, and can play an
# MPEG file with just a few lines of code. Hence this module is rather
# small. What it provides on top of the basic pygame features, is a
# player-like class interface with Play, Pause, Rewind etc. It also
# implements a resizable player window. And, of course, it integrates
# nicely with pykaraoke.py and pykaraoke_mini.py.
#
# Previous implementations ran the player within a thread; this is no
# longer the case. Instead, it is the caller's responsibility to call
# pycdg.manager.Poll() every once in a while to ensure that the player
# gets enough CPU time to do its work. Ideally, this should be at
# least every 100 milliseconds or so to guarantee good video and audio
# response time.
# Display depth (bits)
DISPLAY_DEPTH = 32
# Check to see if the movie module is available.
try:
import pygame.movie as movie
except ImportError:
movie = None
# mpgPlayer Class
class mpgPlayer(pykPlayer):
# Initialise the player instace
def __init__(self, song, songDb, errorNotifyCallback=None, doneCallback=None):
"""The first parameter, song, may be either a pykdb.SongStruct
instance, or it may be a filename. """
pykPlayer.__init__(self, song, songDb, errorNotifyCallback, doneCallback)
self.Movie = None
manager.setCpuSpeed('mpg')
manager.InitPlayer(self)
manager.OpenDisplay(depth = DISPLAY_DEPTH)
# Close the mixer while using Movie
manager.CloseAudio()
# Open the Movie module
filepath = self.SongDatas[0].GetFilepath()
if type(filepath) == unicode:
filepath = filepath.encode(sys.getfilesystemencoding())
self.Movie = pygame.movie.Movie(filepath)
self.Movie.set_display(manager.display, (0, 0, manager.displaySize[0], manager.displaySize[1]))
def doPlay(self):
self.Movie.play()
def doPause(self):
self.Movie.pause()
def doUnpause(self):
self.Movie.play()
def doRewind(self):
self.Movie.stop()
self.Movie.rewind()
# Get the movie length (in seconds).
def GetLength(self):
return self.Movie.get_length()
# Get the current time (in milliseconds).
def GetPos(self):
return (self.Movie.get_time() * 1000)
def SetupOptions(self):
""" Initialise and return optparse OptionParser object,
suitable for parsing the command line options to this
application. """
parser = pykPlayer.SetupOptions(self, usage = "%prog [options] <mpg filename>")
# Remove irrelevant options.
parser.remove_option('--font-scale')
return parser
def shutdown(self):
# This will be called by the pykManager to shut down the thing
# immediately.
if self.Movie:
self.Movie.stop()
# Must remove the object before using pygame.mixer module again
self.Movie = None
pykPlayer.shutdown(self)
def handleEvent(self, event):
if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN and (event.mod & (pygame.KMOD_LSHIFT | pygame.KMOD_RSHIFT | pygame.KMOD_LMETA | pygame.KMOD_RMETA)):
# Shift/meta return: start/stop song. Useful for keybinding apps.
self.Close()
return
pykPlayer.handleEvent(self, event)
# Internal. Only called by the pykManager.
def doResize(self, newSize):
# Resize the screen.
self.Movie.set_display(manager.display, (0, 0, manager.displaySize[0], manager.displaySize[1]))
# Internal. Only called by the pykManager.
def doResizeBegin(self):
# The Movie player must be paused while resizing otherwise we
# get Xlib errors. pykmanager will call here before the resize
# so that we can do it.
if self.State == STATE_PLAYING:
self.Movie.pause()
# Internal. Only called by the pykManager.
def doResizeEnd(self):
# Called by pykmanager when resizing has finished.
# We only play if it was playing in the first place.
if self.State == STATE_PLAYING:
self.Movie.play()
class externalPlayer(pykPlayer):
""" This class is used to invoke an external command and wait for
it to finish. It is usually used to play a video file using an
external player. """
def __init__(self, song, songDb, errorNotifyCallback=None, doneCallback=None):
"""The first parameter, song, may be either a pykdb.SongStruct
instance, or it may be a filename. """
pykPlayer.__init__(self, song, songDb, errorNotifyCallback, doneCallback)
self.Movie = None
manager.setCpuSpeed('mpg')
manager.InitPlayer(self)
# Close the audio and the display
manager.CloseAudio()
manager.CloseDisplay()
manager.CloseCPUControl()
self.procReturnCode = None
self.proc = None
def doPlay(self):
if self.procReturnCode != None:
# The movie is done.
self.__stop()
if not self.proc:
self.__start()
def GetLength(self):
# We cannot fetch the length from arbitrary external players.
# Return zero-length.
return 0
def GetPos(self):
# Use the default GetPos() which simply checks the time
# since we started playing. This does not take account
# for any fast-forward/rewind that may occur in the
# external player, but we cannot support getting the
# song position from arbitrary user-supplied players.
return pykPlayer.GetPos(self)
def doStuff(self):
if self.procReturnCode != None:
# The movie is done.
self.__stop()
self.Close()
pykPlayer.doStuff(self)
def __start(self):
filepath = self.SongDatas[0].GetFilepath()
external = manager.settings.MpgExternal
if '%' in external:
# Assume the filename parameter is embedded in the string.
cmd = external % {
'file' : filepath,
}
elif external:
# No parameter appears to be present; assume the program
# accepts the filename as the only parameter.
cmd = [external, filepath]
shell = True
if env == ENV_WINDOWS:
# Don't try to open the process under a "shell" in
# Windows; that just breaks commands with spaces.
shell = False
assert self.procReturnCode == None
sys.stdout.flush()
self.proc = subprocess.Popen(cmd, shell = shell)
if manager.settings.MpgExternalThreaded:
# Wait for it to complete in a thread.
self.thread = threading.Thread(target = self.__runThread)
self.thread.start()
else:
# Don't wait for it in a thread; wait for it here.
self.thread = None
self.__runThread()
def __stop(self):
if self.thread:
self.thread.join()
self.proc = None
self.procReturnCode = None
self.thread = None
def __runThread(self):
""" This method runs in a sub-thread. Its job is just to wait
for the process to finish. """
try:
self.procReturnCode = self.proc.wait()
except OSError:
self.procReturnCode = -1
# Can be called from the command line with the MPG filepath as parameter
def main():
player = mpgPlayer(None, None)
player.Play()
manager.WaitForPlayer()
if __name__ == "__main__":
sys.exit(main())
#import profile
#result = profile.run('main()', 'pympg.prof')
#sys.exit(result)
|