Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion librespot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


class Version:
version_name = "0.0.10"
version_name = "0.0.11"

@staticmethod
def platform() -> Platform:
Expand Down
55 changes: 13 additions & 42 deletions librespot/audio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,32 +326,6 @@ def get_url(resp: StorageResolve.StorageResolveResponse) -> str:
selected_url = random.choice(resp.cdnurl)
return selected_url

@staticmethod
def load_track(
session: Session, track: Metadata.Track, file: Metadata.AudioFile,
resp_or_url: typing.Union[StorageResolve.StorageResolveResponse,
str], preload: bool,
halt_listener: HaltListener) -> LoadedStream:
if type(resp_or_url) is str:
url = resp_or_url
else:
url = CdnFeedHelper.get_url(resp_or_url)
start = int(time.time() * 1000)
key = session.audio_key().get_audio_key(track.gid, file.file_id)
audio_key_time = int(time.time() * 1000) - start

streamer = session.cdn().stream_file(file, key, url, halt_listener)
input_stream = streamer.stream()
normalization_data = NormalizationData.read(input_stream)
if input_stream.skip(0xA7) != 0xA7:
raise IOError("Couldn't skip 0xa7 bytes!")
return LoadedStream(
track,
streamer,
normalization_data,
file.file_id, preload, audio_key_time
)

@staticmethod
def load_episode_external(
session: Session, episode: Metadata.Episode,
Expand All @@ -375,9 +349,9 @@ def load_episode_external(
)

@staticmethod
def load_episode(
def load_content(
session: Session,
episode: Metadata.Episode,
track_or_episode: typing.Union[Metadata.Track, Metadata.Episode],
file: Metadata.AudioFile,
resp_or_url: typing.Union[StorageResolve.StorageResolveResponse, str],
preload: bool,
Expand All @@ -388,7 +362,7 @@ def load_episode(
else:
url = CdnFeedHelper.get_url(resp_or_url)
start = int(time.time() * 1000)
key = session.audio_key().get_audio_key(episode.gid, file.file_id)
key = session.audio_key().get_audio_key(track_or_episode.gid, file.file_id)
audio_key_time = int(time.time() * 1000) - start

streamer = session.cdn().stream_file(file, key, url, halt_listener)
Expand All @@ -397,7 +371,7 @@ def load_episode(
if input_stream.skip(0xA7) != 0xA7:
raise IOError("Couldn't skip 0xa7 bytes!")
return LoadedStream(
episode,
track_or_episode,
streamer,
normalization_data,
file.file_id, preload, audio_key_time
Expand Down Expand Up @@ -742,22 +716,19 @@ def load(self, playable_id: PlayableId,
preload, halt_listener)
raise TypeError("Unknown content: {}".format(playable_id))

def load_stream(self, file: Metadata.AudioFile, track: Metadata.Track,
episode: Metadata.Episode, preload: bool,
halt_lister: HaltListener):
if track is None and episode is None:
def load_stream(self, file: Metadata.AudioFile,
track_or_episode: typing.Union[Metadata.Track, Metadata.Episode],
preload: bool, halt_lister: HaltListener):
if track_or_episode is None:
raise RuntimeError("No content passed!")
elif file is None:
raise RuntimeError("Content has no audio file!")
response = self.resolve_storage_interactive(file.file_id, preload)
if response.result == StorageResolve.StorageResolveResponse.Result.CDN:
if track is not None:
return CdnFeedHelper.load_track(self.__session, track, file,
response, preload, halt_lister)
return CdnFeedHelper.load_episode(self.__session, episode, file,
response, preload, halt_lister)
return CdnFeedHelper.load_content(self.__session, track_or_episode, file,
response, preload, halt_lister)
if response.result == StorageResolve.StorageResolveResponse.Result.STORAGE:
if track is None:
if track_or_episode is None:
pass
elif response.result == StorageResolve.StorageResolveResponse.Result.RESTRICTED:
raise RuntimeError("Content is restricted!")
Expand All @@ -779,7 +750,7 @@ def load_episode(self, episode_id: EpisodeId,
"Couldn't find any suitable audio file, available: {}".format(
episode.audio))
raise FeederException("Cannot find suitable audio file")
return self.load_stream(file, None, episode, preload, halt_listener)
return self.load_stream(file, episode, preload, halt_listener)

def load_track(self, track_id_or_track: typing.Union[TrackId,
Metadata.Track],
Expand All @@ -799,7 +770,7 @@ def load_track(self, track_id_or_track: typing.Union[TrackId,
"Couldn't find any suitable audio file, available: {}".format(
track.file))
raise FeederException("Cannot find suitable audio file")
return self.load_stream(file, track, None, preload, halt_listener)
return self.load_stream(file, track, preload, halt_listener)

def pick_alternative_if_necessary(
self, track: Metadata.Track) -> typing.Union[Metadata.Track, None]:
Expand Down
24 changes: 14 additions & 10 deletions librespot/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,13 @@ def get_ext_metadata(self, extension_kind: ExtensionKind, uri: str):

body = response.content
if body is None:
raise ConnectionError("Extended Metadata request failed: No response body")
raise ConnectionError("Extended Metadata request for {} failed: No response body".format(uri))

proto = BatchedExtensionResponse()
proto.ParseFromString(body)
entityextd = proto.extended_metadata.pop().extension_data.pop()
if entityextd.header.status_code != 200:
raise ConnectionError("Extended Metadata request failed: Status code {}".format(entityextd.header.status_code))
raise ConnectionError("Extended Metadata request for {} failed: Status code {}".format(uri, entityextd.header.status_code))
mdb: bytes = entityextd.extension_data.value
return mdb

Expand Down Expand Up @@ -267,20 +267,20 @@ def get_metadata_4_show(self, show: ShowId) -> Metadata.Show:
md.ParseFromString(mdb)
return md

def get_playlist(self,
_id: PlaylistId) -> Playlist4External.SelectedListContent:
def get_playlist(self, playlist: PlaylistId) -> Playlist4External.SelectedListContent:
"""

:param _id: PlaylistId:
:param playlist: PlaylistId:

"""
response = self.send("GET",
"/playlist/v2/playlist/{}".format(_id.id()), None,
None)
response = self.send("GET", "/playlist/v2/playlist/{}".format(playlist.id()),
None, None)
ApiClient.StatusCodeException.check_status(response)

body = response.content
if body is None:
raise IOError()
raise ConnectionError("Playlist Metadata request for {} failed: No response body".format(playlist.to_spotify_uri()))

proto = Playlist4External.SelectedListContent()
proto.ParseFromString(body)
return proto
Expand Down Expand Up @@ -1065,7 +1065,11 @@ def connect(self) -> None:
acc.write_int(2 + 4 + len(client_hello_bytes))
acc.write(client_hello_bytes)
# Read APResponseMessage
ap_response_message_length = self.connection.read_int()
try:
ap_response_message_length = self.connection.read_int()
except struct.error:
time.sleep(1)
ap_response_message_length = self.connection.read_int()
acc.write_int(ap_response_message_length)
ap_response_message_bytes = self.connection.read(
ap_response_message_length - 4)
Expand Down
Loading
Loading