kokarare1212/librespot-python

[FEATURE REQUEST] Add support for streaming podcasts please :)

MrBruz opened this issue ยท 13 comments

Not much more to this feature request than specified in the title ^ ๐Ÿ‘

Thank you for your inquiry.
Some podcasts are already supported (Episode), but they are still incomplete, so we will add additional features.

Full podcast support should now be implemented with the following commit.
62feb08

Awesome thanks! Is this exactly the same code as if im streaming tracks or should I chnage stuff?

You can get the stream by writing the following.

from librespot.audio.decoders import AudioQuality, VorbisOnlyAudioQuality
from librespot.metadata import EpisodeId

# e.g. NHK Radio News (https://open.spotify.com/episode/2KAW1GCHpOsxPBuZ0v59S4) 
episode_id = EpisodeId.from_base62("2KAW1GCHpOsxPBuZ0v59S4")
stream = session.content_feeder().load(episode_id, VorbisOnlyAudioQuality(AudioQuality.VERY_HIGH), False, None)

The TrackId and EpisodeId have changed, but nothing else.

  File "/home/james/Documents/programs/python/spotify_testing/spotify_testing.py", line 169, in client
    stream = SESSION.content_feeder().load(episode_id, VorbisOnlyAudioQuality(QUALITY), False, None)
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 722, in load
    return self.load_episode(playable_id, audio_quality_picker,
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 754, in load_episode
    return CdnFeedHelper.load_episode_external(self.__session, episode,
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 366, in load_episode_external
    streamer = session.cdn().stream_external_episode(
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 429, in stream_external_episode
    StreamId(episode),
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 879, in __init__
    self.file_id = None if file is None else file.file_id
AttributeError: 'Episode' object has no attribute 'file_id'

I get this error while trying to load the following episode:
https://open.spotify.com/episode/3u0krXMhLcdGZUZkDVmMSt

It was caused by a faulty keyword argument.
I've fixed it in the commit below, can you please try again?
459c02e

Traceback (most recent call last):
  File "/home/james/Documents/programs/python/spotify_testing/spotify_testing.py", line 529, in <module>
    main()
  File "/home/james/Documents/programs/python/spotify_testing/spotify_testing.py", line 525, in main
    client()
  File "/home/james/Documents/programs/python/spotify_testing/spotify_testing.py", line 169, in client
    stream = SESSION.content_feeder().load(episode_id, VorbisOnlyAudioQuality(QUALITY), False, None)
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 722, in load
    return self.load_episode(playable_id, audio_quality_picker,
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 754, in load_episode
    return CdnFeedHelper.load_episode_external(self.__session, episode,
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 366, in load_episode_external
    streamer = session.cdn().stream_external_episode(
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 427, in stream_external_episode
    return CdnManager.Streamer(
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 577, in __init__
    self.write_chunk(first_chunk, 0, False)
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 586, in write_chunk
    self.buffer[chunk_index] = self.__audio_decrypt.decrypt_chunk(
  File "/home/james/.local/lib/python3.9/site-packages/librespot/structure.py", line 67, in decrypt_chunk
    raise NotImplementedError
NotImplementedError

It seems that the NoopAudioDecrypt class was not implemented.
It was fixed in the following commit.
c5db0a8

Nice job! It now works with https://open.spotify.com/episode/3u0krXMhLcdGZUZkDVmMSt but it unfortunately fails on the url you provided. https://open.spotify.com/episode/2KAW1GCHpOsxPBuZ0v59S4

Using 0 because preferred AudioQuality.HIGH couldn't be found.
Audio key error, code: 1
Audio key error, code: 1
Traceback (most recent call last):
  File "/home/james/Documents/programs/python/spotify_testing/spotify_testing.py", line 530, in <module>
    main()
  File "/home/james/Documents/programs/python/spotify_testing/spotify_testing.py", line 526, in main
    client()
  File "/home/james/Documents/programs/python/spotify_testing/spotify_testing.py", line 169, in client
    stream = SESSION.content_feeder().load(episode_id, VorbisOnlyAudioQuality(QUALITY), False, None)
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 722, in load
    return self.load_episode(playable_id, audio_quality_picker,
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 762, in load_episode
    return self.load_stream(file, None, episode, preload,
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 737, in load_stream
    return CdnFeedHelper.load_episode(self.__session, episode, file,
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 389, in load_episode
    key = session.audio_key().get_audio_key(episode.gid, file.file_id)
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 279, in get_audio_key
    return self.get_audio_key(gid, file_id, False)
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 280, in get_audio_key
    raise RuntimeError(
RuntimeError: Failed fetching audio key! gid: 5a6837196f0851b78d9a7b26ad00e044, fileId: ea90811b5f1a8631786631cd8bb9ffbbf591d70f

It turns out that an unintended default value by Protobuf caused an unintended AudioFile to be selected.
This has been fixed in the following commit.
9c35e63

Traceback (most recent call last):
  File "/home/james/Documents/programs/python/spotify_testing/./spotify_testing.py", line 544, in <module>
    main()
  File "/home/james/Documents/programs/python/spotify_testing/./spotify_testing.py", line 540, in main
    client()
  File "/home/james/Documents/programs/python/spotify_testing/./spotify_testing.py", line 169, in client
    stream = SESSION.content_feeder().load(
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 722, in load
    return self.load_episode(playable_id, audio_quality_picker,
  File "/home/james/.local/lib/python3.9/site-packages/librespot/audio/__init__.py", line 752, in load_episode
    episode = self.__session.api().get_metadata_4_episode(episode_id)
  File "/home/james/.local/lib/python3.9/site-packages/librespot/core.py", line 105, in get_metadata_4_episode
    ApiClient.StatusCodeException.check_status(response)
  File "/home/james/.local/lib/python3.9/site-packages/librespot/core.py", line 160, in check_status
    raise ApiClient.StatusCodeException(response)
librespot.core.StatusCodeException: 451

Ah I see! Turns out doing a api request about that episode before attempting to stream will return a 404 error so I can use that to check before trying to stream :)

Thanks for all the help as always!!