From 5ffbb4714a9160dceff2f4c4e08bba2ca757d17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ho=C3=A0ng=20Gia=20B=E1=BA=A3o?= <70064328+YT-Advanced@users.noreply.github.com> Date: Wed, 18 Dec 2024 07:43:35 +0700 Subject: [PATCH] fix(Spoof Streaming Data): Performance degradation on iOS client (#110) * fix(Spoof Streaming Data): Apply workarounds to the correct client * Lint code * Lint * Correct the logic * Use `put` to update the client type * Fix build error * Fix logic * Apply HLS fix for all client * Remove unused method * fix: Apply code review suggestions * fix: Apply code review suggestions --------- Co-authored-by: inotia00 <108592928+inotia00@users.noreply.github.com> --- .../spoof/SpoofStreamingDataPatch.java | 65 +++++++++---------- .../spoof/requests/StreamingDataRequest.java | 1 - 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java index 6872eb7db..d61b4a039 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java @@ -1,5 +1,7 @@ package app.revanced.extension.shared.patches.spoof; +import static app.revanced.extension.shared.utils.Utils.isSDKAbove; + import android.net.Uri; import android.text.TextUtils; @@ -24,8 +26,8 @@ import app.revanced.extension.shared.utils.Utils; public class SpoofStreamingDataPatch extends BlockRequestPatch { /** - * key: videoId - * value: android StreamingData + * Key: videoId. + * Value: Original StreamingData of Android client. */ private static final Map streamingDataMap = Collections.synchronizedMap( new LinkedHashMap<>(10) { @@ -37,20 +39,6 @@ public class SpoofStreamingDataPatch extends BlockRequestPatch { } }); - /** - * key: android StreamingData - * value: fetched ClientType - */ - private static final Map clientTypeMap = Collections.synchronizedMap( - new LinkedHashMap<>(10) { - private static final int CACHE_LIMIT = 5; - - @Override - protected boolean removeEldestEntry(Entry eldest) { - return size() > CACHE_LIMIT; // Evict the oldest entry if over the cache limit. - } - }); - /** * Injection point. */ @@ -120,12 +108,25 @@ public class SpoofStreamingDataPatch extends BlockRequestPatch { var stream = request.getStream(); if (stream != null) { - Logger.printDebug(() -> "Overriding video stream: " + videoId); - // Put the videoId, originalStreamingData, and the clientType used for spoofing into a HashMap. - streamingDataMap.put(videoId, originalStreamingData); - clientTypeMap.put(originalStreamingData, stream.second); + ByteBuffer spoofedStreamingData = stream.first; + ClientType spoofedClientType = stream.second; - return stream.first; + Logger.printDebug(() -> "Overriding video stream: " + videoId); + + // Put the videoId and originalStreamingData into a HashMap. + if (spoofedClientType == ClientType.IOS) { + // For YT Music 6.20.51, which is supported by RVX, it can run on Android 5.0 (SDK 21). + // The IDE does not make any suggestions since the project's minSDK is 24, but you should check the SDK version for compatibility with SDK 21. + if (isSDKAbove(24)) { + streamingDataMap.putIfAbsent(videoId, originalStreamingData); + } else { + if (!streamingDataMap.containsKey(videoId)) { + streamingDataMap.put(videoId, originalStreamingData); + } + } + } + + return spoofedStreamingData; } } @@ -141,11 +142,14 @@ public class SpoofStreamingDataPatch extends BlockRequestPatch { /** * Injection point. *

- * It seems that some 'adaptiveFormats' are missing from the initial response of streaming data on iOS. - * Since the {@link FormatStreamModel} class for measuring the video length is not initialized on iOS clients, - * The video length field is always initialized to an estimated value, not the actual value. + * In iOS Clients, Progressive Streaming are not available, so 'formats' field have been removed + * completely from the initial response of streaming data. + * Therefore, {@link FormatStreamModel} class is never be initialized, and the video length field + * is set with an estimated value from `adaptiveFormats` instead. *

- * To fix this, replace streamingData (spoofedStreamingData) with originalStreamingData, which is only used to initialize the {@link FormatStreamModel} class to measure the video length. + * To get workaround with this, replace streamingData (spoofedStreamingData) with originalStreamingData, + * which is only used to initialize the {@link FormatStreamModel} class to calculate the video length. + * The playback issues shouldn't occur since the integrity check is not applied for Progressive Stream. *

* Called after {@link #getStreamingData(String, StreamingDataOuterClass$StreamingData)}. * @@ -156,15 +160,10 @@ public class SpoofStreamingDataPatch extends BlockRequestPatch { try { StreamingDataOuterClass$StreamingData androidStreamingData = streamingDataMap.get(videoId); if (androidStreamingData != null) { - ClientType clientType = clientTypeMap.get(androidStreamingData); - if (clientType == ClientType.IOS) { - Logger.printDebug(() -> "Overriding iOS streaming data to original streaming data: " + videoId); - return androidStreamingData; - } else { - Logger.printDebug(() -> "Not overriding original streaming data as spoofed client is not iOS: " + videoId + " (" + clientType + ")"); - } + Logger.printDebug(() -> "Overriding iOS streaming data to original streaming data: " + videoId); + return androidStreamingData; } else { - Logger.printDebug(() -> "Not overriding original streaming data (original streaming data is null): " + videoId); + Logger.printDebug(() -> "Not overriding original streaming data as spoofed client is not iOS: " + videoId); } } catch (Exception ex) { Logger.printException(() -> "getOriginalStreamingData failure", ex); diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.java b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.java index d7c9e8f83..63106ff15 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.java @@ -189,7 +189,6 @@ public class StreamingDataRequest { } else { try (InputStream inputStream = new BufferedInputStream(connection.getInputStream()); ByteArrayOutputStream baos = new ByteArrayOutputStream()) { - byte[] buffer = new byte[2048]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) >= 0) {