PyMPlayer 0.6.0 - March 3, 2011

Changes since 0.5.0

--------------------
      General
--------------------

 * The command() and query() methods are no more. Use the generated methods
   and properties for interacting with MPlayer. In other words, the interaction
   with MPlayer, and the API for that matter, became more Pythonic. Now, Windows
   is also fully-supported.

 * properties are also generated by Player.introspect(). MPlayer properties
   are exposed as Python properties (new-style classes). As such, 'get_property'
   and 'set_property' is done via regular property access. On the other hand,
   'step_property' is done by using the Step class with property access.
   For instance, the following code fragment:

      p = Player()
      p.time_pos = Step(value=10)

   will generate the command: 'step_property time_pos 10'

   Note that properties take precedence over commands. Thus, commands with the
   same name and/or functionality with a particular property will not be generated.

 * Player.introspect() now called by default on module load, not on instantiation

 * An 'autospawn' parameter (default: True) is introduced. This is for used for
   autospawning the underlying MPlayer process upon class instantiation so that
   users can immediately issue commands to MPlayer without forgetting to spawn
   the MPlayer process first.

--------------------
        API
--------------------

Additions:
 * Added CommandPrefix and Step classes


Changes:
 * Player(args=(), introspect=True) -> Player(args=(), stdout=PIPE, stderr=None, autospawn=True):
   The parameters for stdout and stderr can now be specified on class
   instantiation. Note that stdout=PIPE is now the default.
   Also applicable to: GPlayer and QtPlayer

 * AsyncPlayer(args=(), introspect=True, socket_map=None) to
   AsyncPlayer(args=(), stdout=PIPE, stderr=None, autospawn=True, socket_map=None)

 * Player.start(stdout=None, stderr=None) -> Player.spawn():
   The stdout and stderr optional arguments of start() can now be specified
   on class instantiation.
   NOTE: spawn() will be called automatically on instantiation if autospawn is True

 * Player.command(name, *args) -> _command(name, *args, **kwargs):
   command() is now an internal method. Use the introspection-generated methods
   such as loadfile(), pause(), etc. instead.

 * All generated methods now accept an optional 'prefix' parameter. For instance,
   pause() -> pause(prefix=None). The CommandPrefix class contains the valid prefixes.

 * The 'complete' signal of QtPlayer has been renamed to 'completed'


Deletions:
 * Player.get_property():
   Use Python property access instead
   
 * Player.get_*() methods except get_meta_*():
   Use Python property access instead

 * Player.query():
   The functionality of query() has been merged back to _command(). Use the
   introspection-generated methods and properties instead.
   NOTE: Support for timeouts has been removed.

--------------------
   Typical Usage
--------------------

from mplayer import Player, Step, CommandPrefix

# Set path to the mplayer binary
Player.path = '/path/to/mplayer'
# Generate additional methods based on the currently installed version
Player.introspect()

p = Player()
p.loadfile('/path/to/somefile.mp4')
fn = p.filename
p.seek(50, 1)
p.time_pos += 5
p.pause()
Player.command_prefix = CommandPrefix.PAUSING_KEEP
p.percent_pos = Step()
...
p.quit()

--------------------
 Player interaction
--------------------

There are two ways of obtaining data from MPlayer.

1. synchronous:

p = mplayer.Player()
p.loadfile('/path/to/some/file.mkv')
time_length = p.length
# if successful, time_length should now contain a float object

This method simply returns whatever is in the pipe buffers.

*** IMPORTANT ***
Getting property values will temporarily suppress the transfer of data to the
subscribers. Upon finishing, data transfer to the subscribers will be enabled
again.


2. asynchronous (via publish-subscribe mechanism):

This method is inspired by the Observer design pattern (aka publisher/subscriber)
and is the replacement for handle_data() and handle_error() introduced in 0.3.0.
Basically, subscribers are simply callback functions which accept a single
parameter--the data published by whichever publisher (stdout/stderr) the
subscribers are attached to.

For applications using asyncore, GTK/GObject, or Qt, using the Player subclasses
is the recommended way. Typical usage are as follows:

asyncore:

  p = mplayer.async.AsyncPlayer()
  p.stdout.hook(subscriber1)
  asyncore.loop()


GTK/GObject:

  p = mplayer.gtk2.GPlayer()
  p.stdout.hook(subscriber1)
  gtk.main()


Qt:

  app = QtGui.QApplication(sys.argv)
  p = mplayer.qt4.QtPlayer()
  p.stdout.hook(subscriber1)
  sys.exit(app.exec_())


For other frameworks or toolkits, e.g. Tkinter, typical usage is as follows:

  p = mplayer.Player()
  p.stdout.hook(subscriber1)

  fd = p.stdout.fileno()
  cb = p.stdout.publish

  tkinter.createfilehandler(fd, tkinter.READABLE, cb)
