.. currentmodule:: MplayerCtrl .. _cheeseshop: http://pypi.python.org/pypi/MplayerCtrl/ .. _wxPython: http://wxpython.org .. _MplayerCtrl: http://packages.python.org/MplayerCtrl/ .. _MplayerWin32Download: http://sourceforge.net/projects/mplayer-win32/files/ .. _MplayerDownload: http://www.mplayerhq.hu/design7/dload.html ======== Tutorial ======== This tutorial is written to show you how easy it is to use the MplayerCtrl with wxPython and not to teach you how to use wxPython_. .. note:: You need to start the script as administrator in Windows Vista and Windows 7 (because of UAC) .. _installation: Download and Installation ------------------------- There are three things to download and to install: * wxPython * the MplayerCtrl * and the Mplayer, of course. Download ======== Don't forget that the MplayerCtrl has one dependency: wxPython_. If you need to install wxPython, you can download it `here `_. Of course you first need to install the MplayerCtrl, before you can use it. You can download the source from the cheeseshop_ and install it with the setup.py or you can also use easy_install or pip:: easy_install MplayerCtrl # or pip install MplayerCtrl One last item that you need is the mplayer(.exe), which you can get here: MplayerDownload_ or you can get the Win32 files here: MplayerWin32Download_. Installation ============ * At the wxPython_ website there are tutorials for how to install it on all major platforms. * Installation instructions for the Mplayer can be found in the following `README `_ and/or the `installation section `_. * Now let's install the **MplayerCtrl**: If you've downloaded the installer, just install it. You can install the source with this command:: > setup.py install or as said above you can use easy_install or pip:: easy_install MplayerCtrl # or pip install MplayerCtrl Now you can import it! :: >>> import MplayerCtrl as mpc >>> mpc.__version__ '0.3.0' Getting started --------------- Let's start with an easy Frame. :: import wx import MplayerCtrl as mpc class Frame(wx.Frame): def __init__(self, parent, id, title, mplayer, media_file): wx.Frame.__init__(self, parent, id, title) self.mpc = mpc.MplayerCtrl(self, -1, mplayer, media_file) self.Show() if __name__ == '__main__': app = wx.App(redirect=False) frame = Frame(None, -1, 'Hello MplayerCtrl', u'mplayer', u'testmovie.mpg') app.MainLoop() So, what's happening here? 1. We create a class named Frame, as you would do normally 2. There's an attribute called *mpc*. It's an instance of the :class:`~MplayerCtrl.MplayerCtrl` class with the following arguments: 1. argument: *parent* of the :class:`~MplayerCtrl` 2. argument: *id* of the :class:`~MplayerCtrl`, as used for each wx.Panel instance 3. argument: the path to the mplayer(.exe) 4. argument: this arg is optional. It's used to start playback immediately with the given file; in this case the file's name is testmovie.mpg 3. Our frame is created and shown .. note:: You have to pass unicode to the MplayerCtrl Events ------ .. note:: The events are in the MplayerCtrl_ module, not in the wxPython_ module. You should know what events are and how you can use them with wxPython. A list of all :ref:`reference-events` of the :class:`~MplayerCtrl`. Standard events =============== :: import wx import MplayerCtrl as mpc class Frame(wx.Frame): def __init__(self, parent, id, title, mplayer, media_file): wx.Frame.__init__(self, parent, id, title) self.mpc = mpc.MplayerCtrl(self, -1, mplayer, media_file) self.Bind(mpc.EVT_PROCESS_STARTED, self.on_process_started) self.Bind(mpc.EVT_MEDIA_STARTED, self.on_media_started) self.Bind(mpc.EVT_MEDIA_FINISHED, self.on_media_finished) self.Bind(mpc.EVT_PROCESS_STOPPED, self.on_process_stopped) self.Show() def on_process_started(self, evt): print 'Process started' def on_media_started(self, evt): print 'Media started' def on_media_finished(self, evt): print 'Media finished' self.mpc.Quit() def on_process_stopped(self, evt): print 'Process stopped' if __name__ == '__main__': app = wx.App(redirect=False) frame = Frame(None, -1, 'Hello MplayerCtrl', u'mplayer', u'testmovie.mpg') app.MainLoop() If you run the code above, you can tell that the events are working because the print statements should be printing to your stdout. The events will signal you as soon as they fire to let you know which event happened. If the :attr:`~EVT_MEDIA_FINISHED` is posted, we :meth:`~MplayerCtrl.Quit` the Mplayer process, but the Panel won't be destroyed. To destroy the complete MplayerCtrl you have to call the :meth:`~MplayerCtrl.Destroy` method. Stderr Event ============ There are two special events, one of them is the :attr:`EVT_STDERR` event. Let's extend the example above to demonstrate how this event works:: import wx import MplayerCtrl as mpc class Frame(wx.Frame): def __init__(self, parent, id, title, mplayer, media_file): wx.Frame.__init__(self, parent, id, title) self.mpc = mpc.MplayerCtrl(self, -1, mplayer, media_file) self.Bind(mpc.EVT_PROCESS_STARTED, self.on_process_started) self.Bind(mpc.EVT_MEDIA_STARTED, self.on_media_started) self.Bind(mpc.EVT_MEDIA_FINISHED, self.on_media_finished) self.Bind(mpc.EVT_PROCESS_STOPPED, self.on_process_stopped) self.Bind(mpc.EVT_STDERR, self.on_stderr) self.Show() def on_process_started(self, evt): print 'Process started' def on_media_started(self, evt): print 'Media started' def on_media_finished(self, evt): print 'Media finished' self.mpc.Quit() def on_process_stopped(self, evt): print 'Process stopped' def on_stderr(self, evt): print 'oh oh some errors:' print '==>', evt.data if __name__ == '__main__': app = wx.App(redirect=False) frame = Frame(None, -1, 'Hello MplayerCtrl', u'mplayer', u'testmovie.mpg') app.MainLoop() As you can see, there's a new event every time the mplayer process writes data to its stderr. To access the data, call the :attr:`~MplayerCtrl.MplayerCtrl.Stderr.data` attribute of the event-argument (line: 31). An example output:: Process started Media started oh oh some errors: ==> The selected video_out device is incompatible with this codec. Media finished Process stopped Stdout Event ============ .. versionadded:: 0.2.3 The :attr:`EVT_STDOUT` event is similar to the the Stderr event, you can also access the data through evt.data. The one and only difference is, the data contains the stdout output of the mplayer, instead of the stderr. To use this event you've to replace :attr:`EVT_STDERR` with :attr:`EVT_STDOUT` (see the example above). Properties ---------- There are 4 ways how you can change/set properties: 1. :ref:`tutorial-pythonic-property` 2. :ref:`tutorial-get-property` 3. :ref:`tutorial-set-property` 4. :ref:`tutorial-step-property` .. _tutorial-pythonic-property: "Pythonic" properties ===================== .. versionadded:: 0.2.0 Now there are real pythonic properties, created with property, you can access them through MplayerCtrl.the_prop. A little example:: volume = self.mpc.volume stream_pos = self.mpc.stream_pos # now set a property self.mpc.volume = 50 self.mpc.time_pos = 20 # now de/increase a property self.mpc.volume -= 10 self.mpc.time_pos += 5 A list of all properties: :ref:`reference-props` .. _tutorial-get-property: GetProperty =========== :meth:`~MplayerCtrl.GetProperty` returns the current value of a property. Example usage:: length = self.mpc.GetProperty('length') print 'The current length of the file:', length If a property isn't available for this type of media or the property isn't a valid property (:ref:`reference-props`), an :exc:`~MplayerCtrl.AnsError` is raised. .. _tutorial-set-property: SetProperty =========== :meth:`~MplayerCtrl.SetProperty` sets a property, a list with all possible properties you can find here: :ref:`reference-props` Example usage:: self.mpc.SetProperty('volume', 90) If the property isn't a valid property (:ref:`reference-props`), an :exc:`~MplayerCtrl.AnsError` is raised. .. _tutorial-step-property: StepProperty ============ :meth:`~MplayerCtrl.StepProperty` changes a property by value, or increases by a default if value is not given or zero. The direction is reversed if direction is less than zero. Example usage:: self.mpc.StepProperty('volume', 5) If the property isn't a valid property (:ref:`reference-props`), an :exc:`~MplayerCtrl.AnsError` is raised. Methods ------- There are many more methods to set/get properties. Here's a list of all the methods of the :class:`MplayerCtrl` class: :class:`MplayerCtrl` .. _tutorial-arguments: Arguments --------- In the `Mplayer-Documentation `_ you can find a list of all available args. If you create an instance of the :class:`MplayerCtrl` class, you can get started with these args:: -wid, -slave, -noconsolecontrols, -nofontconfig, -input conf=devnull // os.devnull -input nodefault-bindings -idle The -input, -slave and -idle arguments are added automatically if not specified .. versionchanged:: 0.1.3 behavior of passing arguments to the mplayer If you want to use your own args for the mplayer, you can use *mplayer_args* it must be a list or tuple containing the arguments. .. warning:: You should never add -wid and -msglevel this does the MplayerCtrl for you and both are required for full functionallity Exceptions ---------- There is no module without (custom) exceptions. The MplayerCtrl has these exceptions: 1. BaseMplayerCtrlException 2. AnsError 3. BuildProcessError 4. NoMplayerRunning BaseMplayerCtrlException ======================== The :exc:`MplayerCtrl.BaseMplayerCtrlException` is the base exception for all other exceptions from the MplayerCtrl module. To catch all exceptions thrown by the MplayerCtrl you can use this (Note: this is not recommended as it's not very useful):: try: # do something except mpc.BaseMplayerCtrlException: pass AnsError ======== The :exc:`MplayerCtrl.AnsError` is raised, if an ANS_ERROR is returned by the mplayer process. Possible causes for this error: * wrong value * unknown property * property is unavailable, e.g. the chapter property used while playing a stream BuildProcessError ================= The :exc:`MplayerCtrl.BuildProcessError` is raised if the path to the mplayer(.exe) is incorrect or another error occurs while building the mplayer. NoMplayerRunning ================ The :exc:`MplayerCtrl.NoMplayerRunning` is raised, if you've quit the mplayer with :meth:`MplayerCtrl.Quit` and try to call a method/function of the MplayerCtrl. To solve this problem you've just to call :meth:`MplayerCtrl.Start`. .. versionadded:: 0.2.2 Examples -------- Here is a very simple example: A wx.Frame with the MplayerCtrl and the MplayerCtrl plays a file (*testmovie.mpg*):: import wx import MplayerCtrl as mpc class Frame(wx.Frame): def __init__(self, parent, id): wx.Frame.__init__(self, parent, id) self.mpc = mpc.MplayerCtrl(self, -1, u'mplayer.exe', media_file=u'testmovie.mpg') self.Show() if __name__ == '__main__': app = wx.App(redirect=False) f = Frame(None, -1) app.MainLoop() Another example, now with events:: import wx import MplayerCtrl as mpc class Frame(wx.Frame): def __init__(self, parent, id): wx.Frame.__init__(self, parent, id) self.mpc = mpc.MplayerCtrl(self, -1, u'mplayer.exe', media_file=u'testmovie.mpg') self.Bind(mpc.EVT_MEDIA_STARTED, self.on_media_started) self.Bind(mpc.EVT_MEDIA_FINISHED, self.on_media_finished) self.Bind(mpc.EVT_PROCESS_STARTED, self.on_process_started) self.Bind(mpc.EVT_PROCESS_STOPPED, self.on_process_stopped) self.Show() def on_media_started(self, evt): print 'Media started!' def on_media_finished(self, evt): print 'Media finished!' self.mpc.Quit() # quits the Mplayer-process def on_process_started(self, evt): print 'Process started!' def on_process_stopped(self, evt): print 'Process stopped!' if __name__ == '__main__': app = wx.App(redirect=False) f = Frame(None, -1) app.MainLoop() Now let's get the arriving data from stderr and stdout:: import wx import MplayerCtrl as mpc class Frame(wx.Frame): def __init__(self, parent, id): wx.Frame.__init__(self, parent, id) self.mpc = mpc.MplayerCtrl(self, -1, u'mplayer.exe', media_file=u'testmovie.mpg') self.Bind(mpc.EVT_STDERR, self.on_stderr) self.Bind(mpc.EVT_STDOUT, self.on_stdout) self.Show() def on_stderr(self, evt): print ':O Some errors:', evt.data def on_stdout(self, evt): print 'stdout >>>', evt.data if __name__ == '__main__': app = wx.App(redirect=False) f = Frame(None, -1) app.MainLoop() Let's use a wx.EVT_KEY_DOWN event to decrease or increase the volume:: import MplayerCtrl as mpc import wx class Frame(wx.Frame): def __init__(self, parent, id, size=(-1,-1)): wx.Frame.__init__(self, parent, id, size=size) self.mpc = mpc.MplayerCtrl(self, -1, u'mplayer') self.Bind(mpc.EVT_MEDIA_STARTED, self.media_started) self.Bind(mpc.EVT_MEDIA_FINISHED, self.media_finished) self.Bind(mpc.EVT_PROCESS_STARTED, self.process_started) self.Bind(mpc.EVT_PROCESS_STOPPED, self.process_stopped) self.mpc.Bind(wx.EVT_KEY_DOWN, self.key_down) self.Center() self.Show() def media_started(self, evt): print '----------> Media started' def media_finished(self, evt): print '----------> Media finished' def process_started(self, evt): print '----------> Process started' self.mpc.Loadfile(u'testmovie.mpg') def process_stopped(self, evt): print '----------> Process stopped' def key_down(self, evt): k = evt.GetKeyCode() if k in (43, 45) and self.mpc.playing: volume = self.mpc.volume if k == 43: if not volume > 95: self.mpc.volume += 5 elif k == 45: if not volume <= 5: self.mpc.volume -= 5 evt.Skip() if __name__ == '__main__': app = wx.App() f = Frame(None, -1) app.MainLoop() See also: ``_