From 0952431121f49a97c3ad289971e12ccf44410501 Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Fri, 31 Jan 2025 21:38:31 +0100 Subject: [PATCH] [YouTube] Move InnertubeClientRequestInfo creations in class' methods This commits provides methods to get InnertubeClientRequestInfo instances, which can be used by extractor clients to get visitor data to pass to PoTokenProvider implementations using YoutubeParsingHelper. Ability to create custom instances has been removed, but returned objects can be modified. This is what YoutubeStreamHelper now uses to set the visitorData property. --- .../youtube/InnertubeClientRequestInfo.java | 101 ++++++++++++-- .../services/youtube/YoutubeStreamHelper.java | 131 ++---------------- 2 files changed, 100 insertions(+), 132 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/InnertubeClientRequestInfo.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/InnertubeClientRequestInfo.java index c1a91b0f9..c8848b086 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/InnertubeClientRequestInfo.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/InnertubeClientRequestInfo.java @@ -1,8 +1,35 @@ package org.schabi.newpipe.extractor.services.youtube; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.ANDROID_CLIENT_ID; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.ANDROID_CLIENT_NAME; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.ANDROID_CLIENT_VERSION; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.DESKTOP_CLIENT_PLATFORM; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.EMBED_CLIENT_SCREEN; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.IOS_CLIENT_ID; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.IOS_CLIENT_NAME; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.IOS_CLIENT_VERSION; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.IOS_DEVICE_MODEL; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.IOS_OS_VERSION; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.MOBILE_CLIENT_PLATFORM; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_CLIENT_ID; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_CLIENT_NAME; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_CLIENT_PLATFORM; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_CLIENT_VERSION; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_DEVICE_MAKE; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_DEVICE_MODEL_AND_OS_NAME; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WATCH_CLIENT_SCREEN; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_CLIENT_ID; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_CLIENT_NAME; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_EMBEDDED_CLIENT_ID; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_EMBEDDED_CLIENT_NAME; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_HARDCODED_CLIENT_VERSION; +import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_REMIX_HARDCODED_CLIENT_VERSION; + import javax.annotation.Nonnull; import javax.annotation.Nullable; +// TODO: add docs + public final class InnertubeClientRequestInfo { @Nonnull @@ -23,11 +50,11 @@ public final class InnertubeClientRequestInfo { @Nullable public String visitorData; - public ClientInfo(@Nonnull final String clientName, - @Nonnull final String clientVersion, - @Nonnull final String clientScreen, - @Nullable final String clientId, - @Nullable final String visitorData) { + private ClientInfo(@Nonnull final String clientName, + @Nonnull final String clientVersion, + @Nonnull final String clientScreen, + @Nullable final String clientId, + @Nullable final String visitorData) { this.clientName = clientName; this.clientVersion = clientVersion; this.clientScreen = clientScreen; @@ -50,12 +77,12 @@ public final class InnertubeClientRequestInfo { public String osVersion; public int androidSdkVersion; - public DeviceInfo(@Nonnull final String platform, - @Nullable final String deviceMake, - @Nullable final String deviceModel, - @Nullable final String osName, - @Nullable final String osVersion, - final int androidSdkVersion) { + private DeviceInfo(@Nonnull final String platform, + @Nullable final String deviceMake, + @Nullable final String deviceModel, + @Nullable final String osName, + @Nullable final String osVersion, + final int androidSdkVersion) { this.platform = platform; this.deviceMake = deviceMake; this.deviceModel = deviceModel; @@ -65,9 +92,57 @@ public final class InnertubeClientRequestInfo { } } - public InnertubeClientRequestInfo(@Nonnull final ClientInfo clientInfo, - @Nonnull final DeviceInfo deviceInfo) { + private InnertubeClientRequestInfo(@Nonnull final ClientInfo clientInfo, + @Nonnull final DeviceInfo deviceInfo) { this.clientInfo = clientInfo; this.deviceInfo = deviceInfo; } + + @Nonnull + public static InnertubeClientRequestInfo ofWebClient() { + return new InnertubeClientRequestInfo( + new InnertubeClientRequestInfo.ClientInfo( + WEB_CLIENT_NAME, WEB_HARDCODED_CLIENT_VERSION, WATCH_CLIENT_SCREEN, + WEB_CLIENT_ID, null), + new InnertubeClientRequestInfo.DeviceInfo(DESKTOP_CLIENT_PLATFORM, null, null, + null, null, -1)); + } + + @Nonnull + public static InnertubeClientRequestInfo ofWebEmbeddedPlayerClient() { + return new InnertubeClientRequestInfo( + new InnertubeClientRequestInfo.ClientInfo(WEB_EMBEDDED_CLIENT_NAME, + WEB_REMIX_HARDCODED_CLIENT_VERSION, EMBED_CLIENT_SCREEN, + WEB_EMBEDDED_CLIENT_ID, null), + new InnertubeClientRequestInfo.DeviceInfo(DESKTOP_CLIENT_PLATFORM, null, null, + null, null, -1)); + } + + @Nonnull + public static InnertubeClientRequestInfo ofTvHtml5Client() { + return new InnertubeClientRequestInfo( + new InnertubeClientRequestInfo.ClientInfo(TVHTML5_CLIENT_NAME, + TVHTML5_CLIENT_VERSION, WATCH_CLIENT_SCREEN, TVHTML5_CLIENT_ID, null), + new InnertubeClientRequestInfo.DeviceInfo(TVHTML5_CLIENT_PLATFORM, + TVHTML5_DEVICE_MAKE, TVHTML5_DEVICE_MODEL_AND_OS_NAME, + TVHTML5_DEVICE_MODEL_AND_OS_NAME, "", -1)); + } + + @Nonnull + public static InnertubeClientRequestInfo ofAndroidClient() { + return new InnertubeClientRequestInfo( + new InnertubeClientRequestInfo.ClientInfo(ANDROID_CLIENT_NAME, + ANDROID_CLIENT_VERSION, WATCH_CLIENT_SCREEN, ANDROID_CLIENT_ID, null), + new InnertubeClientRequestInfo.DeviceInfo(MOBILE_CLIENT_PLATFORM, null, null, + "Android", "15", 35)); + } + + @Nonnull + public static InnertubeClientRequestInfo ofIosClient() { + return new InnertubeClientRequestInfo( + new InnertubeClientRequestInfo.ClientInfo(IOS_CLIENT_NAME, IOS_CLIENT_VERSION, + WATCH_CLIENT_SCREEN, IOS_CLIENT_ID, null), + new InnertubeClientRequestInfo.DeviceInfo(MOBILE_CLIENT_PLATFORM, "Apple", + IOS_DEVICE_MODEL, "iOS", IOS_OS_VERSION, -1)); + } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamHelper.java index 9f005299b..1eb56f250 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamHelper.java @@ -17,31 +17,11 @@ import java.util.List; import java.util.Map; import static org.schabi.newpipe.extractor.NewPipe.getDownloader; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.ANDROID_CLIENT_ID; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.ANDROID_CLIENT_NAME; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.ANDROID_CLIENT_VERSION; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.DESKTOP_CLIENT_PLATFORM; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.EMBED_CLIENT_SCREEN; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.IOS_CLIENT_ID; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.IOS_CLIENT_NAME; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.IOS_CLIENT_VERSION; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.IOS_DEVICE_MODEL; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.IOS_OS_VERSION; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.MOBILE_CLIENT_PLATFORM; import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_CLIENT_ID; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_CLIENT_NAME; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_CLIENT_PLATFORM; import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_CLIENT_VERSION; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_DEVICE_MAKE; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_DEVICE_MODEL_AND_OS_NAME; import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.TVHTML5_USER_AGENT; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WATCH_CLIENT_SCREEN; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_CLIENT_ID; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_CLIENT_NAME; import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_EMBEDDED_CLIENT_ID; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_EMBEDDED_CLIENT_NAME; import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_EMBEDDED_CLIENT_VERSION; -import static org.schabi.newpipe.extractor.services.youtube.ClientsConstants.WEB_REMIX_HARDCODED_CLIENT_VERSION; import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.CONTENT_CHECK_OK; import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.CPN; import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.DISABLE_PRETTY_PRINT_PARAMETER; @@ -75,20 +55,8 @@ public final class YoutubeStreamHelper { @Nonnull final ContentCountry contentCountry, @Nonnull final String videoId) throws IOException, ExtractionException { final InnertubeClientRequestInfo innertubeClientRequestInfo = - new InnertubeClientRequestInfo( - new InnertubeClientRequestInfo.ClientInfo( - WEB_CLIENT_NAME, - getClientVersion(), - WATCH_CLIENT_SCREEN, - WEB_CLIENT_ID, - null), - new InnertubeClientRequestInfo.DeviceInfo( - DESKTOP_CLIENT_PLATFORM, - null, - null, - null, - null, - -1)); + InnertubeClientRequestInfo.ofWebClient(); + innertubeClientRequestInfo.clientInfo.clientVersion = getClientVersion(); final Map> headers = getYouTubeHeaders(); @@ -122,20 +90,7 @@ public final class YoutubeStreamHelper { @Nonnull final String cpn, final int signatureTimestamp) throws IOException, ExtractionException { final InnertubeClientRequestInfo innertubeClientRequestInfo = - new InnertubeClientRequestInfo( - new InnertubeClientRequestInfo.ClientInfo( - TVHTML5_CLIENT_NAME, - TVHTML5_CLIENT_VERSION, - WATCH_CLIENT_SCREEN, - TVHTML5_CLIENT_ID, - null), - new InnertubeClientRequestInfo.DeviceInfo( - TVHTML5_CLIENT_PLATFORM, - TVHTML5_DEVICE_MAKE, - TVHTML5_DEVICE_MODEL_AND_OS_NAME, - TVHTML5_DEVICE_MODEL_AND_OS_NAME, - "", - -1)); + InnertubeClientRequestInfo.ofTvHtml5Client(); final Map> headers = new HashMap<>( getClientHeaders(TVHTML5_CLIENT_ID, TVHTML5_CLIENT_VERSION)); @@ -175,20 +130,9 @@ public final class YoutubeStreamHelper { @Nonnull final PoTokenResult webPoTokenResult, final int signatureTimestamp) throws IOException, ExtractionException { final InnertubeClientRequestInfo innertubeClientRequestInfo = - new InnertubeClientRequestInfo( - new InnertubeClientRequestInfo.ClientInfo( - WEB_CLIENT_NAME, - getClientVersion(), - WATCH_CLIENT_SCREEN, - WEB_CLIENT_ID, - webPoTokenResult.visitorData), - new InnertubeClientRequestInfo.DeviceInfo( - DESKTOP_CLIENT_PLATFORM, - null, - null, - null, - null, - -1)); + InnertubeClientRequestInfo.ofWebClient(); + innertubeClientRequestInfo.clientInfo.clientVersion = getClientVersion(); + innertubeClientRequestInfo.clientInfo.visitorData = webPoTokenResult.visitorData; final JsonBuilder builder = prepareJsonBuilder(localization, contentCountry, innertubeClientRequestInfo, null); @@ -199,7 +143,7 @@ public final class YoutubeStreamHelper { addPoToken(builder, webPoTokenResult.playerRequestPoToken); - final byte[] body = JsonWriter.string(builder.end().done()) + final byte[] body = JsonWriter.string(builder.done()) .getBytes(StandardCharsets.UTF_8); final String url = YOUTUBEI_V1_URL + PLAYER + "?" + DISABLE_PRETTY_PRINT_PARAMETER; @@ -218,20 +162,7 @@ public final class YoutubeStreamHelper { @Nullable final PoTokenResult webEmbeddedPoTokenResult, final int signatureTimestamp) throws IOException, ExtractionException { final InnertubeClientRequestInfo innertubeClientRequestInfo = - new InnertubeClientRequestInfo( - new InnertubeClientRequestInfo.ClientInfo( - WEB_EMBEDDED_CLIENT_NAME, - WEB_REMIX_HARDCODED_CLIENT_VERSION, - EMBED_CLIENT_SCREEN, - WEB_EMBEDDED_CLIENT_ID, - null), - new InnertubeClientRequestInfo.DeviceInfo( - DESKTOP_CLIENT_PLATFORM, - null, - null, - null, - null, - -1)); + InnertubeClientRequestInfo.ofWebEmbeddedPlayerClient(); final Map> headers = new HashMap<>( getClientHeaders(WEB_EMBEDDED_CLIENT_ID, WEB_EMBEDDED_CLIENT_VERSION)); @@ -273,20 +204,8 @@ public final class YoutubeStreamHelper { @Nonnull final PoTokenResult androidPoTokenResult) throws IOException, ExtractionException { final InnertubeClientRequestInfo innertubeClientRequestInfo = - new InnertubeClientRequestInfo( - new InnertubeClientRequestInfo.ClientInfo( - ANDROID_CLIENT_NAME, - ANDROID_CLIENT_VERSION, - WATCH_CLIENT_SCREEN, - ANDROID_CLIENT_ID, - androidPoTokenResult.visitorData), - new InnertubeClientRequestInfo.DeviceInfo( - MOBILE_CLIENT_PLATFORM, - null, - null, - "Android", - "15", - 35)); + InnertubeClientRequestInfo.ofAndroidClient(); + innertubeClientRequestInfo.clientInfo.visitorData = androidPoTokenResult.visitorData; final Map> headers = getMobileClientHeaders(getAndroidUserAgent(localization)); @@ -314,20 +233,7 @@ public final class YoutubeStreamHelper { @Nonnull final String videoId, @Nonnull final String cpn) throws IOException, ExtractionException { final InnertubeClientRequestInfo innertubeClientRequestInfo = - new InnertubeClientRequestInfo( - new InnertubeClientRequestInfo.ClientInfo( - ANDROID_CLIENT_NAME, - ANDROID_CLIENT_VERSION, - WATCH_CLIENT_SCREEN, - ANDROID_CLIENT_ID, - null), - new InnertubeClientRequestInfo.DeviceInfo( - MOBILE_CLIENT_PLATFORM, - null, - null, - "Android", - "15", - 35)); + InnertubeClientRequestInfo.ofAndroidClient(); final Map> headers = getMobileClientHeaders(getAndroidUserAgent(localization)); @@ -367,20 +273,7 @@ public final class YoutubeStreamHelper { @Nullable final PoTokenResult iosPoTokenResult) throws IOException, ExtractionException { final InnertubeClientRequestInfo innertubeClientRequestInfo = - new InnertubeClientRequestInfo( - new InnertubeClientRequestInfo.ClientInfo( - IOS_CLIENT_NAME, - IOS_CLIENT_VERSION, - WATCH_CLIENT_SCREEN, - IOS_CLIENT_ID, - null), - new InnertubeClientRequestInfo.DeviceInfo( - MOBILE_CLIENT_PLATFORM, - "Apple", - IOS_DEVICE_MODEL, - "iOS", - IOS_OS_VERSION, - -1)); + InnertubeClientRequestInfo.ofIosClient(); final Map> headers = getMobileClientHeaders(getIosUserAgent(localization));