From e1bff247285a3adeb37401b3865f7cdca7ed48a2 Mon Sep 17 00:00:00 2001 From: Marvin Schenkel Date: Sat, 24 Jun 2023 08:39:08 +0200 Subject: [PATCH] Fix pytube not matching function name. (#731) * Fix pytube not matching function name. * Fix personal playlists for multiple instances. (#725) --- .../server/providers/ytmusic/__init__.py | 26 +++++++++++++------ .../server/providers/ytmusic/helpers.py | 7 +++-- .../server/providers/ytmusic/manifest.json | 2 +- requirements_all.txt | 2 +- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/music_assistant/server/providers/ytmusic/__init__.py b/music_assistant/server/providers/ytmusic/__init__.py index 88bab587..e1df9d32 100644 --- a/music_assistant/server/providers/ytmusic/__init__.py +++ b/music_assistant/server/providers/ytmusic/__init__.py @@ -310,7 +310,11 @@ class YoutubeMusicProvider(MusicProvider): async def get_track(self, prov_track_id) -> Track: """Get full track details by id.""" await self._check_oauth_token() - if track_obj := await get_track(prov_track_id=prov_track_id, headers=self._headers): + if track_obj := await get_track( + prov_track_id=prov_track_id, + headers=self._headers, + signature_timestamp=self._signature_timestamp, + ): return await self._parse_track(track_obj) raise MediaNotFoundError(f"Item {prov_track_id} not found") @@ -485,13 +489,19 @@ class YoutubeMusicProvider(MusicProvider): async def get_stream_details(self, item_id: str, retry=0) -> StreamDetails: """Return the content details for the given track when it will be streamed.""" - data = { - "playbackContext": { - "contentPlaybackContext": {"signatureTimestamp": self._signature_timestamp} - }, - "video_id": item_id, - } - track_obj = await self._post_data("player", data=data) + # Misschien dit vervangen met api.get_song()? https://github.com/KoljaWindeler/ytube_music_player/blob/main/custom_components/ytube_music_player/media_player.py#L1493 + # data = { + # "playbackContext": { + # "contentPlaybackContext": {"signatureTimestamp": self._signature_timestamp} + # }, + # "video_id": item_id, + # } + # track_obj = await self._post_data("player", data=data) + track_obj = await get_track( + prov_track_id=item_id, + headers=self._headers, + signature_timestamp=self._signature_timestamp, + ) stream_format = await self._parse_stream_format(track_obj) url = await self._parse_stream_url(stream_format=stream_format, item_id=item_id) if not await self._is_valid_deciphered_url(url=url): diff --git a/music_assistant/server/providers/ytmusic/helpers.py b/music_assistant/server/providers/ytmusic/helpers.py index a7836349..e994ad0f 100644 --- a/music_assistant/server/providers/ytmusic/helpers.py +++ b/music_assistant/server/providers/ytmusic/helpers.py @@ -63,12 +63,14 @@ async def get_playlist(prov_playlist_id: str, headers: dict[str, str]) -> dict[s return await asyncio.to_thread(_get_playlist) -async def get_track(prov_track_id: str, headers: dict[str, str]) -> dict[str, str]: +async def get_track( + prov_track_id: str, headers: dict[str, str], signature_timestamp: str +) -> dict[str, str]: """Async wrapper around the ytmusicapi get_playlist function.""" def _get_song(): ytm = ytmusicapi.YTMusic(auth=json.dumps(headers)) - track_obj = ytm.get_song(videoId=prov_track_id) + track_obj = ytm.get_song(videoId=prov_track_id, signatureTimestamp=signature_timestamp) track = {} track["videoId"] = track_obj["videoDetails"]["videoId"] track["title"] = track_obj["videoDetails"]["title"] @@ -83,6 +85,7 @@ async def get_track(prov_track_id: str, headers: dict[str, str]) -> dict[str, st "thumbnails" ] track["isAvailable"] = track_obj["playabilityStatus"]["status"] == "OK" + track["streamingData"] = track_obj["streamingData"] return track return await asyncio.to_thread(_get_song) diff --git a/music_assistant/server/providers/ytmusic/manifest.json b/music_assistant/server/providers/ytmusic/manifest.json index 0bbe9174..6386577b 100644 --- a/music_assistant/server/providers/ytmusic/manifest.json +++ b/music_assistant/server/providers/ytmusic/manifest.json @@ -4,7 +4,7 @@ "name": "YouTube Music", "description": "Support for the YouTube Music streaming provider in Music Assistant.", "codeowners": ["@MarvinSchenkel"], - "requirements": ["ytmusicapi==1.0.0", "git+https://github.com/pytube/pytube.git@refs/pull/1501/head"], + "requirements": ["ytmusicapi==1.0.0", "git+https://github.com/pytube/pytube.git@refs/pull/1680/head"], "documentation": "https://github.com/music-assistant/hass-music-assistant/discussions/606", "multi_instance": true } diff --git a/requirements_all.txt b/requirements_all.txt index 8d705aa0..45fb3e4f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -15,7 +15,7 @@ deezer-python==5.12.0 faust-cchardet>=2.1.18 git+https://github.com/gieljnssns/python-radios.git@main git+https://github.com/jozefKruszynski/python-tidal.git@v0.7.1 -git+https://github.com/pytube/pytube.git@refs/pull/1501/head +git+https://github.com/pytube/pytube.git@refs/pull/1680/head mashumaro==3.7 memory-tempfile==2.2.3 music-assistant-frontend==20230616.0 -- 2.34.1