Yetangitu / Spodcast

Spodcast is a caching Spotify podcast to RSS proxy. Using Spodcast you can follow Spotify-hosted netcasts/podcasts using any player which supports RSS, thus enabling the use of older hardware which is not compatible with the Spotify (web) app.
GNU General Public License v3.0
357 stars 14 forks source link

Cannot download episodes anymore (Not found for url exception) #13

Closed diveflo closed 2 years ago

diveflo commented 2 years ago

Hi,

somehow I cannot download anymore episodes.

The full log:

DEBUG:spodcast.spodcast:args: Namespace(config_location='/mnt/audio/spodcast/spodcast.json', prepare_feed=False, urls=['https://open.spotify.com/show/1OLcQdw2PFDPG1jo3s0wbp'], login=None, root_path='/mnt/audio/spodcast', skip_existing=None, retry=None, max_episodes='5', chunk_size=None, download_real_time=None, language=None, credentials_location=None, rss_feed=None, transcode=None, log_level='debug', func=<function client at 0xb6b07fa0>) DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): apresolve.spotify.com:443 DEBUG:urllib3.connectionpool:https://apresolve.spotify.com:443 "GET /?type=accesspoint HTTP/1.1" 200 None INFO:Librespot:Session:Created new session! device_id: xxxxxxxxxxxxxxxxxxxxxxx, ap: ap-gew1.spotify.com:4070 INFO:Librespot:Session:Connection successfully! INFO:Librespot:Session:Session.Receiver started DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): apresolve.spotify.com:443 DEBUG:urllib3.connectionpool:https://apresolve.spotify.com:443 "GET /?type=spclient HTTP/1.1" 200 None DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): apresolve.spotify.com:443 INFO:Librespot:Session:Skipping 02 INFO:Librespot:Session:Received license_version: 0 INFO:Librespot:Session:Received country_code: DE DEBUG:Librespot:Session:Parsed product info: {'type': 'open', 'ab-ad-player-targeting': '1', 'ab-ad-requester': '1', 'ab-android-push-notifications': '1', 'ab-browse-music-tuesday': '1', 'ab-collection-bookmark-model': '1', 'ab-collection-followed-artists-only': '1', 'ab-collection-hide-unavailable-albums': '0', 'ab-collection-offline-mode': '0', 'ab-collection-union': '1', 'ab-desktop-hide-follow': '0', 'ab-desktop-playlist-annotation-edit': '1', 'ab-mobile-discover': '0', 'ab-mobile-running-onlymanualmode': 'only-manual', 'ab-mobile-running-tempo-detection': 'Control', 'ab-mobile-social-feed': '1', 'ab-mobile-startpage': '0', 'ab-moments-experience': '0', 'ab-new-share-flow': '0', 'ab-play-history': '0', 'ab-playlist-extender': '5', 'ab-sugarpills-sanity-check': '2', 'ab-test-group': '767', 'ab-watch-now': '0', 'ab_recently_played_feature_time_filter_threshold': 'com.spotify.gaia=30,driving-mode=120,spotify%3Ainternal%3Astartpage=30', 'ad-catalogues': 'spotify', 'ad-formats-preroll-video': '0', 'ad-formats-video-takeover': '1', 'ad-persist-reward-time': '0', 'ad-session-persistence': '1', 'ad-use-adlogic': 'stream', 'ads': '1', 'allow-override-internal-prefs': '0', 'ap-resolve-pods': '0', 'app-developer': '0', 'arsenal_country': '1', 'audio-preview-url-template': 'https://p.scdn.co/mp3-preview/{id}', 'backend-advised-bitrate': '1', 'browse-overview-enabled': '1', 'buffering-strategy': '0', 'buffering-strategy-parameters': '0.8:0.2:0.0:0.0:0.0:0.0:1.0:10:10:2000:10000:10485760', 'capper-profile': None, 'capping-bar-threshold': '3601', 'catalogue': 'free', 'collection': '1', 'enable-annotations': '2', 'enable-annotations-read': '0', 'enable-autostart': '1', 'enable-crossfade': '1', 'enable-gapless': '1', 'expiry': '1', 'explicit-content': '1', 'fb-grant-permission-local-render': '0', 'fb-info-confirmation': 'control', 'financial-product': 'pr:open,tc:0', 'head-file-caching': '1', 'head-files': '1', 'head-files-url': 'https://heads-fa.scdn.co/head/{file_id}', 'high-bitrate': '0', 'image-url': 'https://i.scdn.co/image/{file_id}', 'incognito_mode_timeout': '21600', 'india-experience': '0', 'instant-search': '0', 'instant-search-expand-sidebar': '0', 'is_email_verified': '0', 'key-caching-max-count': '10000', 'key-caching-max-offline-seconds': '1800', 'key-memory-cache-mode': '1:15,300', 'lastfm-session': None, 'libspotify': '0', 'license-acceptance-grace-days': '30', 'license-agreements': None, 'local-files-import': '0', 'metadata-link-lookup-modes': '0', 'mobile': '0', 'mobile-browse': '0', 'mobile-login': '0', 'mobile-payment': '0', 'name': 'Spotify Free', 'network-operator-premium-activation': '1', 'nft-disabled': '1', 'npt-disabled': '2', 'offline': '0', 'on-demand': '1', 'pause-after': '18000', 'payments-locked-state': '0', 'player-license': 'on-demand', 'playlist-annotations-markup': '0', 'playlist-folders': '1', 'preferred-locale': 'en', 'prefetch-keys': '1', 'prefetch-strategy': '0', 'prefetch-window-max': '2', 'profile-image-upload': '1', 'public-toplist': '0', 'publish-activity': '0', 'publish-playlist': '0', 'radio': '1', 'remote-control': '6', 'send-email': '0', 'shows-collection': '1', 'shows-collection-jam': '1', 'shuffle': '0', 'shuffle-algorithm': '1', 'sidebar-navigation-enabled': '0', 'storage-size-config': '10240,90,500,3', 'streaming': '1', 'streaming-rules': None, 'track-cap': '0', 'ugc-abuse-report': '1', 'ugc-abuse-report-url': 'https://support.spotify.com/abuse/?uri={uri}', 'use-fb-publish-backend': '2', 'use-pl3': '0', 'use-playlist-app': '0', 'use-playlist-uris': '0', 'user-profile-show-invitation-codes': '0', 'video-cdn-sampling': '1', 'video-device-blacklisted': '0', 'video-initial-bitrate': '200000', 'video-keyframe-url': 'http://keyframes-fa.cdn.spotify.com/keyframes/v1/sources/{source_id}/keyframe/heights/{height}/timestamps/{timestamp_ms}.jpg', 'video-manifest-url': 'https://spclient.wg.spotify.com/manifests/v6/{type}/sources/{source_id}/options/supports_drm', 'video-wifi-initial-bitrate': '800000', 'wanted-licenses': None, 'widevine-license-url': 'https://spclient.wg.spotify.com/widevine-license/v1/video/license'} INFO:Librespot:Session:Skipping 69 INFO:Librespot:Session:Skipping 1f DEBUG:Librespot:MercuryClient:Handling packet, cmd: 0xb5, seq: 331586318658174976, flags: b'\x01', parts: 1 DEBUG:Librespot:MercuryClient:Couldn't dispatch Mercury event seq: 331586318658174976, uri: hm://pusher/v1/connections/ZjU4MmIxNmNiODE1NWM3YmMxZjgxMDhhMTZmNjRjZjFjODRjMTA5YytBUCt0Y3A6Ly9nZXcxLWFjY2Vzc3BvaW50LWEtZ2Q0OS5nZXcxLnNwb3RpZnkubmV0OjUwMDMrRDEzMDNCNkMwQ0REN0EyOTA3MTg5QzdENjJFOTE4QkNDNjc5RjlBMTJEN0UwNDE3RTZCQjI3NTA1QjcyMDFDNQ%3D%3D, code: 200, payload: b'' DEBUG:Librespot:Session:Received 0x10: 71ecf06a1db7dd2e153baadbd9bdebe8c0626907 INFO:Librespot:Session:Skipping unknown command cmd: 0x75, payload: b'\x00\x00\x00' DEBUG:urllib3.connectionpool:https://apresolve.spotify.com:443 "GET /?type=dealer HTTP/1.1" 200 None DEBUG:Librespot:TokenProvider:Token expired or not suitable, requesting again. scopes: ['playlist-read'], old_token: None DEBUG:Librespot:MercuryClient:Send Mercury request, seq: 0, uri: hm://keymaster/token/authenticated?scope=playlist-read&client_id=xxxxxxxxxxxxxxxx&device_id=xxxxxxxxxxxxxxxx, method: GET DEBUG:Librespot:MercuryClient:Handling packet, cmd: 0xb2, seq: 0, flags: b'\x01', parts: 2 DEBUG:Librespot:TokenProvider:Updated token successfully! scopes: ['playlist-read'], new_token: <librespot.core.TokenProvider.StoredToken object at 0xb5c38f28> INFO:Librespot:Session:Authenticated as xxxxx! DEBUG:spodcast.app:episode_id None. show_id 1OLcQdw2PFDPG1jo3s0wbp INFO:spodcast.podcast:Fetching episodes... DEBUG:Librespot:TokenProvider:Token expired or not suitable, requesting again. scopes: ['user-read-email'], old_token: None DEBUG:Librespot:MercuryClient:Send Mercury request, seq: 1, uri: hm://keymaster/token/authenticated?scope=user-read-email&client_id=xxxxxxxxxxxxxxxx&device_id=xxxxxxxxxxxxxxxx, method: GET DEBUG:Librespot:MercuryClient:Handling packet, cmd: 0xb2, seq: 1, flags: b'\x01', parts: 2 DEBUG:Librespot:TokenProvider:Updated token successfully! scopes: ['user-read-email'], new_token: <librespot.core.TokenProvider.StoredToken object at 0xb5c388e0> DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.spotify.com:443 DEBUG:urllib3.connectionpool:https://api.spotify.com:443 "GET /v1/shows/1OLcQdw2PFDPG1jo3s0wbp/episodes?limit=50&offset=0 HTTP/1.1" 200 None DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.spotify.com:443 DEBUG:urllib3.connectionpool:https://api.spotify.com:443 "GET /v1/shows/1OLcQdw2PFDPG1jo3s0wbp/episodes?limit=50&offset=50 HTTP/1.1" 200 None DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.spotify.com:443 DEBUG:urllib3.connectionpool:https://api.spotify.com:443 "GET /v1/shows/1OLcQdw2PFDPG1jo3s0wbp/episodes?limit=50&offset=100 HTTP/1.1" 200 None DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.spotify.com:443 DEBUG:urllib3.connectionpool:https://api.spotify.com:443 "GET /v1/shows/1OLcQdw2PFDPG1jo3s0wbp/episodes?limit=50&offset=150 HTTP/1.1" 200 None DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.spotify.com:443 DEBUG:urllib3.connectionpool:https://api.spotify.com:443 "GET /v1/shows/1OLcQdw2PFDPG1jo3s0wbp/episodes?limit=50&offset=200 HTTP/1.1" 200 None DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.spotify.com:443 DEBUG:urllib3.connectionpool:https://api.spotify.com:443 "GET /v1/shows/1OLcQdw2PFDPG1jo3s0wbp/episodes?limit=50&offset=250 HTTP/1.1" 200 None DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.spotify.com:443 DEBUG:urllib3.connectionpool:https://api.spotify.com:443 "GET /v1/shows/1OLcQdw2PFDPG1jo3s0wbp/episodes?limit=50&offset=300 HTTP/1.1" 200 None DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.spotify.com:443 DEBUG:urllib3.connectionpool:https://api.spotify.com:443 "GET /v1/shows/1OLcQdw2PFDPG1jo3s0wbp/episodes?limit=50&offset=350 HTTP/1.1" 200 None DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.spotify.com:443 DEBUG:urllib3.connectionpool:https://api.spotify.com:443 "GET /v1/shows/1OLcQdw2PFDPG1jo3s0wbp/episodes?limit=50&offset=400 HTTP/1.1" 200 None INFO:spodcast.podcast:Fetching episode information... DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.spotify.com:443 DEBUG:urllib3.connectionpool:https://api.spotify.com:443 "GET /v1/episodes/4cSLQpgJt3mIky4fnjnsPb HTTP/1.1" 200 None DEBUG:spodcast.podcast:episode info: {'audio_preview_url': 'https://p.scdn.co/mp3-preview/298d41f47db5ba1832183ee0ee563ce30e524650', 'content_type': 'PODCAST_EPISODE', 'description': 'Wie Nacktmulle ihr schreckliches Regiment führen und E-Scooter ellipsenförmige Problemzonen schaffen. Ey Leute! Frech kommt weiter. Einfach mal müde ne Folge aufnehmen und auf dem flambierten Parmesanrad in den Sonnenuntergang reiten. Learn more about your ad choices. Visit podcastchoices.com/adchoices', 'duration_ms': 2978246, 'explicit': False, 'external_urls': {'spotify': 'https://open.spotify.com/episode/4cSLQpgJt3mIky4fnjnsPb'}, 'href': 'https://api.spotify.com/v1/episodes/4cSLQpgJt3mIky4fnjnsPb', 'html_description': '

Wie Nacktmulle ihr schreckliches Regiment führen und E-Scooter ellipsenförmige Problemzonen schaffen. Ey Leute! Frech kommt weiter. Einfach mal müde ne Folge aufnehmen und auf dem flambierten Parmesanrad in den Sonnenuntergang reiten.

Learn more about your ad choices. Visit podcastchoices.com/adchoices

', 'id': '4cSLQpgJt3mIky4fnjnsPb', 'images': [{'height': 640, 'url': 'https://i.scdn.co/image/ab6765630000ba8a21e277ef5fc2ffa449254d37', 'width': 640}, {'height': 300, 'url': 'https://i.scdn.co/image/ab67656300005f1f21e277ef5fc2ffa449254d37', 'width': 300}, {'height': 64, 'url': 'https://i.scdn.co/image/ab6765630000f68d21e277ef5fc2ffa449254d37', 'width': 64}], 'is_externally_hosted': False, 'is_paywall_content': False, 'is_playable': True, 'language': 'de', 'languages': ['de'], 'name': 'Einfach müde', 'release_date': '2022-06-18', 'release_date_precision': 'day', 'resume_point': {'fully_played': False, 'resume_position_ms': 0}, 'show': {'available_markets': ['AD', 'AE', 'AG', 'AL', 'AM', 'AO', 'AR', 'AT', 'AU', 'AZ', 'BA', 'BB', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BN', 'BO', 'BR', 'BS', 'BT', 'BW', 'BZ', 'CA', 'CH', 'CI', 'CL', 'CM', 'CO', 'CR', 'CV', 'CW', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'ES', 'FI', 'FJ', 'FM', 'FR', 'GA', 'GB', 'GD', 'GE', 'GH', 'GM', 'GN', 'GQ', 'GR', 'GT', 'GW', 'GY', 'HK', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IN', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE', 'KH', 'KI', 'KM', 'KN', 'KW', 'LA', 'LB', 'LC', 'LI', 'LR', 'LS', 'LT', 'LU', 'LV', 'MA', 'MC', 'ME', 'MG', 'MH', 'MK', 'ML', 'MN', 'MO', 'MR', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NE', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NZ', 'OM', 'PA', 'PE', 'PG', 'PH', 'PL', 'PS', 'PT', 'PW', 'PY', 'QA', 'RO', 'RS', 'RW', 'SA', 'SB', 'SC', 'SE', 'SG', 'SI', 'SK', 'SL', 'SM', 'SN', 'SR', 'ST', 'SV', 'SZ', 'TD', 'TG', 'TH', 'TL', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ', 'US', 'UY', 'UZ', 'VC', 'VN', 'VU', 'WS', 'XK', 'ZA', 'ZM', 'ZW'], 'copyrights': [], 'description': 'Fest & Flauschig mit Jan Böhmermann und Olli Schulz. Der preisgekrönte, verblüffend fabelhafte, grenzenlos fantastische Podcast für sie, ihn und es.', 'explicit': False, 'external_urls': {'spotify': 'https://open.spotify.com/show/1OLcQdw2PFDPG1jo3s0wbp'}, 'href': 'https://api.spotify.com/v1/shows/1OLcQdw2PFDPG1jo3s0wbp', 'html_description': '

Fest & Flauschig mit Jan Böhmermann und Olli Schulz. Der preisgekrönte, verblüffend fabelhafte, grenzenlos fantastische Podcast für sie, ihn und es.

', 'id': '1OLcQdw2PFDPG1jo3s0wbp', 'images': [{'height': 640, 'url': 'https://i.scdn.co/image/ab6765630000ba8a21e277ef5fc2ffa449254d37', 'width': 640}, {'height': 300, 'url': 'https://i.scdn.co/image/ab67656300005f1f21e277ef5fc2ffa449254d37', 'width': 300}, {'height': 64, 'url': 'https://i.scdn.co/image/ab6765630000f68d21e277ef5fc2ffa449254d37', 'width': 64}], 'is_externally_hosted': False, 'languages': ['de'], 'media_type': 'audio', 'name': 'Fest & Flauschig', 'publisher': 'Jan Böhmermann & Olli Schulz', 'total_episodes': 415, 'type': 'show', 'uri': 'spotify:show:1OLcQdw2PFDPG1jo3s0wbp'}, 'type': 'episode', 'uri': 'spotify:episode:4cSLQpgJt3mIky4fnjnsPb'} DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api-partner.spotify.com:443 DEBUG:urllib3.connectionpool:https://api-partner.spotify.com:443 "GET /pathfinder/v1/query?operationName=getEpisode&variables=%7B%22uri%22:%22spotify:episode:4cSLQpgJt3mIky4fnjnsPb%22%7D&extensions=%7B%22persistedQuery%22:%7B%22version%22:1,%22sha256Hash%22:%22224ba0fd89fcfdfb3a15fa2d82a6112d3f4e2ac88fba5c6713de04d1b72cf482%22%7D%7D HTTP/1.1" 200 None DEBUG:spodcast.podcast:('{"data":{"episode":{"id":"4cSLQpgJt3mIky4fnjnsPb","uri":"spotify:episode:4cSLQpgJt3mIky4fnjnsPb","name":"Einfach müde","htmlDescription":"

Wie Nacktmulle ihr schreckliches Regiment führen und E-Scooter ellipsenförmige Problemzonen schaffen. Ey Leute! Frech kommt weiter. Einfach mal müde ne Folge aufnehmen und auf dem flambierten Parmesanrad in den Sonnenuntergang reiten.

Learn more about your ad choices. Visit <a href=\"https://podcastchoices.com/adchoices\" rel=\"nofollow\">podcastchoices.com/adchoices

","description":"Wie Nacktmulle ihr schreckliches Regiment führen und E-Scooter ellipsenförmige Problemzonen schaffen. Ey Leute! Frech kommt weiter. Einfach mal müde ne Folge aufnehmen und auf dem flambierten Parmesanrad in den Sonnenuntergang reiten. Learn more about your ad choices. Visit podcastchoices.com/adchoices","duration":{"totalMilliseconds":2978246},"audio":{"items":[{"url":"https://p.scdn.co/mp3-preview/649ad573183f3e299658d43dcead5fd5e71e2c78","format":"AAC_24","fileId":"649ad573183f3e299658d43dcead5fd5e71e2c78","externallyHosted":false},{"url":"https://p.scdn.co/mp3-preview/531e8201de62066a4f78427f378d134e3e87701b","format":"MP4_128_DUAL","fileId":"531e8201de62066a4f78427f378d134e3e87701b","externallyHosted":false},{"url":"https://p.scdn.co/mp3-preview/e1f819cf9b3c282b00a64e26f12718c64a28fd60","format":"MP4_128","fileId":"e1f819cf9b3c282b00a64e26f12718c64a28fd60","externallyHosted":false},{"url":"https://p.scdn.co/mp3-preview/8f4418c60184e9b0776ae16e4d2766024d103f8d","format":"OGG_VORBIS_96","fileId":"8f4418c60184e9b0776ae16e4d2766024d103f8d","externallyHosted":false}]},"audioPreview":{"url":"https://p.scdn.co/mp3-preview/298d41f47db5ba1832183ee0ee563ce30e524650","format":"MP3_96"},"playability":{"playable":true,"reason":"PLAYABLE"},"playedState":{"playPositionMilliseconds":0,"state":"NOT_STARTED"},"releaseDate":{"isoString":"2022-06-18T21:50:00Z"},"contentRating":{"label":"NONE"},"coverArt":{"sources":[{"url":"https://i.scdn.co/image/ab6765630000f68d21e277ef5fc2ffa449254d37","width":64,"height":64},{"url":"https://i.scdn.co/image/ab67656300005f1f21e277ef5fc2ffa449254d37","width":300,"height":300},{"url":"https://i.scdn.co/image/ab6765630000ba8a21e277ef5fc2ffa449254d37","width":640,"height":640}]},"type":"PODCAST_EPISODE","podcast":{"uri":"spotify:show:1OLcQdw2PFDPG1jo3s0wbp","name":"Fest & Flauschig","coverArt":{"sources":[{"url":"https://i.scdn.co/image/ab6765630000f68d21e277ef5fc2ffa449254d37","width":64,"height":64},{"url":"https://i.scdn.co/image/ab67656300005f1f21e277ef5fc2ffa449254d37","width":300,"height":300},{"url":"https://i.scdn.co/image/ab6765630000ba8a21e277ef5fc2ffa449254d37","width":640,"height":640}]},"trailer":null,"showTypes":["SHOW_TYPE_EXCLUSIVE"]},"sharingInfo":{"shareUrl":"https://open.spotify.com/episode/4cSLQpgJt3mIky4fnjnsPb?si=FUC2Gy4tQFOJ2CUmXOxVyA","shareId":"FUC2Gy4tQFOJ2CUmXOxVyA"},"segments":{"segments":{"totalCount":0}}}},"extensions":{"cacheControl":{"version":1.0,"hints":[]}}}', {'data': {'episode': {'id': '4cSLQpgJt3mIky4fnjnsPb', 'uri': 'spotify:episode:4cSLQpgJt3mIky4fnjnsPb', 'name': 'Einfach müde', 'htmlDescription': '

Wie Nacktmulle ihr schreckliches Regiment führen und E-Scooter ellipsenförmige Problemzonen schaffen. Ey Leute! Frech kommt weiter. Einfach mal müde ne Folge aufnehmen und auf dem flambierten Parmesanrad in den Sonnenuntergang reiten.

Learn more about your ad choices. Visit podcastchoices.com/adchoices

', 'description': 'Wie Nacktmulle ihr schreckliches Regiment führen und E-Scooter ellipsenförmige Problemzonen schaffen. Ey Leute! Frech kommt weiter. Einfach mal müde ne Folge aufnehmen und auf dem flambierten Parmesanrad in den Sonnenuntergang reiten. Learn more about your ad choices. Visit podcastchoices.com/adchoices', 'duration': {'totalMilliseconds': 2978246}, 'audio': {'items': [{'url': 'https://p.scdn.co/mp3-preview/649ad573183f3e299658d43dcead5fd5e71e2c78', 'format': 'AAC_24', 'fileId': '649ad573183f3e299658d43dcead5fd5e71e2c78', 'externallyHosted': False}, {'url': 'https://p.scdn.co/mp3-preview/531e8201de62066a4f78427f378d134e3e87701b', 'format': 'MP4_128_DUAL', 'fileId': '531e8201de62066a4f78427f378d134e3e87701b', 'externallyHosted': False}, {'url': 'https://p.scdn.co/mp3-preview/e1f819cf9b3c282b00a64e26f12718c64a28fd60', 'format': 'MP4_128', 'fileId': 'e1f819cf9b3c282b00a64e26f12718c64a28fd60', 'externallyHosted': False}, {'url': 'https://p.scdn.co/mp3-preview/8f4418c60184e9b0776ae16e4d2766024d103f8d', 'format': 'OGG_VORBIS_96', 'fileId': '8f4418c60184e9b0776ae16e4d2766024d103f8d', 'externallyHosted': False}]}, 'audioPreview': {'url': 'https://p.scdn.co/mp3-preview/298d41f47db5ba1832183ee0ee563ce30e524650', 'format': 'MP3_96'}, 'playability': {'playable': True, 'reason': 'PLAYABLE'}, 'playedState': {'playPositionMilliseconds': 0, 'state': 'NOT_STARTED'}, 'releaseDate': {'isoString': '2022-06-18T21:50:00Z'}, 'contentRating': {'label': 'NONE'}, 'coverArt': {'sources': [{'url': 'https://i.scdn.co/image/ab6765630000f68d21e277ef5fc2ffa449254d37', 'width': 64, 'height': 64}, {'url': 'https://i.scdn.co/image/ab67656300005f1f21e277ef5fc2ffa449254d37', 'width': 300, 'height': 300}, {'url': 'https://i.scdn.co/image/ab6765630000ba8a21e277ef5fc2ffa449254d37', 'width': 640, 'height': 640}]}, 'type': 'PODCAST_EPISODE', 'podcast': {'uri': 'spotify:show:1OLcQdw2PFDPG1jo3s0wbp', 'name': 'Fest & Flauschig', 'coverArt': {'sources': [{'url': 'https://i.scdn.co/image/ab6765630000f68d21e277ef5fc2ffa449254d37', 'width': 64, 'height': 64}, {'url': 'https://i.scdn.co/image/ab67656300005f1f21e277ef5fc2ffa449254d37', 'width': 300, 'height': 300}, {'url': 'https://i.scdn.co/image/ab6765630000ba8a21e277ef5fc2ffa449254d37', 'width': 640, 'height': 640}]}, 'trailer': None, 'showTypes': ['SHOW_TYPE_EXCLUSIVE']}, 'sharingInfo': {'shareUrl': 'https://open.spotify.com/episode/4cSLQpgJt3mIky4fnjnsPb?si=FUC2Gy4tQFOJ2CUmXOxVyA', 'shareId': 'FUC2Gy4tQFOJ2CUmXOxVyA'}, 'segments': {'segments': {'totalCount': 0}}}}, 'extensions': {'cacheControl': {'version': 1.0, 'hints': []}}}) DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api-partner.spotify.com:443 DEBUG:urllib3.connectionpool:https://api-partner.spotify.com:443 "GET /pathfinder/v1/query?operationName=getEpisode&variables=%7B%22uri%22:%22spotify:episode:4cSLQpgJt3mIky4fnjnsPb%22%7D&extensions=%7B%22persistedQuery%22:%7B%22version%22:1,%22sha256Hash%22:%22224ba0fd89fcfdfb3a15fa2d82a6112d3f4e2ac88fba5c6713de04d1b72cf482%22%7D%7D HTTP/1.1" 200 None DEBUG:spodcast.podcast:download_url: https://p.scdn.co/mp3-preview/8f4418c60184e9b0776ae16e4d2766024d103f8d DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): p.scdn.co:443 DEBUG:urllib3.connectionpool:https://p.scdn.co:443 "GET /mp3-preview/8f4418c60184e9b0776ae16e4d2766024d103f8d HTTP/1.1" 404 0 Traceback (most recent call last): File "/usr/local/bin/spodcast", line 8, in sys.exit(main()) File "/usr/local/lib/python3.9/dist-packages/spodcast/main.py", line 42, in main args.func(args) File "/usr/local/lib/python3.9/dist-packages/spodcast/app.py", line 24, in client download_episode(episode) File "/usr/local/lib/python3.9/dist-packages/spodcast/podcast.py", line 172, in download_episode path, size, mimetype = download_file(download_url, filepath) File "/usr/local/lib/python3.9/dist-packages/spodcast/podcast.py", line 83, in download_file r.raise_for_status() # Will only raise for 4xx codes, so... File "/usr/local/lib/python3.9/dist-packages/requests/models.py", line 960, in raise_for_status raise HTTPError(http_error_msg, response=self) requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://p.scdn.co/mp3-preview/8f4418c60184e9b0776ae16e4d2766024d103f8d

Notes:

Let me know if I can assist somehow:) Thanks!

Yetangitu commented 2 years ago

I'll look into this, Spotify may have changed something somewhere somehow.

ahuse commented 2 years ago

I have the same issue. Worked for a day with a newly created account. Now it is not working again. Can still log in to the accounts. At the moment it seems like an internal ban, but could be something else that I triggered by creating and using a new account.

Yetangitu commented 2 years ago

I don't think this is caused by any banning, what seems to have happened is that Spotify has changed the way external streams are served. The current web client uses episodes[].external_playback_url to get the URL of the stream to play which is not present in the data served when using the authentication token generated by librespot:

Using a token gleaned from the web player:

$ curl -s 'https://api.spotify.com/v1/episodes?ids=78jHXrnIMJp5oLFsM2edS7' -H 'authorization: Bearer BQA-RnNIWkUGm4bHA1UVTrDpvzjOr4OLZXX-GySBuaEYn22DigMUbC201orHzmQZPcCU0SPS6nRUBhadjZoziNfNmK4suUzgMngvXBWsOdZ4D9f-ABCDEFGHIJKWERGn4hGibHWo0sFBrvNDlsw8KGMI2svbK_H1ufAMbSCdLOG3bknHhIXTc3G2gHxYWFQVmZi_p751JLzyfBIaIOxo4AQWC54gtgcyBb8TcNCi-BiHTVJ8UUpIL8Ab1v1Uvz8pFWHtKEi4U2HeO039cG_v6F8KmKbFwbJCZeKm0MeWjqkwQxmJdWB5MpetMKWuGgQT151oxA8EHp3TJYBtRC96ZcPSyw' |grep external_playback_url
    "external_playback_url" : "https://traffic.megaphone.fm/GLT8613565834.mp3?updated=1655823165",
$

Using a token generated by librespot

$ curl -s 'https://api.spotify.com/v1/episodes?ids=78jHXrnIMJp5oLFsM2edS7' -H 'authorization: Bearer BQDqtW9lsyWEu6Uvgb44ELVt18EXQP0FUfbf_AzKaoMeSLXBS13Wd5dfBOg2OqeU0jfDTxf_gLPO3EHHGfboF0ydBi3iAVjDv4pABCDEFGHIJKwOHrMWdaWySl-ej_nLZHbDoi79koauMPi0dJsz2_DhMNYHs1ZSHDDkHLriki-PimVYitM6XsI8eoAKUkk9EcmuLefyPeeCE6NXTw4rivzGWbxnuNTIM1E4YdtkUqEAPprc-CMP1BYF5FuExWtHsuwceLfqPghKDZs1K3HTDxnZms4LQl0' |grep external_playback_url
$

These two versions use the same Spotify account, the only difference is where the token was generated. There are bug reports out on a similar problem for librespot (the rust version): https://github.com/librespot-org/librespot/issues/818 where they also notice the required URL is not present.

(note: these tokens are edited and will not work, generate your own...)

What rests is to find which scope/dealer/protocol_version/... is needed for Spotify to serve the required data. If you feel like digging I'd suggest loading the web client and start observing what comes by when it authenticates etc.

Yetangitu commented 2 years ago

The root cause of this problem seems to be clear now (https://github.com/kokarare1212/librespot-python/issues/135) , working on a solution...

Yetangitu commented 2 years ago

Fixed in v0.5.0

tapatianbeast commented 2 years ago

Fixed in v0.5.0

Please update the docker image

Yetangitu commented 2 years ago

Fixed in v0.5.0

Please update the docker image

@heywoodlh This is for you

heywoodlh commented 2 years ago

@Yetangitu Docker Hub image has been updated: heywoodlh/spodcast:0.5.0! Thanks for pinging me, I didn't even realize that my podcasts haven't gotten an update for a couple weeks. :smile:

Yetangitu commented 2 years ago

Clearly you need more interesting podcasts...

Yetangitu commented 2 years ago

For those who don't read release notes:

This release:

To get spodcast to fetch those episodes it missed while #13 reared its ugly head (i.e. between 2022-06-16 and 2022-06-30) you can temporarily increase --max-episodes (or sync in the web interface, although that only goes up to 5) to whatever number of episodes you expect have been missed - the number depends on the release frequency.

tapatianbeast commented 2 years ago

I can't download individual episodes whit docker

INFO:Librespot:Session:Connection successfully! INFO:Librespot:Session:Session.Receiver started INFO:Librespot:Session:Skipping 02 INFO:Librespot:Session:Received license_version: 0 INFO:Librespot:Session:Received country_code: MX INFO:Librespot:Session:Skipping 1f INFO:Librespot:Session:Skipping 69 INFO:Librespot:Session:Skipping unknown command cmd: 0x75, payload: b'\x00\x00\x00' INFO:Librespot:Session:Authenticated as 31g47gqhgxqaqdw2yunf43hwvrbi! INFO:spodcast.podcast:Fetching episode information... Traceback (most recent call last): File "/usr/local/bin/spodcast", line 8, in sys.exit(main()) File "/usr/local/lib/python3.10/site-packages/spodcast/main.py", line 42, in main args.func(args) File "/usr/local/lib/python3.10/site-packages/spodcast/app.py", line 24, in client download_episode(episode_id) File "/usr/local/lib/python3.10/site-packages/spodcast/podcast.py", line 152, in download_episode podcast_name, podcast_id, duration_ms, episode_name, description, release_date, uri, download_url = get_episode_info(episode_id) File "/usr/local/lib/python3.10/site-packages/spodcast/podcast.py", line 43, in get_episode_info episode_id = EpisodeId.from_hex(episode_id_hex) File "/usr/local/lib/python3.10/site-packages/librespot/metadata.py", line 177, in from_hex return EpisodeId(hex_str) File "/usr/local/lib/python3.10/site-packages/librespot/metadata.py", line 159, in init self.__hex_id = hex_id.lower() AttributeError: 'EpisodeId' object has no attribute 'lower'

Yetangitu commented 2 years ago

What happens when you feed it a show link? Does it download episodes or do you get the same error?

Yetangitu commented 2 years ago

I can confirm this problem and will produce a fix r.s.n.

Yetangitu commented 2 years ago

Fixed in v0.5.1

@heywoodlh once more, please...

heywoodlh commented 2 years ago

Done!

ahuse commented 2 years ago

For one of my podcasts (Gemischtes Hack) i cannot download episodes most of the time, strangely sometimes it is downloading without an error. Here is the log:

INFO:Librespot:Session:Created new session! device_id: XXX, ap: ap-gew1.spotify.com:80
INFO:Librespot:Session:Connection successfully!
INFO:Librespot:Session:Session.Receiver started
INFO:Librespot:Session:Skipping 02
INFO:Librespot:Session:Received license_version: 0
INFO:Librespot:Session:Received country_code: DE
INFO:Librespot:Session:Skipping 1f
INFO:Librespot:Session:Skipping 69
INFO:Librespot:Session:Skipping unknown command cmd: 0x75, payload: b'\x00\x00\x00'
INFO:Librespot:Session:Authenticated as XXX
INFO:spodcast.podcast:Fetching episode information...
INFO:spodcast.podcast:Downloading file
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/response.py", line 438, in _error_catcher
    yield
  File "/usr/lib/python3/dist-packages/urllib3/response.py", line 519, in read
    data = self._fp.read(amt) if not fp_closed else b""
  File "/usr/lib/python3.9/http/client.py", line 458, in read
    n = self.readinto(b)
  File "/usr/lib/python3.9/http/client.py", line 502, in readinto
    n = self.fp.readinto(b)
  File "/usr/lib/python3.9/socket.py", line 704, in readinto
    return self._sock.recv_into(b)
  File "/usr/lib/python3.9/ssl.py", line 1241, in recv_into
    return self.read(nbytes, buffer)
  File "/usr/lib/python3.9/ssl.py", line 1099, in read
    return self._sslobj.read(len, buffer)
ssl.SSLError: [SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC] decryption failed or bad record mac (_ssl.c:2622)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/alex/.local/bin/spodcast", line 8, in <module>
    sys.exit(main())
  File "/home/alex/.local/lib/python3.9/site-packages/spodcast/__main__.py", line 42, in main
    args.func(args)
  File "/home/alex/.local/lib/python3.9/site-packages/spodcast/app.py", line 30, in client
    download_episode(episode_id)
  File "/home/alex/.local/lib/python3.9/site-packages/spodcast/podcast.py", line 173, in download_episode
    path, size, mimetype = download_file(download_url, filepath)
  File "/home/alex/.local/lib/python3.9/site-packages/spodcast/podcast.py", line 92, in download_file
    shutil.copyfileobj(r.raw, file)
  File "/usr/lib/python3.9/shutil.py", line 205, in copyfileobj
    buf = fsrc_read(length)
  File "/usr/lib/python3/dist-packages/urllib3/response.py", line 541, in read
    raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
  File "/usr/lib/python3.9/contextlib.py", line 135, in __exit__
    self.gen.throw(type, value, traceback)
  File "/usr/lib/python3/dist-packages/urllib3/response.py", line 449, in _error_catcher
    raise SSLError(e)
urllib3.exceptions.SSLError: [SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC] decryption failed or bad record mac (_ssl.c:2622)
Yetangitu commented 2 years ago

I just tried that podcast (https://open.spotify.com/show/7BTOsF2boKmlYr76BelijW?si=dad40f01e89a48ba) and had no such problems. The episodes are hosted externally from Spotify, content comes from https://dcs.megaphone.fm/. This is not a problem with either spodcast, librespot-python or Spotify. It can be a problem with the hosting provider, with OpenSSL, with a transparent proxy somewhere between you and dcs.megaphone.fm or anything else which interferes with traffic between the two.

ahuse commented 2 years ago

Ok. Thank you for the clarification. I will continue to monitor this problem. Maybe it resolves itself in a few days.