Adding support for other stream handlers in hopes to support Maemo 4.1
[watersofshiloah] / src / stream_osso.py
1 import logging
2
3 import gobject
4 import dbus
5
6 import util.misc as misc_utils
7
8
9 _moduleLogger = logging.getLogger(__name__)
10
11
12 class SimplePlayer(gobject.GObject):
13
14         STATE_PLAY = "play"
15         STATE_PAUSE = "pause"
16         STATE_STOP = "stop"
17
18         __gsignals__ = {
19                 'state-change' : (
20                         gobject.SIGNAL_RUN_LAST,
21                         gobject.TYPE_NONE,
22                         (gobject.TYPE_STRING, ),
23                 ),
24                 'eof' : (
25                         gobject.SIGNAL_RUN_LAST,
26                         gobject.TYPE_NONE,
27                         (gobject.TYPE_STRING, ),
28                 ),
29                 'error' : (
30                         gobject.SIGNAL_RUN_LAST,
31                         gobject.TYPE_NONE,
32                         (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT),
33                 ),
34         }
35
36         _SERVICE_NAME = "com.nokia.osso_media_server"
37         _OBJECT_PATH = "/com/nokia/osso_media_server"
38         _AUDIO_INTERFACE_NAME = "com.nokia.osso_media_server.music"
39
40         def __init__(self):
41                 gobject.GObject.__init__(self)
42                 #Fields
43                 self._state = self.STATE_STOP
44                 self._uri = ""
45                 self._elapsed = 0
46                 self._duration = 0
47
48                 #Event callbacks
49                 self.on_playing_done = on_playing_done
50
51                 session_bus = dbus.SessionBus()
52
53                 # Get the osso-media-player proxy object
54                 oms_object = session_bus.get_object(
55                         self._SERVICE_NAME,
56                         self._OBJECT_PATH,
57                         introspect=False,
58                         follow_name_owner_changes=True,
59                 )
60                 # Use the audio interface
61                 oms_audio_interface = dbus.Interface(
62                         oms_object,
63                         self._AUDIO_INTERFACE_NAME,
64                 )
65                 self._audioProxy = oms_audio_interface
66
67                 self._audioProxy.connect_to_signal("state_changed", self._on_state_changed)
68                 self._audioProxy.connect_to_signal("end_of_stream", self._on_end_of_stream)
69
70                 error_signals = [
71                         "no_media_selected",
72                         "file_not_found",
73                         "type_not_found",
74                         "unsupported_type",
75                         "gstreamer",
76                         "dsp",
77                         "device_unavailable",
78                         "corrupted_file",
79                         "out_of_memory",
80                         "audio_codec_not_supported",
81                 ]
82                 for error in error_signals:
83                         self._audioProxy.connect_to_signal(error, self._on_error)
84
85         @property
86         def playing(self):
87                 return self.state == self.STATE_PLAY
88
89         @property
90         def has_file(self):
91                 return 0 < len(self._uri)
92
93         @property
94         def state(self):
95                 return self._state
96
97         def set_file(self, uri):
98                 if self._uri != uri:
99                         self._invalidate_cache()
100                 if self.state != self.STATE_STOP:
101                         self.stop()
102
103                 self._uri = uri
104                 self._audioProxy.set_media_location(self._uri)
105
106         def play(self):
107                 if self.state == self.STATE_PLAY:
108                         _moduleLogger.info("Already play")
109                         return
110                 _moduleLogger.info("Play")
111                 self._audioProxy.play()
112                 self._state = self.STATE_PLAY
113                 self.emit("state-change", self.STATE_PLAY)
114
115         def pause(self):
116                 if self.state == self.STATE_PAUSE:
117                         _moduleLogger.info("Already pause")
118                         return
119                 _moduleLogger.info("Pause")
120                 self._audioProxy.pause()
121                 self._state = self.STATE_PAUSE
122                 self.emit("state-change", self.STATE_PLAY)
123
124         def stop(self):
125                 if self.state == self.STATE_STOP:
126                         _moduleLogger.info("Already stop")
127                         return
128                 self._audioProxy.stop()
129                 _moduleLogger.info("Stopped")
130                 self._state = self.STATE_STOP
131                 self.emit("state-change", self.STATE_STOP)
132
133         @property
134         def elapsed(self):
135                 pos_info = self._audioProxy.get_position()
136                 if isinstance(pos_info, tuple):
137                         self._elapsed, self._duration = pos_info
138                 return self._elapsed
139
140         @property
141         def duration(self):
142                 pos_info = self._audioProxy.get_position()
143                 if isinstance(pos_info, tuple):
144                         self._elapsed, self._duration = pos_info
145                 return self._duration
146
147         def seek_time(self, ns):
148                 _moduleLogger.debug("Seeking to: %s", ns)
149                 self._audioProxy.seek( dbus.Int32(1), dbus.Int32(ns) )
150
151         def _invalidate_cache(self):
152                 self._elapsed = 0
153                 self._duration = 0
154
155         @misc_utils.log_exception(_moduleLogger)
156         def _on_error(self, *args):
157                 err, debug = "", repr(args)
158                 _moduleLogger.error("Error: %s, (%s)" % (err, debug))
159                 self.emit("error", err, debug)
160
161         @misc_utils.log_exception(_moduleLogger)
162         def _on_end_of_stream(self, *args):
163                 self._state = self.STATE_STOP
164                 self.emit("eof", self._uri)
165
166         @misc_utils.log_exception(_moduleLogger)
167         def _on_state_changed(self, state):
168                 # @todo Switch to updating/emitting state based on this
169                 _moduleLogger.info("State: %s", state)
170
171
172 gobject.type_register(GSTStream)