diff options
Diffstat (limited to 'pydora/audio_backend.py')
-rw-r--r-- | pydora/audio_backend.py | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/pydora/audio_backend.py b/pydora/audio_backend.py index 9599771..f92998a 100644 --- a/pydora/audio_backend.py +++ b/pydora/audio_backend.py | |||
@@ -2,6 +2,7 @@ import os | |||
2 | import time | 2 | import time |
3 | import fcntl | 3 | import fcntl |
4 | import select | 4 | import select |
5 | import socket | ||
5 | 6 | ||
6 | from pandora.py2compat import which | 7 | from pandora.py2compat import which |
7 | from .utils import iterate_forever, SilentPopen | 8 | from .utils import iterate_forever, SilentPopen |
@@ -141,6 +142,13 @@ class BasePlayer(object): | |||
141 | self._process = SilentPopen(self._cmd) | 142 | self._process = SilentPopen(self._cmd) |
142 | self._post_start() | 143 | self._post_start() |
143 | 144 | ||
145 | def _get_select_readers(self): | ||
146 | """Return a list of file-like objects for reading | ||
147 | |||
148 | Will be passed to select() to poll for readers. | ||
149 | """ | ||
150 | return [self._control_channel, self._process.stdout] | ||
151 | |||
144 | def play(self, song): | 152 | def play(self, song): |
145 | """Play a new song from a Pandora model | 153 | """Play a new song from a Pandora model |
146 | 154 | ||
@@ -159,7 +167,7 @@ class BasePlayer(object): | |||
159 | self._loop_hook() | 167 | self._loop_hook() |
160 | 168 | ||
161 | readers, _, _ = select.select( | 169 | readers, _, _ = select.select( |
162 | [self._control_channel, self._process.stdout], [], [], 1) | 170 | self._get_select_readers(), [], [], 1) |
163 | 171 | ||
164 | for handle in readers: | 172 | for handle in readers: |
165 | if handle.fileno() == self._control_fd: | 173 | if handle.fileno() == self._control_fd: |
@@ -272,3 +280,35 @@ class VLCPlayer(BasePlayer): | |||
272 | if (time.time() - self._last_poll) >= self.POLL_INTERVAL: | 280 | if (time.time() - self._last_poll) >= self.POLL_INTERVAL: |
273 | self._send_cmd("status") | 281 | self._send_cmd("status") |
274 | self._last_poll = time.time() | 282 | self._last_poll = time.time() |
283 | |||
284 | |||
285 | class RemoteVLC(VLCPlayer): | ||
286 | |||
287 | def __init__(self, host, port, callbacks, control_channel): | ||
288 | self._connect_to = (host, int(port)) | ||
289 | self._control_sock = None | ||
290 | super(RemoteVLC, self).__init__(callbacks, control_channel) | ||
291 | |||
292 | def _get_select_readers(self): | ||
293 | return [self._control_channel, self._control_sock] | ||
294 | |||
295 | def _send_cmd(self, cmd): | ||
296 | self._control_sock.sendall("{}\n".format(cmd).encode("utf-8")) | ||
297 | |||
298 | def _read_from_process(self, handle): | ||
299 | return handle.recv(self.CHUNK_SIZE).strip() | ||
300 | |||
301 | def _ensure_started(self): | ||
302 | if not self._control_sock: | ||
303 | self._control_sock = socket.create_connection(self._connect_to) | ||
304 | self._control_sock.setblocking(False) | ||
305 | |||
306 | def _find_path(self): | ||
307 | try: | ||
308 | self._ensure_started() | ||
309 | except socket.error: | ||
310 | raise PlayerUnusable("Unable to connect to VLC") | ||
311 | |||
312 | def _post_start(self): | ||
313 | # This is a NOOP for network VLC | ||
314 | pass | ||