use case is enable crossfade support for chromecast devices
'''
player_id = http_request.query.get('player_id')
- startindex = int(http_request.query.get('startindex', 0))
+ startindex = int(http_request.query.get('startindex'))
cancelled = threading.Event()
resp = web.StreamResponse(status=200,
reason='OK',
await buffer.put(b'') # indicate EOF
asyncio.create_task(fill_buffer())
+ player = await self.mass.player.player(player_id)
+
+ # retrieve player object
player = await self.mass.player.player(player_id)
queue_index = startindex
+ LOGGER.info("Start Queue Stream for player %s at index %s" %(player_id, queue_index))
last_fadeout_data = b''
+ # report start of queue playback so we can calculate current track/duration etc.
self.mass.event_loop.create_task(self.mass.player.player_queue_stream_update(player_id, queue_index, True))
while True:
# get the (next) track in queue
while buffer.qsize() > 1 and not cancelled.is_set():
await asyncio.sleep(1)
# end of the track reached
- LOGGER.info("Finished Streaming queue track: %s - %s" % (track_id, queue_track.name))
- # update actual duration to the queue for more accurate now playing info
+ # WIP: update actual duration to the queue for more accurate now playing info
accurate_duration = bytes_written / int(sample_rate * 4 * 2)
queue_track.duration = accurate_duration
self.mass.player.providers[player.player_provider]._player_queue[player_id][queue_index] = queue_track
# move to next queue index
queue_index += 1
self.mass.event_loop.create_task(self.mass.player.player_queue_stream_update(player_id, queue_index, False))
+ LOGGER.info("Finished Streaming queue track: %s - %s" % (track_id, queue_track.name))
# break out the loop if the http session is cancelled
if cancelled.is_set():
break
self._players = {}
self._chromecasts = {}
self._player_queue = {}
- self._player_queue_startindex = {}
+ self._player_queue_index = {}
+ self._player_queue_stream_startindex = {}
self.supported_musicproviders = ['http']
asyncio.ensure_future(self.__discover_chromecasts())
elif cmd == 'next':
enable_crossfade = self.mass.config['player_settings'][player_id]["crossfade_duration"] > 0
if enable_crossfade:
- await self.__play_stream_queue(player_id, self._players[player_id].cur_queue_index+1)
+ await self.__play_stream_queue(player_id, self._player_queue_index[player_id]+1)
else:
self._chromecasts[player_id].media_controller.queue_next()
elif cmd == 'previous':
if enable_crossfade:
- await self.__play_stream_queue(player_id, self._players[player_id].cur_queue_index-1)
+ await self.__play_stream_queue(player_id, self._player_queue_index[player_id]-1)
else:
self._chromecasts[player_id].media_controller.queue_prev()
elif cmd == 'power' and cmd_args == 'off':
''' return the current items in the player's queue '''
return self._player_queue[player_id][offset:limit]
+ async def player_queue_index(self, player_id):
+ ''' get current index of the player's queue '''
+ return self._player_queue_index[player_id]
+
async def play_media(self, player_id, media_items, queue_opt='play'):
'''
play media on a player
'''
castplayer = self._chromecasts[player_id]
- cur_queue_index = self._players[player_id].cur_queue_index
+ cur_queue_index = self._player_queue_index.get(player_id, 0)
enable_crossfade = self.mass.config['player_settings'][player_id]["crossfade_duration"] > 0
if queue_opt == 'replace' or not self._player_queue[player_id]:
async def player_queue_stream_update(self, player_id, cur_index, is_start=False):
''' called by our queue streamer when it started playing a track in the queue at index X '''
if is_start:
- self._player_queue_startindex[player_id] = cur_index
+ self._player_queue_stream_startindex[player_id] = cur_index
+ self._player_queue_index[player_id] = cur_index
# schedule update a few times as we don't know how much time is prebuffered
for i in range(0, 20):
castplayer = self._chromecasts[player_id]
player.state = PlayerState.Paused
else:
player.state = PlayerState.Stopped
- if not 'stream_queue' in mediastatus.content_id:
+ if not mediastatus.content_id:
+ player.cur_item = None
+ player.cur_item_time = 0
+ elif not 'stream_queue' in mediastatus.content_id:
player.cur_item = await self.__parse_track(mediastatus)
player.cur_item_time = mediastatus.adjusted_current_time
- player.cur_queue_index = await self.__get_cur_queue_index(player_id, mediastatus.content_id)
- else:
+ self._player_queue_index[player_id] = await self.__get_cur_queue_index(player_id, mediastatus.content_id)
+ elif 'stream_queue' in mediastatus.content_id:
+ # player is playing our special queue continuous stream
# try to work out the current time
# player is playing a constant stream of the queue so we need to do this the hard way
cur_time_queue = mediastatus.adjusted_current_time
total_time = 0
track_time = 0
- queue_index = self._player_queue_startindex[player_id]
+ queue_index = self._player_queue_stream_startindex[player_id]
queue_track = None
while True:
queue_track = self._player_queue[player_id][queue_index]
break
player.cur_item = queue_track
player.cur_item_time = track_time
- player.cur_queue_index = queue_index
+ self._player_queue_index[player_id] = queue_index
await self.mass.player.update_player(player)
async def __parse_track(self, mediastatus):
if not player_id in self._player_queue:
# TODO: persistant storage of player queue ?
self._player_queue[player_id] = []
+ self._player_queue_index[player_id] = 0
chromecast.wait()
@run_periodic(600)