Debian packaging for 0.99.3 on Fremantle
[panucci.git] / src / panucci / player.py
blobbb25961374477e0ecd7c6125146c86a5599e3f05
1 # -*- coding: utf-8 -*-
3 # This file is part of Panucci.
4 # Copyright (c) 2008-2011 The Panucci Project
6 # Panucci is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # Panucci is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Panucci. If not, see <http://www.gnu.org/licenses/>.
19 from __future__ import absolute_import
21 import logging
23 from panucci.services import ForwardingObservableService
24 from panucci.dbusinterface import interface
25 from panucci import util
27 class PanucciPlayer(ForwardingObservableService):
28 """
29 A proxy object which adds a layer of abstraction between all the different
30 backends. It picks the right backend for the job and forwards signals from
31 them.
32 """
33 signals = [ "playing", "paused", "stopped", "eof" ]
35 def __init__(self, config):
36 self.__log = logging.getLogger('panucci.player.PanucciPlayer')
37 ForwardingObservableService.__init__(self, self.signals, self.__log)
38 self.config = config
40 if self.config.get("options", "backend") == "gstreamer":
41 from panucci.backends.gstreamer import Player
42 self.__player = Player()
44 self.__initialized = False
45 self._start_position = 0
47 # Forward the following signals
48 self.forward(self.__player, [ "playing", "paused", "stopped", "eof" ], PanucciPlayer)
50 #self.__player.register( "playing", self.on_playing )
51 self.__player.register( "paused", self.on_paused )
52 self.__player.register( "stopped", self.on_stopped )
53 self.__player.register( "eof", self.on_stopped )
54 self.__player.register( "error", self.on_player_error )
56 def __getattr__(self, attr):
57 """ If the attribute isn't found in this object, get it from
58 the player object. This makes proxying function calls simple
59 and transparent.
60 """
62 if self.__player is not None:
63 return getattr(self.__player, attr)
64 else:
65 self.__log.critical("No player available")
66 raise AttributeError
68 def do_seek(self, from_beginning=None, from_current=None, percent=None):
69 pos, dur = self.get_position_duration()
70 pos_sec = max(0, pos / 10**9)
71 dur_sec = max(0, dur / 10**9)
73 if self.playing and self.current_uri:
74 interface.PlaybackStopped(self._start_position, pos_sec, dur_sec, self.current_uri)
76 # Hand over the seek command to the backend
77 return self.__player.do_seek(from_beginning, from_current, percent)
79 def on_playing(self, seek_to):
80 """
81 Used to seek to the correct position once the file has started
82 playing. This has to be done once the player is ready because
83 certain player backends can't seek in any state except playing.
84 """
85 if seek_to > 0:
86 self._seek(seek_to)
88 pos, dur = self.get_position_duration()
89 pos_sec = pos / 10**9
90 dur_sec = dur / 10**9
92 interface.PlaybackStarted(pos_sec, self.current_uri)
93 self._start_position = pos_sec
95 def on_paused(self, *args):
96 self.on_stopped_paused()
98 def on_stopped(self, *args):
99 self.on_stopped_paused()
101 def on_stopped_paused(self):
102 pos, dur = self.get_position_duration()
103 pos_sec = max(0, pos / 10**9)
104 dur_sec = max(0, dur / 10**9)
105 if self.current_uri:
106 interface.PlaybackStopped(self._start_position, pos_sec, dur_sec, self.current_uri)
108 def on_stop_requested(self):
109 self.stop()
111 def on_reset_playlist(self):
112 self.stop(True)
113 self.__player.reset_position_duration()
115 def on_player_error(self, msg):
116 self.__log.error("Error: %s", msg)