Skip to content

Commit

Permalink
chore: Merge branch dev to main (ReVanced#4192)
Browse files Browse the repository at this point in the history
  • Loading branch information
LisoUseInAIKyrios authored Dec 23, 2024
2 parents f7d5701 + d235bea commit dfcce5c
Show file tree
Hide file tree
Showing 58 changed files with 583 additions and 537 deletions.
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
## [5.7.1-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.4...v5.7.1-dev.5) (2024-12-22)


### Bug Fixes

* **YouTube - Spoof video streams:** Use 2 letter device language code ([33ff997](https://github.com/ReVanced/revanced-patches/commit/33ff9972000581aca92262f984efb114eeeb9537))

## [5.7.1-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.3...v5.7.1-dev.4) (2024-12-22)


### Bug Fixes

* **YouTube:** Do not reset playback speed to 1.0x after closing comment thread (Fixes stock YouTube bug) ([#4195](https://github.com/ReVanced/revanced-patches/issues/4195)) ([dda788c](https://github.com/ReVanced/revanced-patches/commit/dda788c58c789d4f91646ea8e8a8077f590ab6b3))

## [5.7.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.2...v5.7.1-dev.3) (2024-12-22)


### Bug Fixes

* **YouTube - SponsorBlock:** Show a toast and not a dialog if segment submitted successfully ([134b189](https://github.com/ReVanced/revanced-patches/commit/134b189791113dcf1a1cb7c87b8a0954f432730c))

## [5.7.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.1...v5.7.1-dev.2) (2024-12-22)


### Bug Fixes

* **YouTube - Theme:** Use dark theme color for status and navigation bar ([0240efe](https://github.com/ReVanced/revanced-patches/commit/0240efe33e5444625ca2b760c861c9046d3dc836))

## [5.7.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.7.0...v5.7.1-dev.1) (2024-12-22)


### Bug Fixes

* **YouTube - Spoof video streams:** Use Android VR authentication if using default audio language ([#4191](https://github.com/ReVanced/revanced-patches/issues/4191)) ([98773cc](https://github.com/ReVanced/revanced-patches/commit/98773cc7d46e5c9c7715b82c8006f1ccbcc5443c))

# [5.7.0](https://github.com/ReVanced/revanced-patches/compare/v5.6.0...v5.7.0) (2024-12-22)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.Locale;

import app.revanced.extension.shared.Utils;

public enum AudioStreamLanguage {
/**
* YouTube default.
Expand Down Expand Up @@ -65,8 +67,6 @@ public enum AudioStreamLanguage {
OR,
PA,
PL,
PT_BR,
PT_PT,
RO,
RU,
SI,
Expand All @@ -88,26 +88,19 @@ public enum AudioStreamLanguage {
ZH,
ZU;

private final String iso639_1;
private final String language;

AudioStreamLanguage() {
String name = name();
final int regionSeparatorIndex = name.indexOf('_');
if (regionSeparatorIndex >= 0) {
iso639_1 = name.substring(0, regionSeparatorIndex).toLowerCase(Locale.US)
+ name.substring(regionSeparatorIndex);
} else {
iso639_1 = name().toLowerCase(Locale.US);
}
language = name().toLowerCase(Locale.US);
}

public String getIso639_1() {
public String getLanguage() {
// Changing the app language does not force the app to completely restart,
// so the default needs to be the current language and not a static field.
if (this == DEFAULT) {
return Locale.getDefault().toLanguageTag();
return Locale.getDefault().getLanguage();
}

return iso639_1;
return language;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,6 @@ public enum ClientType {
"com.google.android.apps.youtube.unplugged/8.49.0 (Linux; U; Android 14; GB) gzip",
"34",
"8.49.0",
true), // Requires login.
ANDROID_CREATOR(
14,
"ANDROID_CREATOR",
"Android",
"11",
"com.google.android.apps.youtube.creator/24.45.100 (Linux; U; Android 11) gzip",
"30",
"24.45.100",
true); // Requires login.

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static String createInnertubeBody(ClientType clientType) {
JSONObject context = new JSONObject();

JSONObject client = new JSONObject();
client.put("hl", BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get().getIso639_1());
client.put("hl", BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get().getLanguage());
client.put("clientName", clientType.clientName);
client.put("clientVersion", clientType.clientVersion);
client.put("deviceModel", clientType.deviceModel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.spoof.AudioStreamLanguage;
import app.revanced.extension.shared.spoof.ClientType;

/**
Expand All @@ -36,20 +37,25 @@
public class StreamingDataRequest {

private static final ClientType[] CLIENT_ORDER_TO_USE = ClientType.values();

private static final String AUTHORIZATION_HEADER = "Authorization";

private static final String[] REQUEST_HEADER_KEYS = {
AUTHORIZATION_HEADER, // Available only to logged-in users.
"X-GOOG-API-FORMAT-VERSION",
"X-Goog-Visitor-Id"
};

/**
* TCP connection and HTTP read timeout.
*/
private static final int HTTP_TIMEOUT_MILLISECONDS = 10 * 1000;

/**
* Any arbitrarily large value, but must be at least twice {@link #HTTP_TIMEOUT_MILLISECONDS}
*/
private static final int MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000;

private static final Map<String, StreamingDataRequest> cache = Collections.synchronizedMap(
new LinkedHashMap<>(100) {
/**
Expand All @@ -68,6 +74,7 @@ protected boolean removeEldestEntry(Entry eldest) {
});

private final String videoId;

private final Future<ByteBuffer> future;

private StreamingDataRequest(String videoId, Map<String, String> playerHeaders) {
Expand Down Expand Up @@ -157,13 +164,21 @@ private static ByteBuffer fetch(String videoId, Map<String, String> playerHeader
// Show an error if the last client type fails, or if the debug is enabled then show for all attempts.
final boolean showErrorToast = (++i == CLIENT_ORDER_TO_USE.length) || debugEnabled;

if (clientType == ClientType.ANDROID_VR_NO_AUTH
&& BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get() == AudioStreamLanguage.DEFAULT) {
// Only use no auth Android VR if a non default audio language is selected.
continue;
}

HttpURLConnection connection = send(clientType, videoId, playerHeaders, showErrorToast);
if (connection != null) {
try {
// gzip encoding doesn't response with content length (-1),
// but empty response body does.
if (connection.getContentLength() == 0) {
Logger.printDebug(() -> "Received empty response for client: " + clientType);
if (BaseSettings.DEBUG.get()) {
Logger.printException(() -> "Ignoring empty client response: " + clientType);
}
} else {
try (InputStream inputStream = new BufferedInputStream(connection.getInputStream());
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package app.revanced.extension.youtube.patches;

import app.revanced.extension.shared.Logger;
import app.revanced.extension.youtube.shared.PlayerType;

@SuppressWarnings("unused")
public class FixPlaybackSpeedWhilePlayingPatch {

private static final float DEFAULT_YOUTUBE_PLAYBACK_SPEED = 1.0f;

public static boolean playbackSpeedChanged(float playbackSpeed) {
if (playbackSpeed == DEFAULT_YOUTUBE_PLAYBACK_SPEED &&
PlayerType.getCurrent().isMaximizedOrFullscreen()) {

Logger.printDebug(() -> "Blocking call to change playback speed to 1.0x");

return true;
}

return false;
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,16 @@ public static void submitSegments(@NonNull String videoId, @NonNull String categ
String end = String.format(Locale.US, TIME_TEMPLATE, endTime / 1000f);
String duration = String.format(Locale.US, TIME_TEMPLATE, videoLength / 1000f);

HttpURLConnection connection = getConnectionFromRoute(SBRoutes.SUBMIT_SEGMENTS, privateUserId, videoId, category, start, end, duration);
HttpURLConnection connection = getConnectionFromRoute(SBRoutes.SUBMIT_SEGMENTS,
privateUserId, videoId, category, start, end, duration);
final int responseCode = connection.getResponseCode();

String userMessage = switch (responseCode) {
case HTTP_STATUS_CODE_SUCCESS -> str("revanced_sb_submit_succeeded");
if (responseCode == HTTP_STATUS_CODE_SUCCESS) {
Utils.showToastLong(str("revanced_sb_submit_succeeded"));
return;
}

String userErrorMessage = switch (responseCode) {
case 409 -> str("revanced_sb_submit_failed_duplicate");
case 403 -> str("revanced_sb_submit_failed_forbidden",
Requester.parseErrorStringAndDisconnect(connection));
Expand All @@ -167,7 +172,7 @@ public static void submitSegments(@NonNull String videoId, @NonNull String categ

// Message might be about the users account or an error too large to show in a toast.
// Use a dialog instead.
SponsorBlockUtils.showErrorDialog(userMessage);
SponsorBlockUtils.showErrorDialog(userErrorMessage);
} catch (SocketTimeoutException ex) {
Logger.printDebug(() -> "Timeout", ex);
Utils.showToastLong(str("revanced_sb_submit_failed_timeout"));
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
org.gradle.parallel = true
android.useAndroidX = true
kotlin.code.style = official
version = 5.7.0
version = 5.7.1-dev.5
4 changes: 4 additions & 0 deletions patches/api/patches.api
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,10 @@ public final class app/revanced/patches/youtube/misc/fix/playback/UserAgentClien
public static final fun getUserAgentClientSpoofPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}

public final class app/revanced/patches/youtube/misc/fix/playbackspeed/FIxPlaybackSpeedWhilePlayingPatchKt {
public static final fun getFixPlaybackSpeedWhilePlayingPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}

public final class app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatchKt {
public static final fun getGmsCoreSupportPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,22 +163,31 @@ val themePatch = bytecodePatch(
}

// Fix the splash screen dark mode background color.
// In earlier versions of the app this is white and makes no sense for dark mode.
// This is only required for 19.32 and greater, but is applied to all targets.
// Only dark mode needs this fix as light mode correctly uses the custom color.
// In 19.32+ the dark mode splash screen is white and fades to black.
// Maybe it's a bug in YT, or maybe it intentionally. Who knows.
document("res/values-night/styles.xml").use { document ->
// Create a night mode specific override for the splash screen background.
val style = document.createElement("style")
style.setAttribute("name", "Theme.YouTube.Home")
style.setAttribute("parent", "@style/Base.V23.Theme.YouTube.Home")
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
val childNodes = resourcesNode.childNodes

val windowItem = document.createElement("item")
windowItem.setAttribute("name", "android:windowBackground")
windowItem.textContent = "@color/$splashBackgroundColor"
style.appendChild(windowItem)
for (i in 0 until childNodes.length) {
val node = childNodes.item(i) as? Element ?: continue
val nodeAttributeName = node.getAttribute("name")
if (nodeAttributeName.startsWith("Theme.YouTube.Launcher")) {
val nodeAttributeParent = node.getAttribute("parent")

val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
resourcesNode.appendChild(style)
val style = document.createElement("style")
style.setAttribute("name", "Theme.YouTube.Home")
style.setAttribute("parent", nodeAttributeParent)

val windowItem = document.createElement("item")
windowItem.setAttribute("name", "android:windowBackground")
windowItem.textContent = "@color/$splashBackgroundColor"
style.appendChild(windowItem)

resourcesNode.removeChild(node)
resourcesNode.appendChild(style)
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint

private const val EXTENSION_CLASS_DESCRIPTOR =
Expand All @@ -13,7 +14,10 @@ val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch(
name = "Check watch history domain name resolution",
description = "Checks if the device DNS server is preventing user watch history from being saved.",
) {
dependsOn(addResourcesPatch)
dependsOn(
sharedExtensionPatch,
addResourcesPatch
)

compatibleWith(
"com.google.android.youtube"(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package app.revanced.patches.youtube.misc.fix.playbackspeed

import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction

private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/FixPlaybackSpeedWhilePlayingPatch;"

/**
* Fixes a bug in YouTube 19.34+ where the playback speed
* can incorrectly reset to 1.0x under certain conditions.
*
* Reproduction steps using 19.34+
* 1. Open a video and start playback
* 2. Change the speed to any value that is not 1.0x.
* 3. Open the comments panel.
* 4. Tap any "N more replies" link at the bottom of a comment, or tap on a timestamp of a comment.
* 5. Pause the video
* 6. Resume the video
* 7. Playback speed will incorrectly change to 1.0x.
*/
@Suppress("unused")
val fixPlaybackSpeedWhilePlayingPatch = bytecodePatch{
dependsOn(
sharedExtensionPatch,
playerTypeHookPatch,
versionCheckPatch,
)

execute {
if (!is_19_34_or_greater) {
return@execute
}

playbackSpeedInFeedsFingerprint.method.apply {
val freeRegister = implementation!!.registerCount - parameters.size - 2
val playbackSpeedIndex = indexOfGetPlaybackSpeedInstruction(this)
val playbackSpeedRegister = getInstruction<TwoRegisterInstruction>(playbackSpeedIndex).registerA
val returnIndex = indexOfFirstInstructionOrThrow(playbackSpeedIndex, Opcode.RETURN_VOID)

addInstructionsWithLabels(
playbackSpeedIndex + 1,
"""
invoke-static { v$playbackSpeedRegister }, $EXTENSION_CLASS_DESCRIPTOR->playbackSpeedChanged(F)Z
move-result v$freeRegister
if-nez v$freeRegister, :do_not_change
""",
ExternalLabel("do_not_change", getInstruction(returnIndex))
)
}
}
}
Loading

0 comments on commit dfcce5c

Please sign in to comment.