2 Minimal VLC VLM client for AceProxy. Client class.
10 from vlcmessages import *
13 class VlcException(Exception):
16 Exception from VlcClient
21 class VlcClient(object):
28 self, host='127.0.0.1', port=4212, password='admin', connect_timeout=10,
29 result_timeout=10, out_port=8081):
31 self._recvbuffer = None
33 self._out_port = out_port
37 self._resulttimeout = result_timeout
39 self._shuttingDown = gevent.event.Event()
40 # Authentication done event
41 self._auth = gevent.event.AsyncResult()
43 self._resultlock = gevent.coros.RLock()
45 self._result = gevent.event.AsyncResult()
49 self._password = password
52 logger = logging.getLogger('VlcClient_init')
56 self._socket = telnetlib.Telnet(host, port, connect_timeout)
57 logger.debug("Successfully connected with VLC socket!")
58 except Exception as e:
60 "Socket creation error! VLC is not running? ERROR: " + repr(e))
62 # Spawning recvData greenlet
63 gevent.spawn(self._recvData)
66 # Waiting for authentication event
68 if self._auth.get(timeout=self._resulttimeout) == False:
69 errmsg = "Authentication error"
71 raise VlcException(errmsg)
72 except gevent.Timeout:
73 errmsg = "Authentication timeout"
75 raise VlcException(errmsg)
78 # Destructor just calls destroy() method
83 logger = logging.getLogger("VlcClient_destroy")
85 if self._shuttingDown.isSet():
86 # Already in the middle of destroying
89 # If socket is still alive (connected)
92 logger.debug("Destroying VlcClient...")
93 self._write(VlcMessage.request.SHUTDOWN)
94 # Set shuttingDown flag for recvData
95 self._shuttingDown.set()
97 # Ignore exceptions on destroy
100 def _write(self, message):
102 logger = logging.getLogger("VlcClient_write")
104 # Return if in the middle of destroying
105 if self._shuttingDown.isSet():
110 logger.debug('VLC command: ' + message)
111 self._socket.write(message + "\r\n")
112 except EOFError as e:
113 raise VlcException("Vlc Write error! ERROR: " + repr(e))
115 def _broadcast(self, brtype, stream_name, input=None, muxer='ts', pre_access='', qtype='default'):
116 if self._shuttingDown.isSet():
119 # Start/stop broadcast with VLC
122 broadcast = 'startBroadcast'
124 broadcast = 'stopBroadcast'
126 logger = logging.getLogger("VlcClient_" + broadcast)
128 self._result = gevent.event.AsyncResult()
130 self._resultlock.acquire()
131 # Write message to VLC socket
133 msg = VlcMessage.request.startBroadcast(stream_name, input, self._out_port, muxer, pre_access, qtype)
136 self._write(VlcMessage.request.stopBroadcast(stream_name))
140 result = self._result.get(timeout=self._resulttimeout)
142 logger.error(broadcast + " error")
143 raise VlcException(broadcast + " error")
144 except gevent.Timeout:
145 logger.error(broadcast + " result timeout")
146 raise VlcException(broadcast + " result timeout")
148 self._resultlock.release()
151 logger.debug("Broadcast started")
153 logger.debug("Broadcast stopped")
155 def startBroadcast(self, stream_name, input, muxer='ts', pre_access='', qtype='default'):
156 logger = logging.getLogger("VlcClient_startBroadcast")
157 logger.debug("Starting broadcast......")
158 return self._broadcast(True, stream_name, input, muxer, pre_access, qtype)
160 def stopBroadcast(self, stream_name):
161 return self._broadcast(False, stream_name)
163 def pauseBroadcast(self, stream_name):
164 return self._write(VlcMessage.request.pauseBroadcast(stream_name))
166 def playBroadcast(self, stream_name):
167 return self._write(VlcMessage.request.playBroadcast(stream_name))
171 logger = logging.getLogger("VlcClient_recvData")
176 self._recvbuffer = self._socket.read_until("\n")
177 # Stripping "> " from VLC
178 self._recvbuffer = self._recvbuffer.lstrip("> ")
180 # If something happened during read, abandon reader
181 if not self._shuttingDown.isSet():
182 logger.error("Exception at socket read")
183 self._shuttingDown.set()
186 # Parsing everything only if the string is not empty
189 # First line (VLC version)
190 self._vlcver = self._recvbuffer.strip()
191 # Send password here since PASSWORD doesn't have \n
192 self._write(self._password)
194 elif self._recvbuffer.startswith(VlcMessage.response.SHUTDOWN):
195 # Exit from this loop
196 logger.debug("Got SHUTDOWN from VLC")
199 elif self._recvbuffer.startswith(VlcMessage.response.WRONGPASS):
201 logger.error("Wrong VLC password!")
202 self._auth.set(False)
205 elif self._recvbuffer.startswith(VlcMessage.response.AUTHOK):
207 logger.info("Authentication successful")
210 elif VlcMessage.response.BROADCASTEXISTS in self._recvbuffer:
211 # Broadcast already exists
212 logger.error("Broadcast already exists!")
213 self._result.set(False)
215 elif VlcMessage.response.STOPERR in self._recvbuffer:
216 # Media unknown (stopping non-existent stream)
217 logger.error("Broadcast does not exist!")
218 self._result.set(False)
220 # Do not move this before error handlers!
221 elif self._recvbuffer.startswith(VlcMessage.response.STARTOK):
223 logger.debug("Broadcast started")
224 self._result.set(True)
226 elif self._recvbuffer.startswith(VlcMessage.response.STOPOK):
228 logger.debug("Broadcast stopped")
229 self._result.set(True)