Change Directory

This commit is contained in:
kokarare1212 2021-02-25 08:07:17 +09:00
parent 01dae8ada4
commit 8daf68831e
133 changed files with 221 additions and 38 deletions

View File

@ -8,6 +8,17 @@ class Utils:
buffer = os.urandom(int(length / 2))
return Utils.bytes_to_hex(buffer)
@staticmethod
def truncate_middle(s: str, length: int) -> str:
if length <= 1:
raise TypeError()
first = length / 2
result = s[:first]
result += "..."
result += s[len(s) - (length - first):]
return result
@staticmethod
def split(s: str, c: str):
return s.split(c)

View File

@ -0,0 +1,52 @@
from __future__ import annotations
from librespot.core.Session import Session
from librespot.player import PlayerConfiguration, StateWrapper
from librespot.player.metrics import PlaybackMetrics
from librespot.player.mixing import AudioSink
from librespot.player.playback.PlayerSession import PlayerSession
from librespot.player.state.DeviceStateHandler import DeviceStateHandler
from librespot.standard.Closeable import Closeable
import sched
import time
class Player(Closeable, PlayerSession.Listener, AudioSink.Listener):
VOLUME_MAX: int = 65536
_scheduler: sched.scheduler = sched.scheduler(time.time)
_session: Session = None
_conf: PlayerConfiguration = None
_events: Player.EventsDispatcher = None
_sink: AudioSink = None
_metrics: dict[str, PlaybackMetrics] = dict()
_state: StateWrapper = None
_playerSession: PlayerSession = None
_releaseLineFuture = None
_deviceStateListener: DeviceStateHandler.Listener = None
def __init__(self, conf: PlayerConfiguration, session: Session):
self._conf = conf
self._session = session
self._events = Player.EventsDispatcher(conf)
self._sink = AudioSink(conf, self)
def init_state(self):
self._state = StateWrapper(self._session, self, self._conf)
class Anonymous(DeviceStateHandler.Listener):
def ready(self) -> None:
pass
def command(self, endpoint: DeviceStateHandler.Endpoint, data: DeviceStateHandler.CommandBody) -> None:
pass
self._deviceStateListener = Anonymous()
def volume_up(self, steps: int = 1):
if self.state is None:
return
class EventsDispatcher:
def __init__(self, conf: PlayerConfiguration):
pass

View File

@ -0,0 +1,38 @@
from __future__ import annotations
from librespot.core import Session
from librespot.player import Player, PlayerConfiguration
from librespot.player.state import DeviceStateHandler
from librespot.proto import Connect
from librespot.proto.Player import ContextPlayerOptions, PlayerState, Restrictions, Suppressions
class StateWrapper(DeviceStateHandler.Listener):
_state: PlayerState = None
_session: Session = None
_player: Player = None
_device: DeviceStateHandler = None
def __init__(self, session: Session, player: Player,
conf: PlayerConfiguration):
self._session = session
self._player = player
self._device = DeviceStateHandler(session, self, conf)
self._state = self._init_state()
def _init_state(self) -> PlayerState:
return PlayerState(
playback_speed=1.0,
suppressions=Suppressions(),
context_restrictions=Restrictions(),
options=ContextPlayerOptions(
repeating_context=False,
shuffling_context=False,
repeating_track=False
),
position_as_of_timestamp=0,
position=0,
is_playing=False
)
def ready(self) -> None:
self._device.update_state(Connect.PutStateReason.NEW_DEVICE, 0, self._state)

View File

@ -0,0 +1,6 @@
from __future__ import annotations
import logging
class PlaybackMetrics:
_LOGGER = logging.getLogger(__name__)

View File

@ -0,0 +1,11 @@
from __future__ import annotations
from librespot.player import PlayerConfiguration
class AudioSink:
def __init__(self, conf: PlayerConfiguration, listener: AudioSink.Listener):
pass
class Listener:
def sink_error(self, ex: Exception):
pass

View File

@ -0,0 +1 @@
from librespot.player.mixing.AudioSink import AudioSink

View File

@ -3,4 +3,5 @@ from librespot.standard import Closeable
class PlayerSession(Closeable):
pass
class Listener:
pass

View File

@ -0,0 +1,97 @@
from __future__ import annotations
from librespot.common import Utils
from librespot.core import Session
from librespot.player import PlayerConfiguration
from librespot.proto import Connect, Player
import base64
import concurrent.futures
import enum
import logging
import time
import typing
import urllib.parse
class DeviceStateHandler:
_LOGGER: logging = logging.getLogger(__name__)
_session: Session = None
_deviceInfo: Connect.DeviceInfo = None
_listeners: list[DeviceStateHandler.Listener] = list()
_putState: Connect.PutStateRequest = None
_putStateWorker: concurrent.futures.ThreadPoolExecutor = concurrent.futures.ThreadPoolExecutor()
_connectionId: str = None
def __init__(self, session: Session, player, conf: PlayerConfiguration):
self._session = session
self._deviceInfo = None
self._putState = Connect.PutStateRequest()
def _update_connection_id(self, newer: str) -> None:
newer = urllib.parse.unquote(newer, "UTF-8")
if self._connectionId is None or \
self._connectionId != newer:
self._connectionId = newer
self._LOGGER.debug("Updated Spotify-Connection-Id: {}".format(self._connectionId))
self._notify_ready()
def _notify_ready(self) -> None:
for listener in self._listeners:
listener.ready()
def update_state(self, reason: Connect.PutStateReason, player_time: int, state: Player.PlayerState):
if self._connectionId is None:
raise TypeError()
if player_time == -1:
pass
else:
pass
self._putState.put_state_reason = reason
self._putState.client_side_timestamp = int(time.time() * 1000)
self._putState.device.device_info = self._deviceInfo
self._putState.device.player_state = state
self._putStateWorker.submit(self._put_connect_state, self._putState)
def _put_connect_state(self, req: Connect.PutStateRequest):
self._session.api().put_connect_state(self._connectionId, req)
self._LOGGER.info("Put state. ts: {}, connId: {}, reason: {}".format(
req.client_side_timestamp, Utils.truncate_middle(self._connectionId, 10), req.put_state_reason
))
class Endpoint(enum.Enum):
Play: str = "play"
Pause: str = "pause"
Resume: str = "resume"
SeekTo: str = "seek_to"
SkipNext: str = "skip_next"
SkipPrev: str = "skip_prev"
class Listener:
def ready(self) -> None:
pass
def command(self, endpoint: DeviceStateHandler.Endpoint, data: DeviceStateHandler.CommandBody) -> None:
pass
def volume_changed(self) -> None:
pass
def not_active(self) -> None:
pass
class CommandBody:
_obj: typing.Any = None
_data: bytes = None
_value: str = None
def __init__(self, obj: typing.Any):
self._obj = obj
if obj.get("data") is not None:
self._data = base64.b64decode(obj.get("data"))
if obj.get("value") is not None:
self._value = obj.get("value")

View File

@ -0,0 +1 @@
from librespot.player.state.DeviceStateHandler import DeviceStateHandler

View File

@ -11,7 +11,7 @@ from google.protobuf import symbol_database as _symbol_database
_sym_db = _symbol_database.Default()
import librespot.proto.player_pb2 as player__pb2
import librespot.proto.Player as player__pb2
DESCRIPTOR = _descriptor.FileDescriptor(
name='connect.proto',

Some files were not shown because too many files have changed in this diff Show More