cmd = 'pause' if player.state == PlayerState.Playing else 'play'
if cmd == 'power' and cmd_args == 'toggle':
cmd_args = 'off' if player.powered else 'on'
- if cmd == 'volume' and cmd_args == 'up':
+ if cmd == 'volume' and (cmd_args == 'up' or '+' in cmd_args):
cmd_args = player.volume_level + 2
- elif cmd == 'volume' and cmd_args == 'down':
+ elif cmd == 'volume' and (cmd_args == 'down' or '-' in cmd_args):
cmd_args = player.volume_level - 2
# redirect playlist related commands to parent player
if player.group_parent and cmd not in ['power', 'volume', 'mute']:
self.buffer = b''
self.last_msg_received = 0
self.supported_musicproviders = ['http']
+
# start slimproto server
mass.event_loop.create_task(asyncio.start_server(self.__handle_socket_client, '0.0.0.0', 3483))
# setup discovery
family=socket.AF_INET, reuse_address=True, reuse_port=True,
allow_broadcast=True)
mass.event_loop.create_task(listen)
-
### Provider specific implementation #####
self._lmsplayers[lms_player.player_id] = lms_player
asyncio.create_task(self.__handle_player_event(lms_player.player_id, event, event_data))
- @run_periodic(5)
- async def send_heartbeat():
- try:
+ try:
+ @run_periodic(5)
+ async def send_heartbeat():
timestamp = int(time.time())
data = lms_player.pack_stream(b"t", replayGain=timestamp, flags=0)
lms_player.send_frame(b"strm", data)
- except RuntimeError:
- reader.close()
- lms_player.send_frame = send_frame
- lms_player.send_event = handle_event
- heartbeat_task = asyncio.create_task(send_heartbeat())
-
- # keep reading bytes from the socket
- while True:
- data = await reader.read(64)
- if data:
- lms_player.dataReceived(data)
- else:
- break
+ lms_player.send_frame = send_frame
+ lms_player.send_event = handle_event
+ heartbeat_task = asyncio.create_task(send_heartbeat())
+
+ # keep reading bytes from the socket
+ while True:
+ data = await reader.read(64)
+ if data:
+ lms_player.dataReceived(data)
+ else:
+ break
+ except RuntimeError:
+ LOGGER.warning("connection lost")
# disconnect
heartbeat_task.cancel()
asyncio.create_task(self.__handle_player_event(lms_player.player_id, 'disconnected'))
-
- ### Provider specific implementation #####
class PyLMSPlayer(object):
''' very basic Python implementation of SlimProto '''
async def setup_web(self):
app = web.Application()
+ app.add_routes([web.get('/jsonrpc.js', self.json_rpc)])
+ app.add_routes([web.post('/jsonrpc.js', self.json_rpc)])
app.add_routes([web.get('/ws', self.websocket_handler)])
app.add_routes([web.get('/stream', self.stream)])
app.add_routes([web.get('/api/search', self.search)])
app.add_routes([web.get('/api/{media_type}/{media_id}', self.get_item)])
app.add_routes([web.get('/', self.index)])
app.router.add_static("/", "./web")
-
self.runner = web.AppRunner(app)
await self.runner.setup()
http_site = web.TCPSite(self.runner, '0.0.0.0', self._http_port)
if request.method.upper() != 'HEAD':
async for chunk in self.mass.http_streamer.get_audio_stream(track_id, provider, player_id):
await resp.write(chunk)
- return resp
\ No newline at end of file
+ return resp
+
+ async def json_rpc(self, request):
+ '''
+ implement fake LMS jsonrpc interface
+ for some compatability with tools that talk to lms
+ only support for basic commands
+ '''
+ data = await request.json()
+ params = data['params']
+ player_id = params[0]
+ cmds = params[1]
+ cmd_str = " ".join(cmds)
+ if cmd_str in ['play', 'pause', 'stop']:
+ await self.mass.player.player_command(player_id, cmd_str)
+ elif 'power' in cmd_str:
+ await self.mass.player.player_command(player_id, cmd_str, cmd_str[1])
+ elif cmd_str == 'playlist index +1':
+ await self.mass.player.player_command(player_id, 'next')
+ elif cmd_str == 'playlist index -1':
+ await self.mass.player.player_command(player_id, 'previous')
+ elif 'mixer volume' in cmd_str:
+ await self.mass.player.player_command(player_id, 'volume', cmd_str[2])
+ elif cmd_str == 'mixer muting 1':
+ await self.mass.player.player_command(player_id, 'mute', 'on')
+ elif cmd_str == 'mixer muting 0':
+ await self.mass.player.player_command(player_id, 'mute', 'off')
+ elif cmd_str == 'button volup':
+ await self.mass.player.player_command(player_id, 'volume', 'up')
+ elif cmd_str == 'button voldown':
+ await self.mass.player.player_command(player_id, 'volume', 'down')
+ elif cmd_str == 'button power':
+ await self.mass.player.player_command(player_id, 'power', 'toggle')
+ return web.Response(text='success')
+
\ No newline at end of file