diff --git a/README.md b/README.md index 792826e..c36ef28 100644 --- a/README.md +++ b/README.md @@ -187,24 +187,19 @@ Currently, the following clients are available for use: - ❌ Cannot be used for playback, or playlist/mix/livestream loading. - `WEB` - ✔ Opus formats. +- `MWEB` + - ✔ Opus formats. - `WEBEMBEDDED` - ✔ Opus formats. - ✔ Limited age-restricted video playback. - ❌ No mix/playlist/search support. - `ANDROID` - ❌ Heavily restricted, frequently dysfunctional. - - ✔ Opus formats. -- `ANDROID_TESTSUITE` - - ✔ Opus formats. - - ❌ No mix/playlist/livestream support. - `ANDROID_MUSIC` - ✔ No opus formats for livestreams (requires transcoding). - ❌ No playlist/livestream support. - `ANDROID_VR` - ✔ Opus formats. -- `MEDIA_CONNECT` - - ❌ No Opus formats (requires transcoding). - - ❌ No mix/playlist/search support. - `IOS` - ❌ No Opus formats (requires transcoding). - `TVHTML5EMBEDDED` @@ -391,6 +386,12 @@ In addition, there are a few significant changes to note: the source manager with (e.g. an overridden `YoutubeTrackDetailsLoader`), this **is not** compatible with this source manager. +## Versioning Policy +This project follows [Semantic Versioning](https://semver.org/), except in the case of [client](#available-clients) removal. +Typically, clients are not removed unless there is good reason, such as being deprecated, irreparably broken or removed from YouTube's client lifecycle. +In such scenarios, we anticipate that you have ceased usage of such clients prior to their removal, so do not expect any code breakage, +however we advise that you periodically check and keep your client list up to date due to this. + ## Additional Support If you need additional help with using this source, that's not covered here or in any of the issues, [join our Discord server](https://discord.gg/ZW4s47Ppw4). diff --git a/common/src/main/java/dev/lavalink/youtube/YoutubeAudioSourceManager.java b/common/src/main/java/dev/lavalink/youtube/YoutubeAudioSourceManager.java index 2648de1..5dc62cb 100644 --- a/common/src/main/java/dev/lavalink/youtube/YoutubeAudioSourceManager.java +++ b/common/src/main/java/dev/lavalink/youtube/YoutubeAudioSourceManager.java @@ -79,7 +79,7 @@ public YoutubeAudioSourceManager(boolean allowSearch) { public YoutubeAudioSourceManager(boolean allowSearch, boolean allowDirectVideoIds, boolean allowDirectPlaylistIds) { // query order: music -> web -> androidtestsuite -> tvhtml5embedded - this(allowSearch, allowDirectVideoIds, allowDirectPlaylistIds, new Music(), new Web(), new AndroidTestsuite(), new TvHtml5Embedded()); + this(allowSearch, allowDirectVideoIds, allowDirectPlaylistIds, new Music(), new AndroidVr(), new Web(), new WebEmbedded()); } /** @@ -212,6 +212,7 @@ protected AudioItem loadItemOnce(@NotNull AudioReference reference) { } log.debug("Attempting to load {} with client \"{}\"", reference.identifier, client.getIdentifier()); + httpInterface.getContext().setAttribute(Client.OAUTH_CLIENT_ATTRIBUTE, client.supportsOAuth()); try { AudioItem item = router.route(client); diff --git a/common/src/main/java/dev/lavalink/youtube/clients/Android.java b/common/src/main/java/dev/lavalink/youtube/clients/Android.java index 4c0ae89..8e679a0 100644 --- a/common/src/main/java/dev/lavalink/youtube/clients/Android.java +++ b/common/src/main/java/dev/lavalink/youtube/clients/Android.java @@ -1,5 +1,6 @@ package dev.lavalink.youtube.clients; +import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; import dev.lavalink.youtube.clients.ClientConfig.AndroidVersion; import dev.lavalink.youtube.clients.skeleton.StreamingNonMusicClient; @@ -10,7 +11,7 @@ public class Android extends StreamingNonMusicClient { private static final Logger log = LoggerFactory.getLogger(Android.class); - public static String CLIENT_VERSION = "19.32.24"; + public static String CLIENT_VERSION = "19.44.38"; public static AndroidVersion ANDROID_VERSION = AndroidVersion.ANDROID_11; public static ClientConfig BASE_CONFIG = new ClientConfig() @@ -62,4 +63,25 @@ public ClientOptions getOptions() { public String getIdentifier() { return BASE_CONFIG.getName(); } + + @Override + @NotNull + protected String extractPlaylistName(@NotNull JsonBrowser json) { + return json.get("header") + .get("pageHeaderRenderer") + .get("content") + .get("elementRenderer") + .get("newElement") + .get("type") + .get("componentType") + .get("model") + .get("youtubeModel") + .get("viewModel") + .get("pageHeaderViewModel") + .get("title") + .get("dynamicTextViewModel") + .get("text") + .get("content") + .text(); + } } diff --git a/common/src/main/java/dev/lavalink/youtube/clients/AndroidLite.java b/common/src/main/java/dev/lavalink/youtube/clients/AndroidLite.java deleted file mode 100644 index 1620fc3..0000000 --- a/common/src/main/java/dev/lavalink/youtube/clients/AndroidLite.java +++ /dev/null @@ -1,73 +0,0 @@ -package dev.lavalink.youtube.clients; - -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import dev.lavalink.youtube.YoutubeAudioSourceManager; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class AndroidLite extends Android { - public static ClientConfig BASE_CONFIG = new ClientConfig() - .withApiKey(Android.BASE_CONFIG.getApiKey()) - .withClientName("ANDROID_LITE") - .withClientField("clientVersion", "3.26.1") - .withClientField("androidSdkVersion", ANDROID_VERSION.getSdkVersion()); - - public AndroidLite() { - this(ClientOptions.DEFAULT); - } - - public AndroidLite(@NotNull ClientOptions options) { - super(options, false); - } - - @Override - @NotNull - protected ClientConfig getBaseClientConfig(@NotNull HttpInterface httpInterface) { - return BASE_CONFIG.copy(); - } - - @Override - @NotNull - public String getIdentifier() { - return BASE_CONFIG.getName(); - } - - @Override - @NotNull - public String getPlayerParams() { - return MOBILE_PLAYER_PARAMS; - } - - @Override - public boolean canHandleRequest(@NotNull String identifier) { - // loose check to avoid loading mixes/playlists. - return !identifier.contains("list=") && super.canHandleRequest(identifier); - } - - @Override - public AudioItem loadMix(@NotNull YoutubeAudioSourceManager source, - @NotNull HttpInterface httpInterface, - @NotNull String mixId, - @Nullable String selectedVideoId) { - // Considered returning null but an exception makes it clearer as to why a mix couldn't be loaded, - // assuming someone tries to only register this client with the source manager. - // Also, an exception will halt further loading so other source managers won't be queried. - // N.B. This client genuinely cannot load mixes for whatever reason. You can get the mix metadata - // but there are no videos in the response JSON. Weird. - throw new FriendlyException("This client cannot load mixes", Severity.COMMON, - new RuntimeException("ANDROID_LITE cannot be used to load mixes")); - } - - @Override - public AudioItem loadPlaylist(@NotNull YoutubeAudioSourceManager source, - @NotNull HttpInterface httpInterface, - @NotNull String playlistId, - @Nullable String selectedVideoId) { - // Similar to mixes except server returns status code 500 when trying to load playlists. - throw new FriendlyException("This client cannot load playlists", Severity.COMMON, - new RuntimeException("ANDROID_LITE cannot be used to load playlists")); - } -} diff --git a/common/src/main/java/dev/lavalink/youtube/clients/AndroidMusic.java b/common/src/main/java/dev/lavalink/youtube/clients/AndroidMusic.java index e98d849..f22c12d 100644 --- a/common/src/main/java/dev/lavalink/youtube/clients/AndroidMusic.java +++ b/common/src/main/java/dev/lavalink/youtube/clients/AndroidMusic.java @@ -19,7 +19,7 @@ public class AndroidMusic extends Android { private static final Logger log = LoggerFactory.getLogger(AndroidMusic.class); - public static String CLIENT_VERSION = "7.11.50"; + public static String CLIENT_VERSION = "7.27.52"; public static ClientConfig BASE_CONFIG = new ClientConfig() .withApiKey(Android.BASE_CONFIG.getApiKey()) diff --git a/common/src/main/java/dev/lavalink/youtube/clients/AndroidTestsuite.java b/common/src/main/java/dev/lavalink/youtube/clients/AndroidTestsuite.java deleted file mode 100644 index 729bb88..0000000 --- a/common/src/main/java/dev/lavalink/youtube/clients/AndroidTestsuite.java +++ /dev/null @@ -1,76 +0,0 @@ -package dev.lavalink.youtube.clients; - -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import dev.lavalink.youtube.YoutubeAudioSourceManager; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class AndroidTestsuite extends Android { - public static String CLIENT_VERSION = "1.9"; - - public static ClientConfig BASE_CONFIG = new ClientConfig() - .withApiKey(Android.BASE_CONFIG.getApiKey()) - .withUserAgent(String.format("com.google.android.youtube/%s (Linux; U; Android %s) gzip", CLIENT_VERSION, ANDROID_VERSION.getOsVersion())) - .withClientName("ANDROID_TESTSUITE") - .withClientField("clientVersion", CLIENT_VERSION) - .withClientField("androidSdkVersion", ANDROID_VERSION.getSdkVersion()); - - public AndroidTestsuite() { - this(ClientOptions.DEFAULT); - } - - public AndroidTestsuite(@NotNull ClientOptions options) { - super(options, false); - } - - @Override - @NotNull - protected ClientConfig getBaseClientConfig(@NotNull HttpInterface httpInterface) { - return BASE_CONFIG.copy(); - } - - @Override - @NotNull - public String getIdentifier() { - return BASE_CONFIG.getName(); - } - - @Override - @NotNull - public String getPlayerParams() { - return MOBILE_PLAYER_PARAMS; - } - - @Override - public boolean canHandleRequest(@NotNull String identifier) { - // loose check to avoid loading mixes/playlists. - return !identifier.contains("list=") && super.canHandleRequest(identifier); - } - - @Override - public AudioItem loadMix(@NotNull YoutubeAudioSourceManager source, - @NotNull HttpInterface httpInterface, - @NotNull String mixId, - @Nullable String selectedVideoId) { - // Considered returning null but an exception makes it clearer as to why a mix couldn't be loaded, - // assuming someone tries to only register this client with the source manager. - // Also, an exception will halt further loading so other source managers won't be queried. - // N.B. This client genuinely cannot load mixes for whatever reason. You can get the mix metadata - // but there are no videos in the response JSON. Weird. - throw new FriendlyException("This client cannot load mixes", Severity.COMMON, - new RuntimeException("ANDROID_TESTSUITE cannot be used to load mixes")); - } - - @Override - public AudioItem loadPlaylist(@NotNull YoutubeAudioSourceManager source, - @NotNull HttpInterface httpInterface, - @NotNull String playlistId, - @Nullable String selectedVideoId) { - // Similar to mixes except server returns status code 500 when trying to load playlists. - throw new FriendlyException("This client cannot load playlists", Severity.COMMON, - new RuntimeException("ANDROID_TESTSUITE cannot be used to load playlists")); - } -} diff --git a/common/src/main/java/dev/lavalink/youtube/clients/AndroidVr.java b/common/src/main/java/dev/lavalink/youtube/clients/AndroidVr.java index 9110168..8c2ae5e 100644 --- a/common/src/main/java/dev/lavalink/youtube/clients/AndroidVr.java +++ b/common/src/main/java/dev/lavalink/youtube/clients/AndroidVr.java @@ -1,11 +1,12 @@ package dev.lavalink.youtube.clients; +import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; import dev.lavalink.youtube.clients.ClientConfig.AndroidVersion; import org.jetbrains.annotations.NotNull; public class AndroidVr extends Android { - public static String CLIENT_VERSION = "1.60.18"; + public static String CLIENT_VERSION = "1.60.19"; public static AndroidVersion ANDROID_VERSION = AndroidVersion.ANDROID_12L; public static ClientConfig BASE_CONFIG = new ClientConfig() @@ -42,4 +43,10 @@ public String getPlayerParams() { public String getIdentifier() { return BASE_CONFIG.getName(); } + + @Override + @NotNull + protected String extractPlaylistName(@NotNull JsonBrowser json) { + return json.get("header").get("playlistHeaderRenderer").get("title").get("runs").index(0).get("text").text(); + } } diff --git a/common/src/main/java/dev/lavalink/youtube/clients/Ios.java b/common/src/main/java/dev/lavalink/youtube/clients/Ios.java index 6142399..47af8ac 100644 --- a/common/src/main/java/dev/lavalink/youtube/clients/Ios.java +++ b/common/src/main/java/dev/lavalink/youtube/clients/Ios.java @@ -6,11 +6,11 @@ import org.jetbrains.annotations.NotNull; public class Ios extends StreamingNonMusicClient { - public static String CLIENT_VERSION = "19.07.5"; + public static String CLIENT_VERSION = "19.45.4"; public static ClientConfig BASE_CONFIG = new ClientConfig() .withApiKey("AIzaSyB-63vPrdThhKuerbB2N_l7Kwwcxj6yUAc") - .withUserAgent(String.format("com.google.ios.youtube/%s (iPhone14,5; U; CPU iOS 15_6 like Mac OS X)", CLIENT_VERSION)) + .withUserAgent(String.format("com.google.ios.youtube/%s (iPhone16,2; U; CPU iOS 18_1_0 like Mac OS X;)", CLIENT_VERSION)) .withClientName("IOS") .withClientField("clientVersion", CLIENT_VERSION) .withUserField("lockedSafetyMode", false); @@ -49,6 +49,15 @@ protected JsonBrowser extractPlaylistVideoList(@NotNull JsonBrowser json) { .get("playlistVideoListRenderer"); } + @Override + @NotNull + protected String extractPlaylistName(@NotNull JsonBrowser json) { + return json.get("header") + .get("pageHeaderRenderer") + .get("pageTitle") + .text(); + } + @Override @NotNull public String getPlayerParams() { diff --git a/common/src/main/java/dev/lavalink/youtube/clients/MWeb.java b/common/src/main/java/dev/lavalink/youtube/clients/MWeb.java new file mode 100644 index 0000000..42a2ba0 --- /dev/null +++ b/common/src/main/java/dev/lavalink/youtube/clients/MWeb.java @@ -0,0 +1,67 @@ +package dev.lavalink.youtube.clients; + +import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; +import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; +import org.jetbrains.annotations.NotNull; + +public class MWeb extends Web { + public static ClientConfig BASE_CONFIG = new ClientConfig() + .withApiKey("AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8") + .withClientName("MWEB") + .withClientField("clientVersion", "2.20240726.11.00"); + + public MWeb() { + super(); + } + + public MWeb(@NotNull ClientOptions options) { + super(options); + } + + @Override + @NotNull + public ClientConfig getBaseClientConfig(@NotNull HttpInterface httpInterface) { + return BASE_CONFIG.copy(); + } + + @Override + @NotNull + protected JsonBrowser extractMixPlaylistData(@NotNull JsonBrowser json) { + return json.get("contents") + .get("singleColumnWatchNextResults") + .get("playlist") + .get("playlist"); + } + + @Override + protected String extractPlaylistName(@NotNull JsonBrowser json) { + return json.get("header") + .get("pageHeaderRenderer") + .get("pageTitle") + .text(); + } + + @Override + @NotNull + protected JsonBrowser extractPlaylistVideoList(@NotNull JsonBrowser json) { + return json.get("contents") + .get("singleColumnBrowseResultsRenderer") + .get("tabs") + .index(0) + .get("tabRenderer") + .get("content") + .get("sectionListRenderer") + .get("contents") + .index(0) + .get("itemSectionRenderer") + .get("contents") + .index(0) + .get("playlistVideoListRenderer"); + } + + @Override + @NotNull + public String getIdentifier() { + return BASE_CONFIG.getName(); + } +} diff --git a/common/src/main/java/dev/lavalink/youtube/clients/MediaConnect.java b/common/src/main/java/dev/lavalink/youtube/clients/MediaConnect.java deleted file mode 100644 index f6e99b3..0000000 --- a/common/src/main/java/dev/lavalink/youtube/clients/MediaConnect.java +++ /dev/null @@ -1,75 +0,0 @@ -package dev.lavalink.youtube.clients; - -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import dev.lavalink.youtube.YoutubeAudioSourceManager; -import dev.lavalink.youtube.clients.skeleton.StreamingNonMusicClient; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class MediaConnect extends StreamingNonMusicClient { - public static ClientConfig BASE_CONFIG = new ClientConfig() - .withClientName("MEDIA_CONNECT_FRONTEND") - .withClientField("clientVersion", "0.1"); - - protected ClientOptions options; - - public MediaConnect() { - this(ClientOptions.DEFAULT); - } - - public MediaConnect(@NotNull ClientOptions options) { - this.options = options; - } - - @Override - @NotNull - protected ClientConfig getBaseClientConfig(@NotNull HttpInterface httpInterface) { - return BASE_CONFIG.copy(); - } - - @Override - @NotNull - public String getPlayerParams() { - return MOBILE_PLAYER_PARAMS; - } - - @Override - @NotNull - public ClientOptions getOptions() { - return this.options; - } - - @Override - public boolean canHandleRequest(@NotNull String identifier) { - // This client appears to be able to load livestreams and videos, but will - // receive 400 bad request when loading playlists. mixes do return JSON, but does not contain mix videos. - return !identifier.startsWith(YoutubeAudioSourceManager.SEARCH_PREFIX) && !identifier.contains("list=") && super.canHandleRequest(identifier); - } - - @Override - @NotNull - public String getIdentifier() { - return BASE_CONFIG.getName(); - } - - @Override - public AudioItem loadSearch(@NotNull YoutubeAudioSourceManager source, @NotNull HttpInterface httpInterface, @NotNull String searchQuery) { - throw new FriendlyException("This client cannot load searches", Severity.COMMON, - new RuntimeException("MEDIA_CONNECT cannot be used to load searches")); - } - - @Override - public AudioItem loadPlaylist(@NotNull YoutubeAudioSourceManager source, @NotNull HttpInterface httpInterface, @NotNull String playlistId, @Nullable String selectedVideoId) { - throw new FriendlyException("This client cannot load playlists", Severity.COMMON, - new RuntimeException("MEDIA_CONNECT cannot be used to load playlists")); - } - - @Override - public AudioItem loadMix(@NotNull YoutubeAudioSourceManager source, @NotNull HttpInterface httpInterface, @NotNull String mixId, @Nullable String selectedVideoId) { - throw new FriendlyException("This client cannot load mixes", Severity.COMMON, - new RuntimeException("MEDIA_CONNECT cannot be used to load mixes")); - } -} diff --git a/common/src/main/java/dev/lavalink/youtube/clients/Music.java b/common/src/main/java/dev/lavalink/youtube/clients/Music.java index 6d8d287..610c537 100644 --- a/common/src/main/java/dev/lavalink/youtube/clients/Music.java +++ b/common/src/main/java/dev/lavalink/youtube/clients/Music.java @@ -8,7 +8,7 @@ public class Music extends MusicClient { public static ClientConfig BASE_CONFIG = new ClientConfig() .withApiKey("AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30") // Requires header (Referer music.youtube.com) .withClientName("WEB_REMIX") - .withClientField("clientVersion", "1.20240401.00.00"); + .withClientField("clientVersion", "1.20240724.00.00"); protected ClientOptions options; diff --git a/common/src/main/java/dev/lavalink/youtube/clients/TvHtml5Embedded.java b/common/src/main/java/dev/lavalink/youtube/clients/TvHtml5Embedded.java index 073687b..3fe8694 100644 --- a/common/src/main/java/dev/lavalink/youtube/clients/TvHtml5Embedded.java +++ b/common/src/main/java/dev/lavalink/youtube/clients/TvHtml5Embedded.java @@ -105,6 +105,11 @@ public boolean canHandleRequest(@NotNull String identifier) { return (!identifier.contains("list=") || identifier.contains("list=RD")) && super.canHandleRequest(identifier); } + @Override + public boolean supportsOAuth() { + return true; + } + @Override @NotNull public String getIdentifier() { diff --git a/common/src/main/java/dev/lavalink/youtube/clients/WebEmbedded.java b/common/src/main/java/dev/lavalink/youtube/clients/WebEmbedded.java index 6ee7d38..413a286 100644 --- a/common/src/main/java/dev/lavalink/youtube/clients/WebEmbedded.java +++ b/common/src/main/java/dev/lavalink/youtube/clients/WebEmbedded.java @@ -20,7 +20,7 @@ public class WebEmbedded extends Web { public static ClientConfig BASE_CONFIG = new ClientConfig() .withApiKey("AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8") .withClientName("WEB_EMBEDDED_PLAYER") - .withClientField("clientVersion", "1.20240902.00.00") + .withClientField("clientVersion", "1.20240723.01.00") .withUserField("lockedSafetyMode", false); public WebEmbedded() { diff --git a/common/src/main/java/dev/lavalink/youtube/clients/skeleton/Client.java b/common/src/main/java/dev/lavalink/youtube/clients/skeleton/Client.java index 74cf41f..eebc54f 100644 --- a/common/src/main/java/dev/lavalink/youtube/clients/skeleton/Client.java +++ b/common/src/main/java/dev/lavalink/youtube/clients/skeleton/Client.java @@ -25,6 +25,8 @@ * The interface for a Client. */ public interface Client { + String OAUTH_CLIENT_ATTRIBUTE = "yt-oauth-enabled-client"; + String WATCH_URL = "https://www.youtube.com/watch?v="; String API_BASE_URL = "https://youtubei.googleapis.com/youtubei/v1"; String PLAYER_URL = API_BASE_URL + "/player?prettyPrint=false"; @@ -208,6 +210,13 @@ default boolean isEmbedded() { return false; } + /** + * @return True, if this client supports account linking via OAuth (i.e. TV) + */ + default boolean supportsOAuth() { + return false; + } + void setPlaylistPageCount(int count); /** diff --git a/common/src/main/java/dev/lavalink/youtube/http/YoutubeHttpContextFilter.java b/common/src/main/java/dev/lavalink/youtube/http/YoutubeHttpContextFilter.java index 939c73c..03ba527 100644 --- a/common/src/main/java/dev/lavalink/youtube/http/YoutubeHttpContextFilter.java +++ b/common/src/main/java/dev/lavalink/youtube/http/YoutubeHttpContextFilter.java @@ -3,6 +3,7 @@ import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; import com.sedmelluq.discord.lavaplayer.tools.http.HttpContextRetryCounter; import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; +import dev.lavalink.youtube.clients.skeleton.Client; import org.apache.http.HttpResponse; import org.apache.http.client.CookieStore; import org.apache.http.client.methods.HttpUriRequest; @@ -79,7 +80,12 @@ public void onRequest(HttpClientContext context, context.removeAttribute(ATTRIBUTE_USER_AGENT_SPECIFIED); } - oauth2Handler.applyToken(request); + boolean isRequestFromOauthedClient = context.getAttribute(Client.OAUTH_CLIENT_ATTRIBUTE) == Boolean.TRUE; + + if (isRequestFromOauthedClient && Client.PLAYER_URL.equals(request.getURI().toString())) { + // only apply the token to /player requests. + oauth2Handler.applyToken(request); + } } // try { diff --git a/common/src/main/java/dev/lavalink/youtube/http/YoutubeOauth2Handler.java b/common/src/main/java/dev/lavalink/youtube/http/YoutubeOauth2Handler.java index 340697a..7540333 100644 --- a/common/src/main/java/dev/lavalink/youtube/http/YoutubeOauth2Handler.java +++ b/common/src/main/java/dev/lavalink/youtube/http/YoutubeOauth2Handler.java @@ -9,6 +9,7 @@ import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; +import dev.lavalink.youtube.clients.skeleton.Client; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpUriRequest; diff --git a/common/src/main/java/dev/lavalink/youtube/track/YoutubeAudioTrack.java b/common/src/main/java/dev/lavalink/youtube/track/YoutubeAudioTrack.java index 4ad6259..0fe4c1d 100644 --- a/common/src/main/java/dev/lavalink/youtube/track/YoutubeAudioTrack.java +++ b/common/src/main/java/dev/lavalink/youtube/track/YoutubeAudioTrack.java @@ -68,6 +68,8 @@ public void process(LocalAudioTrackExecutor localExecutor) throws Exception { continue; } + httpInterface.getContext().setAttribute(Client.OAUTH_CLIENT_ATTRIBUTE, client.supportsOAuth()); + try { processWithClient(localExecutor, httpInterface, client, 0); return; // stream played through successfully, short-circuit. diff --git a/plugin/src/main/java/dev/lavalink/youtube/plugin/ClientProviderV3.java b/plugin/src/main/java/dev/lavalink/youtube/plugin/ClientProviderV3.java index 5ff0712..ffc8a58 100644 --- a/plugin/src/main/java/dev/lavalink/youtube/plugin/ClientProviderV3.java +++ b/plugin/src/main/java/dev/lavalink/youtube/plugin/ClientProviderV3.java @@ -11,8 +11,6 @@ public Client[] getClients(String[] clients, OptionsProvider optionsProvider) { private enum ClientMapping implements ClientReference { ANDROID(Android::new), - ANDROID_TESTSUITE(AndroidTestsuite::new), - ANDROID_LITE(AndroidLite::new), ANDROID_MUSIC(AndroidMusic::new), ANDROID_VR(AndroidVr::new), IOS(Ios::new), @@ -20,7 +18,7 @@ private enum ClientMapping implements ClientReference { TVHTML5EMBEDDED(TvHtml5Embedded::new), WEB(Web::new), WEBEMBEDDED(WebEmbedded::new), - MEDIA_CONNECT(MediaConnect::new); + MWEB(MWeb::new); private final ClientWithOptions clientFactory; diff --git a/plugin/src/main/java/dev/lavalink/youtube/plugin/ClientProviderV4.java b/plugin/src/main/java/dev/lavalink/youtube/plugin/ClientProviderV4.java index 25658f8..0bd91d9 100644 --- a/plugin/src/main/java/dev/lavalink/youtube/plugin/ClientProviderV4.java +++ b/plugin/src/main/java/dev/lavalink/youtube/plugin/ClientProviderV4.java @@ -2,7 +2,6 @@ import dev.lavalink.youtube.clients.*; import dev.lavalink.youtube.clients.skeleton.Client; -import dev.lavalink.youtube.clients.WebEmbeddedWithThumbnail; public class ClientProviderV4 implements ClientProvider { @Override @@ -12,8 +11,6 @@ public Client[] getClients(String[] clients, OptionsProvider optionsProvider) { private enum ClientMapping implements ClientReference { ANDROID(AndroidWithThumbnail::new), - ANDROID_TESTSUITE(AndroidTestsuiteWithThumbnail::new), - ANDROID_LITE(AndroidLiteWithThumbnail::new), ANDROID_MUSIC(AndroidMusicWithThumbnail::new), ANDROID_VR(AndroidVrWithThumbnail::new), IOS(IosWithThumbnail::new), @@ -21,7 +18,7 @@ private enum ClientMapping implements ClientReference { TVHTML5EMBEDDED(TvHtml5EmbeddedWithThumbnail::new), WEB(WebWithThumbnail::new), WEBEMBEDDED(WebEmbeddedWithThumbnail::new), - MEDIA_CONNECT(MediaConnectWithThumbnail::new); + MWEB(MWebWithThumbnail::new); private final ClientWithOptions clientFactory; diff --git a/v2/src/main/java/dev/lavalink/youtube/clients/AndroidTestsuiteWithThumbnail.java b/v2/src/main/java/dev/lavalink/youtube/clients/AndroidTestsuiteWithThumbnail.java deleted file mode 100644 index b0fe176..0000000 --- a/v2/src/main/java/dev/lavalink/youtube/clients/AndroidTestsuiteWithThumbnail.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.lavalink.youtube.clients; - -import dev.lavalink.youtube.clients.skeleton.NonMusicClientWithThumbnail; -import org.jetbrains.annotations.NotNull; - -public class AndroidTestsuiteWithThumbnail extends AndroidTestsuite implements NonMusicClientWithThumbnail { - public AndroidTestsuiteWithThumbnail() { - super(); - } - - public AndroidTestsuiteWithThumbnail(@NotNull ClientOptions options) { - super(options); - } -} diff --git a/v2/src/main/java/dev/lavalink/youtube/clients/AndroidLiteWithThumbnail.java b/v2/src/main/java/dev/lavalink/youtube/clients/MWebWithThumbnail.java similarity index 50% rename from v2/src/main/java/dev/lavalink/youtube/clients/AndroidLiteWithThumbnail.java rename to v2/src/main/java/dev/lavalink/youtube/clients/MWebWithThumbnail.java index 828bf9d..17019f0 100644 --- a/v2/src/main/java/dev/lavalink/youtube/clients/AndroidLiteWithThumbnail.java +++ b/v2/src/main/java/dev/lavalink/youtube/clients/MWebWithThumbnail.java @@ -3,12 +3,12 @@ import dev.lavalink.youtube.clients.skeleton.NonMusicClientWithThumbnail; import org.jetbrains.annotations.NotNull; -public class AndroidLiteWithThumbnail extends AndroidLite implements NonMusicClientWithThumbnail { - public AndroidLiteWithThumbnail() { +public class MWebWithThumbnail extends MWeb implements NonMusicClientWithThumbnail { + public MWebWithThumbnail() { super(); } - public AndroidLiteWithThumbnail(@NotNull ClientOptions options) { + public MWebWithThumbnail(@NotNull ClientOptions options) { super(options); } } diff --git a/v2/src/main/java/dev/lavalink/youtube/clients/MediaConnectWithThumbnail.java b/v2/src/main/java/dev/lavalink/youtube/clients/MediaConnectWithThumbnail.java deleted file mode 100644 index 37fee8e..0000000 --- a/v2/src/main/java/dev/lavalink/youtube/clients/MediaConnectWithThumbnail.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.lavalink.youtube.clients; - -import dev.lavalink.youtube.clients.skeleton.NonMusicClientWithThumbnail; -import org.jetbrains.annotations.NotNull; - -public class MediaConnectWithThumbnail extends MediaConnect implements NonMusicClientWithThumbnail { - public MediaConnectWithThumbnail() { - super(); - } - - public MediaConnectWithThumbnail(@NotNull ClientOptions options) { - super(options); - } -}