Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Merge branch dev to main #4123

Merged
merged 14 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
# [5.5.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.5.0-dev.4...v5.5.0-dev.5) (2024-12-16)


### Features

* **YouTube - Navigation buttons:** Add options to disable translucent status bar and navigation bar ([#4133](https://github.com/ReVanced/revanced-patches/issues/4133)) ([a2d2141](https://github.com/ReVanced/revanced-patches/commit/a2d2141cec9b0b4929e07a8010889b21c324b229))

# [5.5.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.5.0-dev.3...v5.5.0-dev.4) (2024-12-16)


### Bug Fixes

* **YouTube - Spoof video streams:** Make livestreams start at the current time when using iOS client ([#4137](https://github.com/ReVanced/revanced-patches/issues/4137)) ([140f484](https://github.com/ReVanced/revanced-patches/commit/140f484b4b251b0dfa94163a63f61f45f5302052))

# [5.5.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.5.0-dev.2...v5.5.0-dev.3) (2024-12-16)


### Features

* **YouTube - Hide feed components:** Remove obsolete `Hide search result shelf header` option ([#4134](https://github.com/ReVanced/revanced-patches/issues/4134)) ([c71443a](https://github.com/ReVanced/revanced-patches/commit/c71443a08883ab10ef2553213c03b00e7c580a43))

# [5.5.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.5.0-dev.1...v5.5.0-dev.2) (2024-12-16)


### Bug Fixes

* **YouTube Music:** Add `Spoof client patch` to fix playback ([#4132](https://github.com/ReVanced/revanced-patches/issues/4132)) ([b092508](https://github.com/ReVanced/revanced-patches/commit/b0925088e8b41636e285cb234593d545604ce461))

# [5.5.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.4.1-dev.1...v5.5.0-dev.1) (2024-12-15)


### Features

* **YouTube:** Add `Force original audio` patch ([#4122](https://github.com/ReVanced/revanced-patches/issues/4122)) ([f4aa440](https://github.com/ReVanced/revanced-patches/commit/f4aa4406080b91f01d623e54b11b99ea849ddcdf))

## [5.4.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.4.0...v5.4.1-dev.1) (2024-12-14)


### Bug Fixes

* **Twitch:** Change recommended target to the latest app version ([fb32972](https://github.com/ReVanced/revanced-patches/commit/fb32972f4de92dac1fc5d73f56a392a671c4e94b))

# [5.4.0](https://github.com/ReVanced/revanced-patches/compare/v5.3.0...v5.4.0) (2024-12-14)


Expand Down
1 change: 1 addition & 0 deletions extensions/music/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Do not remove. Necessary for the extension plugin to be applied to the project.
1 change: 1 addition & 0 deletions extensions/music/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<manifest/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package app.revanced.extension.music.spoof;

/**
* @noinspection unused
*/
public class SpoofClientPatch {
private static final int CLIENT_TYPE_ID = 26;
private static final String CLIENT_VERSION = "6.21";
private static final String DEVICE_MODEL = "iPhone16,2";
private static final String OS_VERSION = "17.7.2.21H221";

public static int getClientId() {
return CLIENT_TYPE_ID;
}

public static String getClientVersion() {
return CLIENT_VERSION;
}

public static String getClientModel() {
return DEVICE_MODEL;
}

public static String getOsVersion() {
return OS_VERSION;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static app.revanced.extension.shared.settings.Setting.parent;
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.ForceiOSAVCAvailability;
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.SpoofiOSAvailability;

import app.revanced.extension.shared.spoof.AudioStreamLanguage;
import app.revanced.extension.shared.spoof.ClientType;
Expand All @@ -22,9 +22,9 @@ public class BaseSettings {
public static final IntegerSetting CHECK_ENVIRONMENT_WARNINGS_ISSUED = new IntegerSetting("revanced_check_environment_warnings_issued", 0, true, false);

public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true, "revanced_spoof_video_streams_user_dialog_message");
public static final EnumSetting<AudioStreamLanguage> SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AudioStreamLanguage.DEFAULT, parent(SPOOF_VIDEO_STREAMS));
public static final EnumSetting<AudioStreamLanguage> SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AudioStreamLanguage.DEFAULT, new SpoofiOSAvailability());
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new ForceiOSAVCAvailability());
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofiOSAvailability());
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
import java.util.Locale;

public enum AudioStreamLanguage {
/**
* YouTube default.
* Can be the original language or can be app language,
* depending on what YouTube decides to pick as the default.
*/
DEFAULT,

// Language codes found in locale_config.xml
Expand Down Expand Up @@ -86,15 +91,21 @@ public enum AudioStreamLanguage {
private final String iso639_1;

AudioStreamLanguage() {
iso639_1 = name().replace('_', '-');
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);
}
}

public String getIso639_1() {
// 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) {
// Android VR requires uppercase language code.
return Locale.getDefault().toLanguageTag().toUpperCase(Locale.US);
return Locale.getDefault().toLanguageTag();
}

return iso639_1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public enum ClientType {
"32", // Android 12.1
"1.56.21",
true,
true),
false),
// Specific for kids videos.
IOS(5,
"IOS",
Expand All @@ -40,21 +40,8 @@ public enum ClientType {
? "17.40.5"
: "19.47.7",
false,
true),
/**
* Android VR with no language code.
* Used for age restricted videos and YouTube Music to disable stable volume.
*/
ANDROID_VR_NO_HL(
ANDROID_VR.id,
ANDROID_VR.clientName,
ANDROID_VR.deviceModel,
ANDROID_VR.osVersion,
ANDROID_VR.userAgent,
ANDROID_VR.androidSdkVersion,
ANDROID_VR.clientVersion,
ANDROID_VR.canLogin,
false);
true
);

private static boolean forceAVC() {
return BaseSettings.SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,16 @@
@SuppressWarnings("unused")
public class SpoofVideoStreamsPatch {
private static final boolean SPOOF_STREAMING_DATA = BaseSettings.SPOOF_VIDEO_STREAMS.get();

private static final boolean FIX_HLS_CURRENT_TIME = SPOOF_STREAMING_DATA
&& BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS;

/**
* Any unreachable ip address. Used to intentionally fail requests.
*/
private static final String UNREACHABLE_HOST_URI_STRING = "https://127.0.0.0";
private static final Uri UNREACHABLE_HOST_URI = Uri.parse(UNREACHABLE_HOST_URI_STRING);

/**
* Injection point. Used by YT Music to disable stable volume.
*/
public static void setClientTypeToAndroidVrNoHl() {
Logger.printDebug(() -> "Setting stream spoofing to: " + ClientType.ANDROID_VR_NO_HL);
BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.save(ClientType.ANDROID_VR_NO_HL);
}

/**
* Injection point.
* Blocks /get_watch requests by returning an unreachable URI.
Expand Down Expand Up @@ -173,10 +169,24 @@ public static byte[] removeVideoPlaybackPostBody(Uri uri, int method, byte[] pos
return postData;
}

public static final class ForceiOSAVCAvailability implements Setting.Availability {
/**
* Injection point.
*
* Fixes iOS livestreams starting from the beginning.
*/
public static boolean fixHLSCurrentTime(boolean original) {
if (FIX_HLS_CURRENT_TIME) {
return false;
}

return original;
}

public static final class SpoofiOSAvailability implements Setting.Availability {
@Override
public boolean isAvailable() {
return BaseSettings.SPOOF_VIDEO_STREAMS.get() && BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS;
return BaseSettings.SPOOF_VIDEO_STREAMS.get()
&& BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ final class PlayerRoutes {
"?fields=streamingData" +
"&alt=proto"
).compile();

private static final String YT_API_URL = "https://youtubei.googleapis.com/youtubei/v1/";

/**
* TCP connection and HTTP read timeout
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package app.revanced.extension.youtube.patches;

import app.revanced.extension.shared.Logger;
import app.revanced.extension.youtube.settings.Settings;

@SuppressWarnings("unused")
public class ForceOriginalAudioPatch {

private static final String DEFAULT_AUDIO_TRACKS_IDENTIFIER = "original";

/**
* Injection point.
*/
public static boolean isDefaultAudioStream(boolean isDefault, String audioTrackId, String audioTrackDisplayName) {
try {
if (!Settings.FORCE_ORIGINAL_AUDIO.get()) {
return isDefault;
}

if (audioTrackDisplayName.isEmpty()) {
// Older app targets can have empty audio tracks and these might be placeholders.
// The real audio tracks are called after these.
return isDefault;
}

Logger.printDebug(() -> "default: " + String.format("%-5s", isDefault) + " id: "
+ String.format("%-8s", audioTrackId) + " name:" + audioTrackDisplayName);

final boolean isOriginal = audioTrackDisplayName.contains(DEFAULT_AUDIO_TRACKS_IDENTIFIER);
if (isOriginal) {
Logger.printDebug(() -> "Using audio: " + audioTrackId);
}

return isOriginal;
} catch (Exception ex) {
Logger.printException(() -> "isDefaultAudioStream failure", ex);
}

return isDefault;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import static app.revanced.extension.shared.Utils.hideViewUnderCondition;
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton;

import android.os.Build;
import android.view.View;

import java.util.EnumMap;
import java.util.Map;

import android.widget.TextView;

import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.settings.Settings;

@SuppressWarnings("unused")
Expand All @@ -26,6 +29,15 @@ public final class NavigationButtonsPatch {
private static final boolean SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON
= Settings.SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON.get();

private static final Boolean DISABLE_TRANSLUCENT_STATUS_BAR
= Settings.DISABLE_TRANSLUCENT_STATUS_BAR.get();

private static final Boolean DISABLE_TRANSLUCENT_NAVIGATION_BAR_LIGHT
= Settings.DISABLE_TRANSLUCENT_NAVIGATION_BAR_LIGHT.get();

private static final Boolean DISABLE_TRANSLUCENT_NAVIGATION_BAR_DARK
= Settings.DISABLE_TRANSLUCENT_NAVIGATION_BAR_DARK.get();

/**
* Injection point.
*/
Expand All @@ -48,4 +60,42 @@ public static void navigationTabCreated(NavigationButton button, View tabView) {
public static void hideNavigationButtonLabels(TextView navigationLabelsView) {
hideViewUnderCondition(Settings.HIDE_NAVIGATION_BUTTON_LABELS, navigationLabelsView);
}

/**
* Injection point.
*/
public static boolean useTranslucentNavigationStatusBar(boolean original) {
// Must check Android version, as forcing this on Android 11 or lower causes app hang and crash.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
return original;
}

if (DISABLE_TRANSLUCENT_STATUS_BAR) {
return false;
}

return original;
}

/**
* Injection point.
*/
public static boolean useTranslucentNavigationButtons(boolean original) {
// Feature requires Android 13+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
return original;
}

if (!DISABLE_TRANSLUCENT_NAVIGATION_BAR_DARK && !DISABLE_TRANSLUCENT_NAVIGATION_BAR_LIGHT) {
return original;
}

if (DISABLE_TRANSLUCENT_NAVIGATION_BAR_DARK && DISABLE_TRANSLUCENT_NAVIGATION_BAR_LIGHT) {
return false;
}

return Utils.isDarkModeEnabled(Utils.getContext())
? !DISABLE_TRANSLUCENT_NAVIGATION_BAR_DARK
: !DISABLE_TRANSLUCENT_NAVIGATION_BAR_LIGHT;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public final class LayoutComponentsFilter extends Filter {
);

private final StringTrieSearch exceptions = new StringTrieSearch();
private final StringFilterGroup searchResultShelfHeader;
private final StringFilterGroup inFeedSurvey;
private final StringFilterGroup notifyMe;
private final StringFilterGroup expandableMetadata;
Expand Down Expand Up @@ -194,11 +193,6 @@ public LayoutComponentsFilter() {
"timed_reaction"
);

searchResultShelfHeader = new StringFilterGroup(
Settings.HIDE_SEARCH_RESULT_SHELF_HEADER,
"shelf_header.eml"
);

notifyMe = new StringFilterGroup(
Settings.HIDE_NOTIFY_ME_BUTTON,
"set_reminder_button"
Expand Down Expand Up @@ -324,9 +318,6 @@ boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBuff
return false;
}

// TODO: This also hides the feed Shorts shelf header
if (matchedGroup == searchResultShelfHeader && contentIndex != 0) return false;

if (matchedGroup == horizontalShelves) {
if (contentIndex == 0 && hideShelves()) {
return super.isFiltered(path, identifier, protobufBufferArray, matchedGroup, contentType, contentIndex);
Expand Down
Loading
Loading