Light but somehow easy to use interface to access mplayer process. It works with introspection, I hope the class is self-explanatory. I tested it under Linux only.
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 | import os
import select
import subprocess
class MPlayer(object):
""" A class to access a slave mplayer process
you may want to use command(name, args*) directly
or call populate() to access functions (and minimal doc).
Exemples:
mp.command('loadfile', '/desktop/funny.mp3')
mp.command('pause')
mp.command('quit')
Note:
After a .populate() call, you can access an higher level interface:
mp.loadfile('/desktop/funny.mp3')
mp.pause()
mp.quit()
Beyond syntax, advantages are:
- completion
- minimal documentation
- minimal return type parsing
"""
exe_name = 'mplayer' if os.sep == '/' else 'mplayer.exe'
def __init__(self):
self._mplayer = subprocess.Popen(
[self.exe_name, '-slave', '-quiet', '-idle'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=1)
self._readlines()
def _readlines(self):
ret = []
while any(select.select([self._mplayer.stdout.fileno()], [], [], 0.6)):
ret.append( self._mplayer.stdout.readline() )
return ret
def command(self, name, *args):
""" Very basic interface [see populate()]
Sends command 'name' to process, with given args
"""
cmd = '%s%s%s\n'%(name,
' ' if args else '',
' '.join(repr(a) for a in args)
)
self._mplayer.stdin.write(cmd)
if name == 'quit':
return
return self._readlines()
@classmethod
def populate(kls):
""" Populates this class by introspecting mplayer executable """
mplayer = subprocess.Popen([kls.exe_name, '-input', 'cmdlist'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
def args_pprint(txt):
lc = txt.lower()
if lc[0] == '[':
return '%s=None'%lc[1:-1]
return lc
while True:
line = mplayer.stdout.readline()
if not line:
break
if line[0].isupper():
continue
args = line.split()
cmd_name = args.pop(0)
arguments = ', '.join([args_pprint(a) for a in args])
func_str = '''def _populated_fn(self, *args):
"""%(doc)s"""
if not (%(minargc)d <= len(args) <= %(argc)d):
raise TypeError('%(name)s takes %(argc)d arguments (%%d given)'%%len(args))
ret = self.command('%(name)s', *args)
if not ret:
return None
if ret[0].startswith('ANS'):
val = ret[0].split('=', 1)[1].rstrip()
try:
return eval(val)
except:
return val
return ret'''%dict(
doc = '%s(%s)'%(cmd_name, arguments),
minargc = len([a for a in args if a[0] != '[']),
argc = len(args),
name = cmd_name,
)
exec(func_str)
setattr(MPlayer, cmd_name, _populated_fn)
if __name__ == '__main__':
import sys
MPlayer.populate()
try:
mp = MPlayer()
import readline
readline.parse_and_bind('tab: complete')
import rlcompleter
mp.loadfile(sys.argv[1])
raw_input('Run this with python -i to get interactive shell.'
'\nPress any key to quit.')
finally:
mp.quit()
|
I'm writing a simple music management soft and wanted to integrate a player. pymplayer was not working well for my needs and the API is very basic, so I decided to do it myself for fun. This one checks passed parameters (number of params only, not type for now) and allow some to retrieve returned value (artist name, current position, etc...) try help(MPlayer) after Mplayer.populate() to see what I mean :)