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 3377bc7..6ee7d38 100644 --- a/common/src/main/java/dev/lavalink/youtube/clients/WebEmbedded.java +++ b/common/src/main/java/dev/lavalink/youtube/clients/WebEmbedded.java @@ -7,8 +7,12 @@ import dev.lavalink.youtube.YoutubeAudioSourceManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.net.URISyntaxException; +import java.util.Map; +import org.apache.http.client.utils.URIBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.net.URI; public class WebEmbedded extends Web { private static final Logger log = LoggerFactory.getLogger(WebEmbedded.class); @@ -16,13 +20,51 @@ public class WebEmbedded extends Web { public static ClientConfig BASE_CONFIG = new ClientConfig() .withApiKey("AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8") .withClientName("WEB_EMBEDDED_PLAYER") - .withClientField("clientVersion", "1.20240806.01.00") + .withClientField("clientVersion", "1.20240902.00.00") .withUserField("lockedSafetyMode", false); public WebEmbedded() { super(ClientOptions.DEFAULT); } + public static void setPoTokenAndVisitorData(String poToken, String visitorData) { + WebEmbedded.poToken = poToken; + + if (poToken == null || visitorData == null) { + BASE_CONFIG.getRoot().remove("serviceIntegrityDimensions"); + BASE_CONFIG.withVisitorData(null); + return; + } + + Map sid = BASE_CONFIG.putOnceAndJoin(BASE_CONFIG.getRoot(), "serviceIntegrityDimensions"); + sid.put("poToken", poToken); + BASE_CONFIG.withVisitorData(visitorData); + } + + @Override + public boolean isEmbedded() { + return true; + } + + @Override + @NotNull + public URI transformPlaybackUri(@NotNull URI originalUri, @NotNull URI resolvedPlaybackUri) { + if (poToken == null) { + return resolvedPlaybackUri; + } + + log.debug("Applying 'pot' parameter on playback URI: {}", resolvedPlaybackUri); + URIBuilder builder = new URIBuilder(resolvedPlaybackUri); + builder.addParameter("pot", poToken); + + try { + return builder.build(); + } catch (URISyntaxException e) { + log.debug("Failed to apply 'pot' parameter.", e); + return resolvedPlaybackUri; + } + } + public WebEmbedded(@NotNull ClientOptions options) { super(options); } 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 d2450b8..3f0ae13 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 @@ -203,6 +203,11 @@ default boolean supportsFormatLoading() { return getOptions().getPlayback(); } + + default boolean isEmbedded() { + return false; + } + void setPlaylistPageCount(int count); /** diff --git a/common/src/main/java/dev/lavalink/youtube/clients/skeleton/NonMusicClient.java b/common/src/main/java/dev/lavalink/youtube/clients/skeleton/NonMusicClient.java index 8d34795..f306721 100644 --- a/common/src/main/java/dev/lavalink/youtube/clients/skeleton/NonMusicClient.java +++ b/common/src/main/java/dev/lavalink/youtube/clients/skeleton/NonMusicClient.java @@ -101,6 +101,11 @@ protected JsonBrowser loadTrackInfoFromInnertube(@NotNull YoutubeAudioSourceMana // All other branches should've been caught by getPlayabilityStatus(). // An exception will be thrown if we can't handle it. if (playabilityStatus == PlayabilityStatus.NON_EMBEDDABLE) { + if (isEmbedded()) { + throw new FriendlyException("Loading information for for video failed", Severity.COMMON, + new RuntimeException("Non-embeddable video cannot be loaded by embedded client")); + } + json = loadTrackInfoFromInnertube(source, httpInterface, videoId, status); getPlayabilityStatus(json.get("playabilityStatus"), true); } diff --git a/plugin/src/main/java/dev/lavalink/youtube/plugin/YoutubePluginLoader.java b/plugin/src/main/java/dev/lavalink/youtube/plugin/YoutubePluginLoader.java index 6776c6e..2f989b5 100644 --- a/plugin/src/main/java/dev/lavalink/youtube/plugin/YoutubePluginLoader.java +++ b/plugin/src/main/java/dev/lavalink/youtube/plugin/YoutubePluginLoader.java @@ -10,6 +10,7 @@ import dev.lavalink.youtube.YoutubeAudioSourceManager; import dev.lavalink.youtube.clients.ClientOptions; import dev.lavalink.youtube.clients.Web; +import dev.lavalink.youtube.clients.WebEmbedded; import dev.lavalink.youtube.clients.skeleton.Client; import lavalink.server.config.RateLimitConfig; import lavalink.server.config.ServerConfig; @@ -169,7 +170,8 @@ public AudioPlayerManager configure(AudioPlayerManager audioPlayerManager) { String visitorData = pot.getVisitorData(); if (token != null && visitorData != null) { - log.debug("Applying poToken and visitorData to WEB client (token: {}, vd: {})", token, visitorData); + log.debug("Applying poToken and visitorData to WEB & WEBEMBEDDED client (token: {}, vd: {})", token, visitorData); + WebEmbedded.setPoTokenAndVisitorData(token, visitorData); Web.setPoTokenAndVisitorData(token, visitorData); } else if (token != null || visitorData != null) { log.warn("Both pot.token and pot.visitorData must be specified and valid for pot to apply."); diff --git a/plugin/src/main/java/dev/lavalink/youtube/plugin/YoutubeRestHandler.java b/plugin/src/main/java/dev/lavalink/youtube/plugin/YoutubeRestHandler.java index abd127c..df3f602 100644 --- a/plugin/src/main/java/dev/lavalink/youtube/plugin/YoutubeRestHandler.java +++ b/plugin/src/main/java/dev/lavalink/youtube/plugin/YoutubeRestHandler.java @@ -4,6 +4,7 @@ import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; import dev.lavalink.youtube.YoutubeAudioSourceManager; import dev.lavalink.youtube.clients.Web; +import dev.lavalink.youtube.clients.WebEmbedded; import dev.lavalink.youtube.plugin.rest.MinimalConfigRequest; import dev.lavalink.youtube.plugin.rest.MinimalConfigResponse; import org.slf4j.Logger; @@ -55,6 +56,7 @@ public void updateYoutubeConfig(@RequestBody MinimalConfigRequest config) { String visitorData = config.getVisitorData(); if (poToken == null || visitorData == null || (!poToken.isEmpty() && !visitorData.isEmpty())) { + WebEmbedded.setPoTokenAndVisitorData(poToken, visitorData); Web.setPoTokenAndVisitorData(poToken, visitorData); log.debug("Updated poToken to \"{}\" and visitorData to \"{}\"", poToken, visitorData); }