Fixing a Maemo 5 issue
[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 Stream(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                 session_bus = dbus.SessionBus()
49
50                 # Get the osso-media-player proxy object
51                 oms_object = session_bus.get_object(
52                         self._SERVICE_NAME,
53                         self._OBJECT_PATH,
54                         introspect=False,
55                         follow_name_owner_changes=True,
56                 )
57                 # Use the audio interface
58                 oms_audio_interface = dbus.Interface(
59                         oms_object,
60                         self._AUDIO_INTERFACE_NAME,
61                 )
62                 self._audioProxy = oms_audio_interface
63
64                 self._audioProxy.connect_to_signal("state_changed", self._on_state_changed)
65                 self._audioProxy.connect_to_signal("end_of_stream", self._on_end_of_stream)
66
67                 error_signals = [
68                         "no_media_selected",
69                         "file_not_found",
70                         "type_not_found",
71                         "unsupported_type",
72                         "gstreamer",
73                         "dsp",
74                         "device_unavailable",
75                         "corrupted_file",
76                         "out_of_memory",
77                         "audio_codec_not_supported",
78                 ]
79                 for error in error_signals:
80                         self._audioProxy.connect_to_signal(error, self._on_error)
81
82         @property
83         def playing(self):
84                 return self.state == self.STATE_PLAY
85
86         @property
87         def has_file(self):
88                 return 0 < len(self._uri)
89
90         @property
91         def state(self):
92                 return self._state
93
94         def set_file(self, uri):
95                 if self._uri != uri:
96                         self._invalidate_cache()
97                 if self.state != self.STATE_STOP:
98                         self.stop()
99
100                 self._uri = uri
101                 self._audioProxy.set_media_location(self._uri)
102
103         def play(self):
104                 if self.state == self.STATE_PLAY:
105                         _moduleLogger.info("Already play")
106                         return
107                 _moduleLogger.info("Play")
108                 self._audioProxy.play()
109                 self._state = self.STATE_PLAY
110                 self.emit("state-change", self.STATE_PLAY)
111
112         def pause(self):
113                 if self.state == self.STATE_PAUSE:
114                         _moduleLogger.info("Already pause")
115                         return
116                 _moduleLogger.info("Pause")
117                 self._audioProxy.pause()
118                 self._state = self.STATE_PAUSE
119                 self.emit("state-change", self.STATE_PLAY)
120
121         def stop(self):
122                 if self.state == self.STATE_STOP:
123                         _moduleLogger.info("Already stop")
124                         return
125                 self._audioProxy.stop()
126                 _moduleLogger.info("Stopped")
127                 self._state = self.STATE_STOP
128                 self.emit("state-change", self.STATE_STOP)
129
130         @property
131         def elapsed(self):
132                 pos_info = self._audioProxy.get_position()
133                 if isinstance(pos_info, tuple):
134                         self._elapsed, self._duration = pos_info
135                 return self._elapsed
136
137         @property
138         def duration(self):
139                 pos_info = self._audioProxy.get_position()
140                 if isinstance(pos_info, tuple):
141                         self._elapsed, self._duration = pos_info
142                 return self._duration
143
144         def seek_time(self, ns):
145                 _moduleLogger.debug("Seeking to: %s", ns)
146                 self._audioProxy.seek( dbus.Int32(1), dbus.Int32(ns) )
147
148         def _invalidate_cache(self):
149                 self._elapsed = 0
150                 self._duration = 0
151
152         @misc_utils.log_exception(_moduleLogger)
153         def _on_error(self, *args):
154                 err, debug = "", repr(args)
155                 _moduleLogger.error("Error: %s, (%s)" % (err, debug))
156                 self.emit("error", err, debug)
157
158         @misc_utils.log_exception(_moduleLogger)
159         def _on_end_of_stream(self, *args):
160                 self._state = self.STATE_STOP
161                 self.emit("eof", self._uri)
162
163         @misc_utils.log_exception(_moduleLogger)
164         def _on_state_changed(self, state):
165                 # @todo Switch to updating/emitting state based on this
166                 _moduleLogger.info("State: %s", state)
167
168
169 gobject.type_register(Stream)