remuco (version 0.9.6) |

`Remuco player adapter module.
The module 'remuco' provides classes and constants for Remuco player adapters.
Class PlayerAdapter:
Base class for player adapters (start reading here).
Class MPRISAdapter:
Base class for player adapters for MPRIS players.
Classes ItemAction and ListAction:
Classes to define actions clients may execute in their media browser.
Class ListReply:
Used by player adapters to reply requests for playlists and other lists.
Class Manager:
Helper class for managing the life cycle of a player adapter.
Constants:
The constants starting with 'INFO' are keys to be used for the dictionary
describing an item (a playable object: song, video, slide, picture, ...).
The constants starting with 'PLAYBACK' are the values used by Remuco to
describe a playback state.
Logging:
It is recommended to use the remuco logging system within player adapters.
To do so, import the module 'remuco.log' and use the functions
* remuco.log.debug(),
* remuco.log.info(),
* remuco.log.warning() and
* remuco.log.error().
Then all messages of the player adapter will be written into the same file
as used internally by the remuco module - that makes debugging a lot easier.
Internally Remuco uses the module 'logging' for all its logging messages.
Messages go into a player specific log file (usually
~/.cache/remuco/PLAYER/log). The log level is defined in a player specific
configuration file (usually ~/.config/remuco/PLAYER/conf).`

Package Contents

``

adapter art config data defs | dictool features files log manager | message mpris net remos report | serial testshell

Classes

``

__builtin__.object
  remuco.adapter.ItemAction
  remuco.adapter.ListAction
  remuco.adapter.ListReply
  remuco.adapter.PlayerAdapter
    remuco.mpris.MPRISAdapter
  remuco.config.Config
  remuco.manager.Manager

class Config(__builtin__.object)
`` | `Class for getting and setting player adapter specific configurations. An instance of Config mirrors the configuration of a specific player adapter (usually ~/.config/remuco/PLAYER/conf). Player adapters are not supposed to create instances of Config. Instead use the 'config' attribute of a PlayerAdapter instance to access the currently used Config instance.`

Methods defined here:

__getattribute__(self, attr)
  `Attribute-style access to standard options.`

__init__(self, player_name)
  `Create a new instance for the given player (adapter).`

getx(self, key, default, converter=None, save=True)
  `Get the value of a non-standard, player specific option.
  @param key:
  config option name
  @param default:
  default value (as string!)
  @keyword converter:
  value converter function, e.g. `int`
  @keyword save:
  save default value in config file if not yet set
  @return:
  option value, optionally converted`

Data descriptors defined here:

__dict__
  `dictionary for instance variables (if defined)`

__weakref__
  `list of weak references to the object (if defined)`

class ItemAction(__builtin__.object)

``

`Item related action for a client's media browser.
An item action defines an action a client may apply to a file from the
local file system, to an item from the playlist, to an item from the play
queue or to an item from the player's media library.
If possible, player adapters should define item actions and send them to
clients by setting the keyword 'file_actions' in PlayerAdapter.__init__(),
via PlayerAdapter.reply_playlist_request(), via
PlayerAdapter.reply_queue_request() or via
PlayerAdapter.reply_mlib_request(). Clients may then use these actions
which results in a call to PlayerAdapter.action_files(),
PlayerAdapter.action_playlist_item(), PlayerAdapter.action_queue_item() or
PlayerAdapter.action_mlib_item().
@see: PlayerAdapter.action_files()
@see: PlayerAdapter.action_playlist()
@see: PlayerAdapter.action_queue()
@see: PlayerAdapter.action_mlib_item()
`

Methods defined here:

__init__(self, label, multiple=False)
  `Create a new action for items or files.
  @param label:
  label of the action (keep short, ideally this is just a single word
  like 'Enqueue', 'Play', ..)
  @keyword multiple:
  if the action may be applied to multiple items/files or only to a
  single item/file`

__str__(self)

Data descriptors defined here:

__dict__
  `dictionary for instance variables (if defined)`

__weakref__
  `list of weak references to the object (if defined)`

id
  `ID of the action (auto-generated, read only)`

class ListAction(__builtin__.object)

``

`List related action for a client's media browser.
A list action defines an action a client may apply to a list from the
player's media library. If possible, player adapters may define list
actions and send them to clients via PlayerAdapter.replay_mlib_request()
Clients may then use these actions which results in a call to
PlayerAdapter.action_mlib_list().
@see: PlayerAdapter.action_mlib_list()
`

Methods defined here:

__init__(self, label)
  `Create a new action for lists from a player's media library.
  @param label:
  label of the action (keep short, ideally this is just a single word
  like 'Load', ..)`

__str__(self)

Data descriptors defined here:

__dict__
  `dictionary for instance variables (if defined)`

__weakref__
  `list of weak references to the object (if defined)`

id
  `ID of the action (auto-generated, read only)`

class ListReply(__builtin__.object)

``

`Reply object for an item list request.
A ListReply is the first parameter of the request methods
PlayerAdapter.request_playlist(), PlayerAdapter.request_queue(),
PlayerAdapter.request_mlib() and PlayerAdapter.request_search().
Player adapters are supposed to use the list reply object to set the
reply data (using properties 'ids', 'names', 'item_actions' and
'nested', 'list_actions') and to send the reply to clients (using send()).
`

Methods defined here:

__init__(self, client, request_id, reply_msg_id, page, path=None)
  `Create a new list reply.
  Used internally, not needed within player adapters.
  @param client: the client to send the reply to
  @param request_id: the request's ID
  @param reply_msg_id: the message ID of the client's request
  @param page: page of the requested list
  @keyword path: path of the requested list, if there is one`

send(self)
  `Send the requested item list to the requesting client.`

Data descriptors defined here:

__dict__
  `dictionary for instance variables (if defined)`

__weakref__
  `list of weak references to the object (if defined)`

ids
  `IDs of the items contained in a list.
  Player adapters should set this to a list of IDs of the items contained
  in the requested list.`

item_actions
  `A list of actions clients can apply to items in the list.
  The list must contain ItemAction objects.`

list_actions
  `A list of actions clients can apply to nested lists in the list.
  The list must contain ListAction objects.`

names
  `Names of the items contained in a list.
  Player adapters should set this to a list of names of the items
  contained in the requested list. Good choice for a name is combination
  of artist and title.`

nested
  `Names of nested lists contained in a list.
  Player adapters should set this to a list of names of the nested lists
  contained in the requested list. To be used only for mlib requests (see
  PlayerAdapter.request_mlib()).`

class MPRISAdapter(remuco.adapter.PlayerAdapter)

``

Method resolution order:
  MPRISAdapter
  remuco.adapter.PlayerAdapter
  __builtin__.object

Methods defined here:

__init__(self, name, display_name=None, poll=2.5, mime_types=None, rating=False, extra_file_actions=None, extra_playlist_actions=None)

action_files(self, action_id, files, uris)

action_playlist_item(self, action_id, positions, ids)

ctrl_next(self)

ctrl_previous(self)

ctrl_seek(self, direction)

ctrl_toggle_playing(self)

ctrl_toggle_repeat(self)

ctrl_toggle_shuffle(self)

ctrl_volume(self, direction)

poll(self)

request_playlist(self, reply)

start(self)

stop(self)

Methods inherited from remuco.adapter.PlayerAdapter:

action_mlib_item(self, action_id, path, positions, ids)
  `Do an action on one or more items from the player's media library.
  The items are specified redundantly by 'positions' and 'ids' - use
  whatever fits better. If the specified action is not applicable to
  multiple items, then 'positions' and 'ids' are one element lists.
  @param action_id:
  ID of the action to do - this specifies one of the actions passed
  previously to reply_mlib_request() by the keyword 'item_actions'
  @param path:
  the library path that contains the items
  @param positions:
  list of positions to apply the action to
  @param ids:
  list of IDs to apply the action to
  @note: Override if item actions gets passed to reply_mlib_request().`

action_mlib_list(self, action_id, path)
  `Do an action on a list from the player's media library.
  @param action_id:
  ID of the action to do - this specifies one of the actions passed
  previously to reply_mlib_request() by the keyword 'list_actions'
  @param path:
  path specifying the list to apply the action to
  @note: Override if list actions gets passed to reply_mlib_request().`

action_queue_item(self, action_id, positions, ids)
  `Do an action on one or more items from the play queue.
  The items are specified redundantly by 'positions' and 'ids' - use
  whatever fits better. If the specified action is not applicable to
  multiple items, then 'positions' and 'ids' are one element lists.
  @param action_id:
  ID of the action to do - this specifies one of the actions passed
  previously to reply_queue_request() by the keyword 'item_actions'
  @param positions:
  list of positions to apply the action to
  @param ids:
  list of IDs to apply the action to
  @note: Override if item actions gets passed to reply_queue_request().`

action_search_item(self, action_id, positions, ids)
  `Do an action on one or more items from a search result.
  @param action_id:
  ID of the action to do - this specifies one of the actions passed
  previously to reply_search_request() by the keyword 'item_actions'
  @param positions:
  list of positions to apply the action to
  @param ids:
  list of IDs to apply the action to
  @note: Override if list actions gets passed to reply_search_request().`

ctrl_navigate(self, action)
  `Navigate through menus (typically DVD menus).
  @param action:
  A number selecting one of these actions: UP, DOWN, LEFT, RIGHT,
  SELECT, RETURN, TOPMENU (e.g. 0 is UP and 6 is TOPMENU).
  @note: Override if it is possible and makes sense.`

ctrl_rate(self, rating)
  `Rate the currently played item.
  @param rating:
  rating value (int)
  @note: Override if it is possible and makes sense.`

ctrl_tag(self, id, tags)
  `Attach some tags to an item.
  @param id:
  ID of the item to attach the tags to
  @param tags:
  a list of tags
  @note: Tags does not mean ID3 tags or similar. It means the general
  idea of tags (e.g. like used at last.fm).
  @note: Override if it is possible and makes sense.`

ctrl_toggle_fullscreen(self)
  `Toggle full screen mode.
  @note: Override if it is possible and makes sense.`

find_image(self, resource)
  `Find a local art image file related to a resource.
  This method first looks in the resource' folder for typical art image
  files (e.g. 'cover.png', 'front.jpg', ...). If there is no such file it
  then looks into the user's thumbnail directory (~/.thumbnails).
  @param resource:
  resource to find an art image for (may be a file name or URI)
  @keyword prefer_thumbnail:
  True means first search in thumbnails, False means first search in
  the resource' folder
  @return: an image file name (which can be used for update_item()) or
  None if no image file has been found or if 'resource' is not local`

request_mlib(self, reply, path)
  `Request the content of a playlist from the player's media library.
  @param reply:
  a ListReply object
  @param path:
  a path within a player's media library
  If path is an empty list, the root of the library (all top level
  playlists) are requested. Otherwise path is set as illustrated in this
  example:
  Consider a player with a media library structure like this:
  |- Radio
  |- Genres
  |- Jazz
  |- ...
  |- Dynamic
  |- Never played
  |- Played recently
  |- ...
  |- Playlists
  |- Party
  |- Sue's b-day
  |- ...
  |- ...
  If path is the empty list, all top level playlists are requests, e.g.
  ['Radio', 'Genres', 'Dynamic', 'Playlists', ...]. Otherwise path may
  specify a specific level in the library tree, e.g. [ 'Radio' ] or
  [ 'Playlists', 'Party', 'Sue's b-day' ] or etc.
  @note: Override if it is possible and makes sense.`

request_queue(self, reply)
  `Request the content of the play queue.
  @param reply:
  a ListReply object
  @note: Override if it is possible and makes sense.`

request_search(self, reply, query)
  `Request a list of items matching a search query.
  @param reply:
  a ListReply object
  @param query:
  a list of search query values corresponding with the search mask
  specified with keyword 'search_mask' in PlayerAdapter.__init__()
  Example: If search mask was [ 'Artist', 'Title', 'Album' ], then
  a query may look like this: [ 'Blondie', '', 'Best' ]. It is up to
  player adapters how to interpret these values. However, good practice
  is to interpret them as case insensitive, and-connected, non exact
  matching search values. The given example would then reply a list
  with all items where 'Blondie' is contained in the artist field and
  'Best' is contained in the Album field.
  @note: Override if it is possible and makes sense.`

update_item(self, id, info, img)
  `Set currently played item.
  @param id:
  item ID (str)
  @param info:
  meta information (dict)
  @param img:
  image / cover art (either a file name or URI or an instance of
  Image.Image)
  @note: Call to synchronize player state with remote clients.
  @see: find_image() for finding image files for an item.
  @see: remuco.INFO_... for keys to use for 'info'`

update_playback(self, playback)
  `Set the current playback state.
  @param playback:
  playback mode
  @see: remuco.PLAYBACK_...
  @note: Call to synchronize player state with remote clients.`

update_position(self, position, queue=False)
  `Set the current item's position in the playlist or queue.
  @param position:
  position of the currently played item (starting at 0)
  @keyword queue:
  True if currently played item is from the queue, False if it is
  from the currently active playlist
  @note: Call to synchronize player state with remote clients.`

update_progress(self, progress, length)
  `Set the current playback progress.
  @param progress:
  number of currently elapsed seconds
  @keyword length:
  item length in seconds (maximum possible progress value)
  @note: Call to synchronize player state with remote clients.`

update_repeat(self, repeat)
  `Set the current repeat mode.
  @param repeat: True means play indefinitely, False means stop after the
  last playlist item
  @note: Call to synchronize player state with remote clients.`

update_shuffle(self, shuffle)
  `Set the current shuffle mode.
  @param shuffle: True means play in non-linear order, False means play
  in linear order
  @note: Call to synchronize player state with remote clients.`

update_volume(self, volume)
  `Set the current volume.
  @param volume: the volume in percent
  @note: Call to synchronize player state with remote clients.`

Data descriptors inherited from remuco.adapter.PlayerAdapter:

__dict__
  `dictionary for instance variables (if defined)`

__weakref__
  `list of weak references to the object (if defined)`

Data and other attributes inherited from remuco.adapter.PlayerAdapter:

manager = <remuco.manager.NoManager object>

class Manager(__builtin__.object)

``

`Life cycle manager for a stand-alone player adapter.
A manager cares about calling a PlayerAdapter's start and stop methods.
Additionally, because Remuco needs a GLib main loop to run, it sets up and
manages such a loop.
It is intended for player adapters running stand-alone, outside the players
they adapt. A manager is not needed for player adapters realized as a
plugin for a media player. In that case the player's plugin interface
should care about the life cycle of a player adapter (see the Rhythmbox
player adapter as an example).
`

Methods defined here:

__init__(self, pa, dbus_name=None, poll_fn=None)
  `Create a new manager.
  @param pa:
  the PlayerAdapter to manage
  @keyword dbus_name:
  if the player adapter uses DBus to communicate with its player set
  this to the player's well known bus name (see run() for more
  information)
  @keyword poll_fn:
  if DBus is not used, this function may be set for periodic checks
  if the player is running, used to automatically start and stop the
  player adapter
  When neither `dbus_name` nor `poll_fn` is given, the adapter is started
  immediately, assuming the player is running and the adapter is ready to
  work.`

run(self)
  `Activate the manager.
  This method starts the player adapter, runs a main loop (GLib) and
  blocks until SIGINT or SIGTERM arrives or until stop() gets called. If
  this happens the player adapter gets stopped and this method returns.
  If `player_dbus_name` or `poll_fn` has been passed to __init__(), then
  the player adapter does not get started until the player is running
  (according to checks based on the DBus name or poll function). Also the
  adapter gets stopped automatically if the player is not running
  anymore. However, the manager keeps running, i.e. the player adapter
  may get started and stopped multiple times while this method is
  running.`

stop(self)
  `Shut down the manager.
  Stops the manager's main loop and player adapter. As a result a
  previous call to run() will return now. This should be used by player
  adapters when there is a crucial error and restarting the adapter won't
  fix this.`

Data descriptors defined here:

__dict__
  `dictionary for instance variables (if defined)`

__weakref__
  `list of weak references to the object (if defined)`

class PlayerAdapter(__builtin__.object)

``

`Base class for Remuco player adapters.
Remuco player adapters must subclass this class and override certain
methods to implement player specific behavior. Additionally PlayerAdapter
provides methods to interact with Remuco clients. Following is a summary
of all relevant methods, grouped by functionality.
===========================================================================
Methods to extend to manage life cycle
===========================================================================
* start()
* stop()
A PlayerAdapter can be started and stopped with start() and stop().
The same instance of a PlayerAdapter should be startable and stoppable
multiple times.
Subclasses of PlayerAdapter may override these methods as needed but
must always call the super class implementations too!
===========================================================================
Methods to override to control the media player:
===========================================================================
* ctrl_toggle_playing()
* ctrl_toggle_repeat()
* ctrl_toggle_shuffle()
* ctrl_toggle_fullscreen()
* ctrl_next()
* ctrl_previous()
* ctrl_seek()
* ctrl_volume()
* ctrl_rate()
* ctrl_tag()
* ctrl_navigate()
* action_files()
* action_playlist_item()
* action_queue_item()
* action_mlib_item()
* action_mlib_list()
* action_search_item()
Player adapters only need to implement only a *subset* of these
methods - depending on what is possible and what makes sense.
Remuco checks which methods have been overridden and uses this
information to notify Remuco clients about capabilities of player
adapters.
===========================================================================
Methods to override to provide information from the media player:
===========================================================================
* request_playlist()
* request_queue()
* request_mlib()
* request_search()
As above, only override the methods which make sense for the
corresponding media player.
===========================================================================
Methods to call to synchronize media player state information with clients:
===========================================================================
* update_playback()
* update_repeat()
* update_shuffle()
* update_item()
* update_position()
* update_progress()
These methods should be called whenever the corresponding information
has changed in the media player (it is safe to call these methods also
if there actually is no change, internally a change check is done
before sending any data to clients).
Subclasses of PlayerAdapter may override the method poll() to
periodically check a player's state.
===========================================================================
Finally some utility methods:
===========================================================================
* find_image()
`

Methods defined here:

__init__(self, name, playback_known=False, volume_known=False, repeat_known=False, shuffle_known=False, progress_known=False, max_rating=0, poll=2.5, file_actions=None, mime_types=None, search_mask=None)
  `Create a new player adapter and configure its capabilities.
  Just does some early initializations. Real job starts with start().
  @param name:
  name of the media player
  @keyword playback_known:
  indicates if the player's playback state can be provided (see
  update_playback())
  @keyword volume_known:
  indicates if the player's volume can be provided (see
  update_volume())
  @keyword repeat_known:
  indicates if the player's repeat mode can be provided (see
  update_repeat())
  @keyword shuffle_known:
  indicates if the player's shuffle mode can be provided (see
  update_shuffle())
  @keyword progress_known:
  indicates if the player's playback progress can be provided (see
  update_progress())
  @keyword max_rating:
  maximum possible rating value for items
  @keyword poll:
  interval in seconds to call poll()
  @keyword file_actions:
  list of ItemAction which can be applied to files from the local
  file system (actions like play a file or append files to the
  playlist) - this keyword is only relevant if the method
  action_files() gets overridden
  @keyword mime_types:
  list of mime types specifying the files to which the actions given
  by the keyword 'file_actions' can be applied, this may be general
  types like 'audio' or 'video' but also specific types like
  'audio/mp3' or 'video/quicktime' (setting this to None means all
  mime types are supported) - this keyword is only relevant if the
  method action_files() gets overridden
  @keyword search_mask:
  list of fields to search the players library for (e.g. artist,
  genre, any, ...) - if set method request_search() should be
  overridden
  @attention: When overriding, call super class implementation first!`

action_files(self, action_id, files, uris)
  `Do an action on one or more files.
  The files are specified redundantly by 'files' and 'uris' - use
  whatever fits better. If the specified action is not applicable to
  multiple files, then 'files' and 'uris' are one element lists.
  The files in 'files' and 'uris' may be any files from the local file
  system that have one of the mime types specified by the keyword
  'mime_types' in __init__().
  @param action_id:
  ID of the action to do - this specifies one of the actions passed
  previously to __init__() by the keyword 'file_actions'
  @param files:
  list of files to apply the action to (regular path names)
  @param uris:
  list of files to apply the action to (URI notation)
  @note: Override if file item actions gets passed to __init__().`

action_mlib_item(self, action_id, path, positions, ids)
  `Do an action on one or more items from the player's media library.
  The items are specified redundantly by 'positions' and 'ids' - use
  whatever fits better. If the specified action is not applicable to
  multiple items, then 'positions' and 'ids' are one element lists.
  @param action_id:
  ID of the action to do - this specifies one of the actions passed
  previously to reply_mlib_request() by the keyword 'item_actions'
  @param path:
  the library path that contains the items
  @param positions:
  list of positions to apply the action to
  @param ids:
  list of IDs to apply the action to
  @note: Override if item actions gets passed to reply_mlib_request().`

action_mlib_list(self, action_id, path)
  `Do an action on a list from the player's media library.
  @param action_id:
  ID of the action to do - this specifies one of the actions passed
  previously to reply_mlib_request() by the keyword 'list_actions'
  @param path:
  path specifying the list to apply the action to
  @note: Override if list actions gets passed to reply_mlib_request().`

action_playlist_item(self, action_id, positions, ids)
  `Do an action on one or more items from the playlist.
  The items are specified redundantly by 'positions' and 'ids' - use
  whatever fits better. If the specified action is not applicable to
  multiple items, then 'positions' and 'ids' are one element lists.
  @param action_id:
  ID of the action to do - this specifies one of the actions passed
  previously to reply_playlist_request() by the keyword 'item_actions'
  @param positions:
  list of positions to apply the action to
  @param ids:
  list of IDs to apply the action to
  @note: Override if item actions gets passed to reply_playlist_request().`

action_queue_item(self, action_id, positions, ids)
  `Do an action on one or more items from the play queue.
  The items are specified redundantly by 'positions' and 'ids' - use
  whatever fits better. If the specified action is not applicable to
  multiple items, then 'positions' and 'ids' are one element lists.
  @param action_id:
  ID of the action to do - this specifies one of the actions passed
  previously to reply_queue_request() by the keyword 'item_actions'
  @param positions:
  list of positions to apply the action to
  @param ids:
  list of IDs to apply the action to
  @note: Override if item actions gets passed to reply_queue_request().`

action_search_item(self, action_id, positions, ids)
  `Do an action on one or more items from a search result.
  @param action_id:
  ID of the action to do - this specifies one of the actions passed
  previously to reply_search_request() by the keyword 'item_actions'
  @param positions:
  list of positions to apply the action to
  @param ids:
  list of IDs to apply the action to
  @note: Override if list actions gets passed to reply_search_request().`

ctrl_navigate(self, action)
  `Navigate through menus (typically DVD menus).
  @param action:
  A number selecting one of these actions: UP, DOWN, LEFT, RIGHT,
  SELECT, RETURN, TOPMENU (e.g. 0 is UP and 6 is TOPMENU).
  @note: Override if it is possible and makes sense.`

ctrl_next(self)
  `Play the next item.
  @note: Override if it is possible and makes sense.`

ctrl_previous(self)
  `Play the previous item.
  @note: Override if it is possible and makes sense.`

ctrl_rate(self, rating)
  `Rate the currently played item.
  @param rating:
  rating value (int)
  @note: Override if it is possible and makes sense.`

ctrl_seek(self, direction)
  `Seek forward or backward some seconds.
  The number of seconds to seek should be reasonable for the current
  item's length (if known).
  If the progress of the current item is known, it should get
  synchronized immediately with clients by calling update_progress().
  @param direction:
  * -1: seek backward
  * +1: seek forward
  @note: Override if it is possible and makes sense.`

ctrl_tag(self, id, tags)
  `Attach some tags to an item.
  @param id:
  ID of the item to attach the tags to
  @param tags:
  a list of tags
  @note: Tags does not mean ID3 tags or similar. It means the general
  idea of tags (e.g. like used at last.fm).
  @note: Override if it is possible and makes sense.`

ctrl_toggle_fullscreen(self)
  `Toggle full screen mode.
  @note: Override if it is possible and makes sense.`

ctrl_toggle_playing(self)
  `Toggle play and pause.
  @note: Override if it is possible and makes sense.`

ctrl_toggle_repeat(self)
  `Toggle repeat mode.
  @note: Override if it is possible and makes sense.
  @see: update_repeat()`

ctrl_toggle_shuffle(self)
  `Toggle shuffle mode.
  @note: Override if it is possible and makes sense.
  @see: update_shuffle()`

ctrl_volume(self, direction)
  `Adjust volume.
  @param volume:
  * -1: decrease by some percent (5 is a good value)
  * 0: mute volume
  * +1: increase by some percent (5 is a good value)
  @note: Override if it is possible and makes sense.`

find_image(self, resource)
  `Find a local art image file related to a resource.
  This method first looks in the resource' folder for typical art image
  files (e.g. 'cover.png', 'front.jpg', ...). If there is no such file it
  then looks into the user's thumbnail directory (~/.thumbnails).
  @param resource:
  resource to find an art image for (may be a file name or URI)
  @keyword prefer_thumbnail:
  True means first search in thumbnails, False means first search in
  the resource' folder
  @return: an image file name (which can be used for update_item()) or
  None if no image file has been found or if 'resource' is not local`

poll(self)
  `Does nothing by default.
  If player adapters override this method, it gets called periodically
  in the interval specified by the keyword 'poll' in __init__().
  A typical use case of this method is to detect the playback progress of
  the current item and then call update_progress(). It can also be used
  to poll any other player state information when a player does not
  provide signals for all or certain state information changes.`

request_mlib(self, reply, path)
  `Request the content of a playlist from the player's media library.
  @param reply:
  a ListReply object
  @param path:
  a path within a player's media library
  If path is an empty list, the root of the library (all top level
  playlists) are requested. Otherwise path is set as illustrated in this
  example:
  Consider a player with a media library structure like this:
  |- Radio
  |- Genres
  |- Jazz
  |- ...
  |- Dynamic
  |- Never played
  |- Played recently
  |- ...
  |- Playlists
  |- Party
  |- Sue's b-day
  |- ...
  |- ...
  If path is the empty list, all top level playlists are requests, e.g.
  ['Radio', 'Genres', 'Dynamic', 'Playlists', ...]. Otherwise path may
  specify a specific level in the library tree, e.g. [ 'Radio' ] or
  [ 'Playlists', 'Party', 'Sue's b-day' ] or etc.
  @note: Override if it is possible and makes sense.`

request_playlist(self, reply)
  `Request the content of the currently active playlist.
  @param reply:
  a ListReply object
  @note: Override if it is possible and makes sense.`

request_queue(self, reply)
  `Request the content of the play queue.
  @param reply:
  a ListReply object
  @note: Override if it is possible and makes sense.`

request_search(self, reply, query)
  `Request a list of items matching a search query.
  @param reply:
  a ListReply object
  @param query:
  a list of search query values corresponding with the search mask
  specified with keyword 'search_mask' in PlayerAdapter.__init__()
  Example: If search mask was [ 'Artist', 'Title', 'Album' ], then
  a query may look like this: [ 'Blondie', '', 'Best' ]. It is up to
  player adapters how to interpret these values. However, good practice
  is to interpret them as case insensitive, and-connected, non exact
  matching search values. The given example would then reply a list
  with all items where 'Blondie' is contained in the artist field and
  'Best' is contained in the Album field.
  @note: Override if it is possible and makes sense.`

start(self)
  `Start the player adapter.
  @attention: When overriding, call super class implementation first!`

stop(self)
  `Shutdown the player adapter.
  Disconnects all clients and shuts down the Bluetooth and WiFi server.
  Also ignores any subsequent calls to an update or reply method (e.g.
  update_volume(), ..., reply_playlist_request(), ...).
  @note: The same player adapter instance can be started again with
  start().
  @attention: When overriding, call super class implementation first!`

update_item(self, id, info, img)
  `Set currently played item.
  @param id:
  item ID (str)
  @param info:
  meta information (dict)
  @param img:
  image / cover art (either a file name or URI or an instance of
  Image.Image)
  @note: Call to synchronize player state with remote clients.
  @see: find_image() for finding image files for an item.
  @see: remuco.INFO_... for keys to use for 'info'`

update_playback(self, playback)
  `Set the current playback state.
  @param playback:
  playback mode
  @see: remuco.PLAYBACK_...
  @note: Call to synchronize player state with remote clients.`

update_position(self, position, queue=False)
  `Set the current item's position in the playlist or queue.
  @param position:
  position of the currently played item (starting at 0)
  @keyword queue:
  True if currently played item is from the queue, False if it is
  from the currently active playlist
  @note: Call to synchronize player state with remote clients.`

update_progress(self, progress, length)
  `Set the current playback progress.
  @param progress:
  number of currently elapsed seconds
  @keyword length:
  item length in seconds (maximum possible progress value)
  @note: Call to synchronize player state with remote clients.`

update_repeat(self, repeat)
  `Set the current repeat mode.
  @param repeat: True means play indefinitely, False means stop after the
  last playlist item
  @note: Call to synchronize player state with remote clients.`

update_shuffle(self, shuffle)
  `Set the current shuffle mode.
  @param shuffle: True means play in non-linear order, False means play
  in linear order
  @note: Call to synchronize player state with remote clients.`

update_volume(self, volume)
  `Set the current volume.
  @param volume: the volume in percent
  @note: Call to synchronize player state with remote clients.`

Data descriptors defined here:

__dict__
  `dictionary for instance variables (if defined)`

__weakref__
  `list of weak references to the object (if defined)`

Data and other attributes defined here:

manager = <remuco.manager.NoManager object>

Data

``

INFO_ALBUM = 'album'
INFO_ARTIST = 'artist'
INFO_GENRE = 'genre'
INFO_LENGTH = 'length'
INFO_RATING = 'rating'
INFO_TAGS = 'tags'
INFO_TITLE = 'title'
INFO_YEAR = 'year'
MIMETYPES_AUDIO = ('audio', 'application/ogg')
MIMETYPES_AV = ('audio', 'application/ogg', 'video')
MIMETYPES_VIDEO = ('video',)
PLAYBACK_PAUSE = 1
PLAYBACK_PLAY = 2
PLAYBACK_STOP = 0
__all__ = ['PlayerAdapter', 'ListReply', 'MPRISAdapter', 'ItemAction', 'ListAction', 'Manager', 'Config', 'INFO_ALBUM', 'INFO_ARTIST', 'INFO_GENRE', 'INFO_LENGTH', 'INFO_RATING', 'INFO_TAGS', 'INFO_TITLE', 'INFO_YEAR', 'PLAYBACK_PAUSE', 'PLAYBACK_PLAY', 'PLAYBACK_STOP', 'MIMETYPES_AUDIO', 'MIMETYPES_VIDEO', ...]
__version__ = '0.9.6'