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
23 from panucci
.services
import ForwardingObservableService
24 from panucci
.dbusinterface
import interface
25 from panucci
import util
27 class PanucciPlayer(ForwardingObservableService
):
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
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
)
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
62 if self
.__player
is not None:
63 return getattr(self
.__player
, attr
)
65 self
.__log
.critical("No player available")
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
):
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.
88 pos
, dur
= self
.get_position_duration()
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)
106 interface
.PlaybackStopped(self
._start
_position
, pos_sec
, dur_sec
, self
.current_uri
)
108 def on_stop_requested(self
):
111 def on_reset_playlist(self
):
113 self
.__player
.reset_position_duration()
115 def on_player_error(self
, msg
):
116 self
.__log
.error("Error: %s", msg
)