|
@@ -3,7 +3,6 @@ from typing import Optional, Iterator, Dict, List
|
|
|
|
|
|
import sys
|
|
|
from itertools import cycle
|
|
|
-from websockets import WebSocketServerProtocol
|
|
|
|
|
|
import chube_search
|
|
|
from channel import Channel, Subscriber
|
|
@@ -46,7 +45,7 @@ class Chueue:
|
|
|
def pop(self):
|
|
|
with self:
|
|
|
if len(self._queue) > 0:
|
|
|
- song_id = self._queue.pop()
|
|
|
+ song_id = self._queue.pop(0)
|
|
|
code = self._codes.pop(song_id)
|
|
|
return self.as_song(song_id, code)
|
|
|
else:
|
|
@@ -164,6 +163,45 @@ async def request_list_operation_processor(ws, data, path):
|
|
|
await room.channel.send(message)
|
|
|
|
|
|
|
|
|
+async def media_action_processor(ws, data, path):
|
|
|
+ room = rooms[path]
|
|
|
+ action = data["action"]
|
|
|
+ send_next = False
|
|
|
+ if action == "NEXT":
|
|
|
+ current_id = data["current_id"]
|
|
|
+ with room.playback.lock, room.chueue:
|
|
|
+ old_song_id = room.playback.get_song_id()
|
|
|
+ if old_song_id == current_id:
|
|
|
+ send_next = True
|
|
|
+ new_song = play_next_song(room)
|
|
|
+ if new_song is None:
|
|
|
+ new_song_id = None
|
|
|
+ else:
|
|
|
+ new_song_id = new_song["id"]
|
|
|
+ if send_next:
|
|
|
+ await room.channel.send(make_message(
|
|
|
+ Message.MEDIA_ACTION,
|
|
|
+ {"action": MediaAction.NEXT.name, "ended_id": old_song_id, "current_id": new_song_id}))
|
|
|
+
|
|
|
+ if action == "PLAY" or send_next:
|
|
|
+ send_play = False
|
|
|
+ with room.playback.lock:
|
|
|
+ if room.playback.get_state() == PlayerState.PAUSED:
|
|
|
+ send_play = True
|
|
|
+ room.playback.set_state(PlayerState.PLAYING)
|
|
|
+ if send_play:
|
|
|
+ await room.channel.send(make_message(Message.MEDIA_ACTION, {"action": MediaAction.PLAY.name}))
|
|
|
+
|
|
|
+ if action == "PAUSE":
|
|
|
+ send_pause = False
|
|
|
+ with room.playback.lock:
|
|
|
+ if room.playback.get_state() == PlayerState.PLAYING:
|
|
|
+ send_pause = True
|
|
|
+ room.playback.set_state(PlayerState.PAUSED)
|
|
|
+ if send_pause:
|
|
|
+ await room.channel.send(make_message(Message.MEDIA_ACTION, {"action": MediaAction.PAUSE.name}))
|
|
|
+
|
|
|
+
|
|
|
async def obtain_control_processor(ws, data, path):
|
|
|
room = rooms[path]
|
|
|
await obtain_control(ws, room)
|
|
@@ -178,15 +216,21 @@ async def release_control_processor(ws, data, path):
|
|
|
# TODO error here
|
|
|
|
|
|
|
|
|
+def play_next_song(room):
|
|
|
+ new_song = room.chueue.pop()
|
|
|
+ room.playback.set_song(new_song)
|
|
|
+ if new_song is None:
|
|
|
+ room.playback.set_state(PlayerState.LIST_END)
|
|
|
+ return new_song
|
|
|
+
|
|
|
+
|
|
|
async def song_end_processor(ws, data, path):
|
|
|
room = rooms[path]
|
|
|
old_song_id = data["id"]
|
|
|
with room.controller_lock, room.playback.lock:
|
|
|
if room.controller is not None and ws is room.controller.ws and old_song_id == room.playback.get_song_id():
|
|
|
- new_song = room.chueue.pop()
|
|
|
- room.playback.set_song(new_song)
|
|
|
+ new_song = play_next_song(room)
|
|
|
if new_song is None:
|
|
|
- room.playback.set_state(PlayerState.LIST_END)
|
|
|
new_song_id = None
|
|
|
else:
|
|
|
new_song_id = new_song["id"]
|
|
@@ -249,6 +293,7 @@ def make_resolver():
|
|
|
resolver = Resolver()
|
|
|
resolver.register(Message.STATE, request_state_processor)
|
|
|
resolver.register(Message.LIST_OPERATION, request_list_operation_processor)
|
|
|
+ resolver.register(Message.MEDIA_ACTION, media_action_processor)
|
|
|
resolver.register(Message.PLAYER_ENABLED, player_enabled_processor)
|
|
|
resolver.register(Message.OBTAIN_CONTROL, obtain_control_processor)
|
|
|
resolver.register(Message.RELEASE_CONTROL, release_control_processor)
|