Yetangitu/Spodcast

Cannot download episodes anymore (Not found for url exception)

diveflo opened this issue · 18 comments

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!

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

ahuse commented

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.

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): librespot-org/librespot#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.

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

Fixed in v0.5.0

Fixed in v0.5.0

Please update the docker image

Fixed in v0.5.0

Please update the docker image

@heywoodlh This is for you

@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. 😄

Clearly you need more interesting podcasts...

For those who don't read release notes:

This release:

  • fixes #13 (i.e. this problem)
  • uses librespot-python interfaces instead of raw web API access (needed to fix #13)
  • can not yet determine decrypted file size for Spotify-hosted episodes (which used to work) so will only look at the file name to determine whether an episode has already been downloaded. To retry corrupted downloads just remove the partially downloaded file and try again.

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.

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'

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

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

Fixed in v0.5.1

@heywoodlh once more, please...

Done!

ahuse commented

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)

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

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