1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 __maintainer__ = 'Benjamin Kampmann <benjamin@fluendo.com>'
18
19 from elisa.base_components.player_engine import PlayerEngine
20 from elisa.core.player import PlayerLoading, \
21 PlayerPlaying, \
22 PlayerPausing, \
23 PlayerStopping, \
24 PlayerError, \
25 PlayerBuffering, \
26 NewBaseTime, \
27 NewClock, \
28 STATES
29
30 from elisa.core.media_uri import MediaUri
31
32 import pygst
33 pygst.require('0.10')
34 import gst
35
36 import urllib
37
39 """
40 This class implements a player using playbin to access the uris
41 """
42
43 uri_schemes = {'http' : 150, 'smb' : 150, 'file': 150, 'ftp' : 150,
44 'sftp' : 150, 'cdda' : 150, 'mms': 150, 'daap': 150}
45
60
61
63 schemes = {}
64 reg = gst.registry_get_default()
65 plugins = reg.get_plugin_list()
66 try:
67 for plugin in plugins:
68 features = reg.get_feature_list_by_plugin(plugin.get_name())
69 for feature in features:
70 if isinstance(feature, gst.ElementFactory) and \
71 feature.get_uri_type():
72 protocols = feature.get_uri_protocols()
73 for protocol in protocols:
74 schemes[str(protocol)] = 150
75 except AttributeError:
76
77
78
79
80 schemes = {'http' : 150, 'smb' : 150, 'file': 150, 'ftp' : 150,
81 'sftp' : 150, 'cdda' : 150,}
82
83 self.warning("Could not find out all uris which are supported by"
84 " playbin. Using statically file, smb, ftp,"
85 " sftp, cdda and http only! \n If you have"
86 " problems with playing this uri-schemes, you"
87 " might install the latest gstreamer and python-"
88 "bindings from cvs.")
89 return schemes
90
91
94
96
97 if sink == None and self._pipeline:
98 self._pipeline.set_state(gst.STATE_NULL)
99 del self._pipeline
100 self._pipeline = None
101
102 self._audiosink = sink
103
104 if self._pipeline:
105 self._pipeline.set_property('audio-sink', self._audiosink)
106
107 if self._pipeline:
108 self._pipeline.set_property('audio-sink', self._audiosink)
109
111 self._visualisation = new_visualisation
112 if self._pipeline:
113 self._pipeline.set_property('vis-plugin', self._visualisation)
114
116 return self._visualisation
117
120
122 """
123 Set the videosink to sink.
124 If the sink none and there was a video-sink before, destroy the
125 pipeline as well and make a new one!
126 """
127 if sink == None:
128 self._pipeline.set_state(gst.STATE_NULL)
129 del self._pipeline
130 self._pipeline = None
131
132 self._videosink = sink
133 if self._pipeline:
134 self._pipeline.set_property('video-sink', self._video_sink)
135
136
138 if not self._pipeline:
139 self._create_pipeline()
140
141 self._current_uri = uri
142 self._pipeline.set_state(gst.STATE_READY)
143 self._state = STATES.STOPPED
144 states = self._pipeline.get_state(3000 * gst.MSECOND)
145
146 if states[1] == gst.STATE_READY:
147
148
149 quoted_uri = MediaUri(uri)
150 quoted_uri.path = urllib.quote(uri.path.encode('utf8'))
151
152 self.debug("Loading %r", str(quoted_uri))
153
154 self._pipeline.set_property('uri', str(quoted_uri))
155
156 self.debug("Ready to play %r", str(quoted_uri))
157
159 self._pipeline.set_property('volume', volume)
160
162 return self._pipeline.get_property('volume')
163
164
165
166
168 self._pipeline = gst.element_factory_make('playbin', 'playbin')
169 pbus = self._pipeline.get_bus()
170 pbus.connect("message", self._bus_message_cb)
171 pbus.add_signal_watch()
172
173 self._pipeline.set_property('video-sink', self._videosink)
174 self._pipeline.set_property('audio-sink', self._audiosink)
175 self._pipeline.set_property('vis-plugin', self._visualisation)
176 self._pipeline.set_state(gst.STATE_READY)
177
179
180 if message.type == gst.MESSAGE_EOS:
181 self._on_eos()
182 elif message.type == gst.MESSAGE_BUFFERING:
183
184 try:
185 percent = message.parse_buffering()
186 if percent < 100:
187 self.pause()
188 else:
189 self.play()
190
191 self._send_msg(PlayerBuffering(percent))
192 except AttributeError:
193 self.info("You won't get a buffering message. This is only"
194 " working with the python bindings >= 0.10.8!")
195 elif message.type == gst.MESSAGE_ERROR:
196 err, msg = message.parse_error()
197 self.warning("Gstreamer %s:%s" % (err, msg))
198 self._send_msg(PlayerError((err, msg)))
199 self._pipeline.set_state(gst.STATE_READY)
200
201 elif message.type == gst.MESSAGE_STATE_CHANGED:
202 old_state, new_state, pending = message.parse_state_changed()
203 if new_state == gst.STATE_PLAYING and message.src == self._pipeline:
204
205 base_time = self._pipeline.get_base_time()
206 self._send_msg(NewBaseTime(base_time))
207 if self._state != STATES.PLAYING:
208 self._state = STATES.PLAYING
209 self._send_msg(PlayerPlaying())
210 elif new_state == gst.STATE_NULL or \
211 new_state == gst.STATE_READY:
212 self._state = STATES.STOPPED
213 elif new_state == gst.STATE_PAUSED:
214 self._state = STATES.PAUSED
215
216 elif message.type == gst.MESSAGE_NEW_CLOCK:
217
218 clock = message.parse_new_clock()
219 self._send_msg(NewClock(clock))
220
226