mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-09 02:43:57 +01:00
feat(YouTube): Add Disable video codecs patch (#5981)
This commit is contained in:
committed by
GitHub
parent
ee4755646b
commit
bfbffbd1f5
@@ -53,7 +53,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
* Set by subclasses if Strings cannot be added as a resource.
|
* Set by subclasses if Strings cannot be added as a resource.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
protected static String restartDialogTitle, restartDialogMessage, restartDialogButtonText, confirmDialogTitle;
|
protected static CharSequence restartDialogTitle, restartDialogMessage, restartDialogButtonText, confirmDialogTitle;
|
||||||
|
|
||||||
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
|
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
|
||||||
try {
|
try {
|
||||||
@@ -125,10 +125,13 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
|
|
||||||
showingUserDialogMessage = true;
|
showingUserDialogMessage = true;
|
||||||
|
|
||||||
|
CharSequence message = BulletPointPreference.formatIntoBulletPoints(
|
||||||
|
Objects.requireNonNull(setting.userDialogMessage).toString());
|
||||||
|
|
||||||
Pair<Dialog, LinearLayout> dialogPair = CustomDialog.create(
|
Pair<Dialog, LinearLayout> dialogPair = CustomDialog.create(
|
||||||
context,
|
context,
|
||||||
confirmDialogTitle, // Title.
|
confirmDialogTitle, // Title.
|
||||||
Objects.requireNonNull(setting.userDialogMessage).toString(), // No message.
|
message,
|
||||||
null, // No EditText.
|
null, // No EditText.
|
||||||
null, // OK button text.
|
null, // OK button text.
|
||||||
() -> {
|
() -> {
|
||||||
|
|||||||
@@ -15,7 +15,15 @@ import android.util.AttributeSet;
|
|||||||
@SuppressWarnings({"unused", "deprecation"})
|
@SuppressWarnings({"unused", "deprecation"})
|
||||||
public class BulletPointPreference extends Preference {
|
public class BulletPointPreference extends Preference {
|
||||||
|
|
||||||
public static SpannedString formatIntoBulletPoints(CharSequence source) {
|
/**
|
||||||
|
* Replaces bullet points with styled spans.
|
||||||
|
*/
|
||||||
|
public static CharSequence formatIntoBulletPoints(CharSequence source) {
|
||||||
|
final char bulletPoint = '•';
|
||||||
|
if (TextUtils.indexOf(source, bulletPoint) < 0) {
|
||||||
|
return source; // Nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
SpannableStringBuilder builder = new SpannableStringBuilder(source);
|
SpannableStringBuilder builder = new SpannableStringBuilder(source);
|
||||||
|
|
||||||
int lineStart = 0;
|
int lineStart = 0;
|
||||||
@@ -26,7 +34,7 @@ public class BulletPointPreference extends Preference {
|
|||||||
if (lineEnd < 0) lineEnd = length;
|
if (lineEnd < 0) lineEnd = length;
|
||||||
|
|
||||||
// Apply BulletSpan only if the line starts with the '•' character.
|
// Apply BulletSpan only if the line starts with the '•' character.
|
||||||
if (lineEnd > lineStart && builder.charAt(lineStart) == '•') {
|
if (lineEnd > lineStart && builder.charAt(lineStart) == bulletPoint) {
|
||||||
int deleteEnd = lineStart + 1; // remove the bullet itself
|
int deleteEnd = lineStart + 1; // remove the bullet itself
|
||||||
|
|
||||||
// If there's a single space right after the bullet, remove that too.
|
// If there's a single space right after the bullet, remove that too.
|
||||||
|
|||||||
@@ -42,11 +42,8 @@ final class PlayerRoutes {
|
|||||||
JSONObject context = new JSONObject();
|
JSONObject context = new JSONObject();
|
||||||
|
|
||||||
AppLanguage language = SpoofVideoStreamsPatch.getLanguageOverride();
|
AppLanguage language = SpoofVideoStreamsPatch.getLanguageOverride();
|
||||||
if (language == null || clientType == ANDROID_VR_1_43_32) {
|
if (language == null) {
|
||||||
// Force original audio has not overrode the language.
|
// Force original audio has not overrode the language.
|
||||||
// Or if YT has fallen over to the last unauthenticated client (VR 1.43), then
|
|
||||||
// always use the app language because forcing an audio stream of specific languages
|
|
||||||
// can sometimes fail so it's better to try and load something rather than nothing.
|
|
||||||
language = BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get();
|
language = BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get();
|
||||||
}
|
}
|
||||||
//noinspection ExtractMethodRecommender
|
//noinspection ExtractMethodRecommender
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ public class CustomDialog {
|
|||||||
* @param dismissDialogOnNeutralClick If the dialog should be dismissed when the Neutral button is clicked.
|
* @param dismissDialogOnNeutralClick If the dialog should be dismissed when the Neutral button is clicked.
|
||||||
* @return The Dialog and its main LinearLayout container.
|
* @return The Dialog and its main LinearLayout container.
|
||||||
*/
|
*/
|
||||||
public static Pair<Dialog, LinearLayout> create(Context context, String title, CharSequence message,
|
public static Pair<Dialog, LinearLayout> create(Context context, CharSequence title, CharSequence message,
|
||||||
@Nullable EditText editText, String okButtonText,
|
@Nullable EditText editText, CharSequence okButtonText,
|
||||||
Runnable onOkClick, Runnable onCancelClick,
|
Runnable onOkClick, Runnable onCancelClick,
|
||||||
@Nullable String neutralButtonText,
|
@Nullable CharSequence neutralButtonText,
|
||||||
@Nullable Runnable onNeutralClick,
|
@Nullable Runnable onNeutralClick,
|
||||||
boolean dismissDialogOnNeutralClick) {
|
boolean dismissDialogOnNeutralClick) {
|
||||||
Logger.printDebug(() -> "Creating custom dialog with title: " + title);
|
Logger.printDebug(() -> "Creating custom dialog with title: " + title);
|
||||||
@@ -85,9 +85,9 @@ public class CustomDialog {
|
|||||||
* @param onNeutralClick Action to perform when the Neutral button is clicked, or null if no Neutral button is needed.
|
* @param onNeutralClick Action to perform when the Neutral button is clicked, or null if no Neutral button is needed.
|
||||||
* @param dismissDialogOnNeutralClick If the dialog should be dismissed when the Neutral button is clicked.
|
* @param dismissDialogOnNeutralClick If the dialog should be dismissed when the Neutral button is clicked.
|
||||||
*/
|
*/
|
||||||
private CustomDialog(Context context, String title, CharSequence message, @Nullable EditText editText,
|
private CustomDialog(Context context, CharSequence title, CharSequence message, @Nullable EditText editText,
|
||||||
String okButtonText, Runnable onOkClick, Runnable onCancelClick,
|
CharSequence okButtonText, Runnable onOkClick, Runnable onCancelClick,
|
||||||
@Nullable String neutralButtonText, @Nullable Runnable onNeutralClick,
|
@Nullable CharSequence neutralButtonText, @Nullable Runnable onNeutralClick,
|
||||||
boolean dismissDialogOnNeutralClick) {
|
boolean dismissDialogOnNeutralClick) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.dialog = new Dialog(context);
|
this.dialog = new Dialog(context);
|
||||||
@@ -139,7 +139,7 @@ public class CustomDialog {
|
|||||||
*
|
*
|
||||||
* @param title The title text to display.
|
* @param title The title text to display.
|
||||||
*/
|
*/
|
||||||
private void addTitle(String title) {
|
private void addTitle(CharSequence title) {
|
||||||
if (TextUtils.isEmpty(title)) return;
|
if (TextUtils.isEmpty(title)) return;
|
||||||
|
|
||||||
TextView titleView = new TextView(context);
|
TextView titleView = new TextView(context);
|
||||||
@@ -232,8 +232,8 @@ public class CustomDialog {
|
|||||||
* @param onNeutralClick Action for the Neutral button click, or null if no Neutral button.
|
* @param onNeutralClick Action for the Neutral button click, or null if no Neutral button.
|
||||||
* @param dismissDialogOnNeutralClick If the dialog should dismiss on Neutral button click.
|
* @param dismissDialogOnNeutralClick If the dialog should dismiss on Neutral button click.
|
||||||
*/
|
*/
|
||||||
private void addButtons(String okButtonText, Runnable onOkClick, Runnable onCancelClick,
|
private void addButtons(CharSequence okButtonText, Runnable onOkClick, Runnable onCancelClick,
|
||||||
@Nullable String neutralButtonText, @Nullable Runnable onNeutralClick,
|
@Nullable CharSequence neutralButtonText, @Nullable Runnable onNeutralClick,
|
||||||
boolean dismissDialogOnNeutralClick) {
|
boolean dismissDialogOnNeutralClick) {
|
||||||
// Button container.
|
// Button container.
|
||||||
LinearLayout buttonContainer = new LinearLayout(context);
|
LinearLayout buttonContainer = new LinearLayout(context);
|
||||||
@@ -280,7 +280,7 @@ public class CustomDialog {
|
|||||||
* @param dismissDialog If the dialog should dismiss when the button is clicked.
|
* @param dismissDialog If the dialog should dismiss when the button is clicked.
|
||||||
* @return The created Button.
|
* @return The created Button.
|
||||||
*/
|
*/
|
||||||
private Button createButton(String text, Runnable onClick, boolean isOkButton, boolean dismissDialog) {
|
private Button createButton(CharSequence text, Runnable onClick, boolean isOkButton, boolean dismissDialog) {
|
||||||
Button button = new Button(context, null, 0);
|
Button button = new Button(context, null, 0);
|
||||||
button.setText(text);
|
button.setText(text);
|
||||||
button.setTextSize(14);
|
button.setTextSize(14);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import android.view.Display;
|
|||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class DisableHdrPatch {
|
public class DisableVideoCodecsPatch {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
@@ -15,5 +15,12 @@ public class DisableHdrPatch {
|
|||||||
? new int[0]
|
? new int[0]
|
||||||
: capabilities.getSupportedHdrTypes();
|
: capabilities.getSupportedHdrTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static boolean allowVP9() {
|
||||||
|
return !Settings.FORCE_AVC_CODEC.get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,7 +15,8 @@ public class ForceOriginalAudioPatch {
|
|||||||
*/
|
*/
|
||||||
public static void setPreferredLanguage() {
|
public static void setPreferredLanguage() {
|
||||||
if (Settings.FORCE_ORIGINAL_AUDIO.get()
|
if (Settings.FORCE_ORIGINAL_AUDIO.get()
|
||||||
&& SpoofVideoStreamsPatch.spoofingToClientWithNoMultiAudioStreams()) {
|
&& SpoofVideoStreamsPatch.spoofingToClientWithNoMultiAudioStreams()
|
||||||
|
&& !Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get().useAuth) {
|
||||||
// If client spoofing does not use authentication and lacks multi-audio streams,
|
// If client spoofing does not use authentication and lacks multi-audio streams,
|
||||||
// then can use any language code for the request and if that requested language is
|
// then can use any language code for the request and if that requested language is
|
||||||
// not available YT uses the original audio language. Authenticated requests ignore
|
// not available YT uses the original audio language. Authenticated requests ignore
|
||||||
|
|||||||
@@ -18,7 +18,22 @@ public class SpoofVideoStreamsPatch {
|
|||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static void setClientOrderToUse() {
|
public static void setClientOrderToUse() {
|
||||||
List<ClientType> availableClients = List.of(
|
final boolean forceAVC = Settings.FORCE_AVC_CODEC.get();
|
||||||
|
|
||||||
|
// VR 1.61 uses VP9/AV1, and cannot force AVC.
|
||||||
|
ClientType client = Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
|
||||||
|
if (forceAVC && client == ANDROID_VR_1_61_48) {
|
||||||
|
client = ANDROID_VR_1_43_32; // Use VR 1.43 instead.
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ClientType> availableClients = forceAVC
|
||||||
|
? List.of(
|
||||||
|
ANDROID_VR_1_43_32,
|
||||||
|
VISIONOS,
|
||||||
|
ANDROID_CREATOR,
|
||||||
|
ANDROID_VR_1_61_48,
|
||||||
|
IPADOS)
|
||||||
|
: List.of(
|
||||||
ANDROID_VR_1_61_48,
|
ANDROID_VR_1_61_48,
|
||||||
VISIONOS,
|
VISIONOS,
|
||||||
ANDROID_CREATOR,
|
ANDROID_CREATOR,
|
||||||
@@ -27,6 +42,6 @@ public class SpoofVideoStreamsPatch {
|
|||||||
);
|
);
|
||||||
|
|
||||||
app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.setClientsToUse(
|
app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.setClientsToUse(
|
||||||
availableClients, Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get());
|
availableClients, client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,6 +48,9 @@ import app.revanced.extension.youtube.swipecontrols.SwipeControlsConfigurationPr
|
|||||||
|
|
||||||
public class Settings extends BaseSettings {
|
public class Settings extends BaseSettings {
|
||||||
// Video
|
// Video
|
||||||
|
public static final BooleanSetting ADVANCED_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_advanced_video_quality_menu", TRUE);
|
||||||
|
public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE);
|
||||||
|
public static final BooleanSetting FORCE_AVC_CODEC = new BooleanSetting("revanced_force_avc_codec", FALSE, true, "revanced_force_avc_codec_user_dialog_message");
|
||||||
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_video_quality_default_wifi", -2);
|
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_video_quality_default_wifi", -2);
|
||||||
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_video_quality_default_mobile", -2);
|
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_video_quality_default_mobile", -2);
|
||||||
public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", FALSE);
|
public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", FALSE);
|
||||||
@@ -56,8 +59,6 @@ public class Settings extends BaseSettings {
|
|||||||
public static final BooleanSetting REMEMBER_SHORTS_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_shorts_quality_last_selected", FALSE);
|
public static final BooleanSetting REMEMBER_SHORTS_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_shorts_quality_last_selected", FALSE);
|
||||||
public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_video_quality_last_selected_toast", TRUE, false,
|
public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_video_quality_last_selected_toast", TRUE, false,
|
||||||
parentsAny(REMEMBER_VIDEO_QUALITY_LAST_SELECTED, REMEMBER_SHORTS_QUALITY_LAST_SELECTED));
|
parentsAny(REMEMBER_VIDEO_QUALITY_LAST_SELECTED, REMEMBER_SHORTS_QUALITY_LAST_SELECTED));
|
||||||
public static final BooleanSetting ADVANCED_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_advanced_video_quality_menu", TRUE);
|
|
||||||
public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE);
|
|
||||||
|
|
||||||
// Speed
|
// Speed
|
||||||
public static final FloatSetting SPEED_TAP_AND_HOLD = new FloatSetting("revanced_speed_tap_and_hold", 2.0f, true);
|
public static final FloatSetting SPEED_TAP_AND_HOLD = new FloatSetting("revanced_speed_tap_and_hold", 2.0f, true);
|
||||||
|
|||||||
@@ -1727,6 +1727,10 @@ public final class app/revanced/patches/youtube/video/audio/ForceOriginalAudioPa
|
|||||||
public static final fun getForceOriginalAudioPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getForceOriginalAudioPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/youtube/video/codecs/DisableVideoCodecsPatchKt {
|
||||||
|
public static final fun getDisableVideoCodecsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/video/hdr/DisableHdrPatchKt {
|
public final class app/revanced/patches/youtube/video/hdr/DisableHdrPatchKt {
|
||||||
public static final fun getDisableHdrPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getDisableHdrPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package app.revanced.patches.youtube.video.codecs
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
|
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.all.misc.transformation.transformInstructionsPatch
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/extension/youtube/patches/DisableVideoCodecsPatch;"
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val disableVideoCodecsPatch = bytecodePatch(
|
||||||
|
name = "disable video codecs",
|
||||||
|
description = "Adds options to disable HDR and VP9 codecs.",
|
||||||
|
) {
|
||||||
|
dependsOn(
|
||||||
|
sharedExtensionPatch,
|
||||||
|
settingsPatch,
|
||||||
|
addResourcesPatch,
|
||||||
|
/**
|
||||||
|
* Override all calls of `getSupportedHdrTypes`.
|
||||||
|
*/
|
||||||
|
transformInstructionsPatch(
|
||||||
|
filterMap = filterMap@{ classDef, _, instruction, instructionIndex ->
|
||||||
|
if (classDef.type.startsWith("Lapp/revanced/")) {
|
||||||
|
return@filterMap null
|
||||||
|
}
|
||||||
|
|
||||||
|
val reference = instruction.getReference<MethodReference>()
|
||||||
|
if (reference?.definingClass =="Landroid/view/Display\$HdrCapabilities;"
|
||||||
|
&& reference.name == "getSupportedHdrTypes") {
|
||||||
|
return@filterMap instruction to instructionIndex
|
||||||
|
}
|
||||||
|
return@filterMap null
|
||||||
|
},
|
||||||
|
transform = { method, entry ->
|
||||||
|
val (instruction, index) = entry
|
||||||
|
val register = (instruction as FiveRegisterInstruction).registerC
|
||||||
|
|
||||||
|
method.replaceInstruction(
|
||||||
|
index,
|
||||||
|
"invoke-static/range { v$register .. v$register }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
||||||
|
"disableHdrVideo(Landroid/view/Display\$HdrCapabilities;)[I",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
compatibleWith(
|
||||||
|
"com.google.android.youtube"(
|
||||||
|
"19.34.42",
|
||||||
|
"20.07.39",
|
||||||
|
"20.13.41",
|
||||||
|
"20.14.43",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
addResources("youtube", "video.codecs.disableVideoCodecsPatch")
|
||||||
|
|
||||||
|
PreferenceScreen.VIDEO.addPreferences(
|
||||||
|
SwitchPreference("revanced_disable_hdr_video"),
|
||||||
|
SwitchPreference("revanced_force_avc_codec")
|
||||||
|
)
|
||||||
|
|
||||||
|
vp9CapabilityFingerprint.method.addInstructionsWithLabels(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->allowVP9()Z
|
||||||
|
move-result v0
|
||||||
|
if-nez v0, :default
|
||||||
|
return v0
|
||||||
|
:default
|
||||||
|
nop
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.video.codecs
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal val vp9CapabilityFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
returns("Z")
|
||||||
|
strings(
|
||||||
|
"vp9_supported",
|
||||||
|
"video/x-vnd.on2.vp9"
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,71 +1,10 @@
|
|||||||
package app.revanced.patches.youtube.video.hdr
|
package app.revanced.patches.youtube.video.hdr
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.all.misc.resources.addResources
|
import app.revanced.patches.youtube.video.codecs.disableVideoCodecsPatch
|
||||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
|
||||||
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
|
|
||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
|
||||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
|
||||||
import app.revanced.util.getReference
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
|
||||||
"Lapp/revanced/extension/youtube/patches/DisableHdrPatch;"
|
|
||||||
|
|
||||||
|
@Deprecated("Patch was renamed", ReplaceWith("disableVideoCodecsPatch"))
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val disableHdrPatch = bytecodePatch(
|
val disableHdrPatch = bytecodePatch{
|
||||||
name = "Disable HDR video",
|
dependsOn(disableVideoCodecsPatch)
|
||||||
description = "Adds an option to disable video HDR.",
|
}
|
||||||
) {
|
|
||||||
dependsOn(
|
|
||||||
sharedExtensionPatch,
|
|
||||||
settingsPatch,
|
|
||||||
addResourcesPatch,
|
|
||||||
// Override all calls of `getSupportedHdrTypes`.
|
|
||||||
transformInstructionsPatch(
|
|
||||||
filterMap = filterMap@{ classDef, _, instruction, instructionIndex ->
|
|
||||||
if (classDef.type.startsWith("Lapp/revanced/")) {
|
|
||||||
return@filterMap null
|
|
||||||
}
|
|
||||||
|
|
||||||
val reference = instruction.getReference<MethodReference>()
|
|
||||||
if (reference?.definingClass =="Landroid/view/Display\$HdrCapabilities;"
|
|
||||||
&& reference.name == "getSupportedHdrTypes") {
|
|
||||||
return@filterMap instruction to instructionIndex
|
|
||||||
}
|
|
||||||
return@filterMap null
|
|
||||||
},
|
|
||||||
transform = { method, entry ->
|
|
||||||
val (instruction, index) = entry
|
|
||||||
val register = (instruction as FiveRegisterInstruction).registerC
|
|
||||||
|
|
||||||
method.replaceInstruction(
|
|
||||||
index,
|
|
||||||
"invoke-static/range { v$register .. v$register }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
|
||||||
"disableHdrVideo(Landroid/view/Display\$HdrCapabilities;)[I",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
compatibleWith(
|
|
||||||
"com.google.android.youtube"(
|
|
||||||
"19.34.42",
|
|
||||||
"20.07.39",
|
|
||||||
"20.13.41",
|
|
||||||
"20.14.43",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
execute {
|
|
||||||
addResources("youtube", "video.hdr.disableHdrPatch")
|
|
||||||
|
|
||||||
PreferenceScreen.VIDEO.addPreferences(
|
|
||||||
SwitchPreference("revanced_disable_hdr_video")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,7 +26,6 @@ internal val videoQualityItemOnClickFingerprint = fingerprint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal val videoQualityMenuOptionsFingerprint = fingerprint {
|
internal val videoQualityMenuOptionsFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.STATIC)
|
accessFlags(AccessFlags.STATIC)
|
||||||
returns("[L")
|
returns("[L")
|
||||||
|
|||||||
@@ -14,12 +14,13 @@ internal val settingsMenuVideoQualityGroup = mutableSetOf<BasePreference>()
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val videoQualityPatch = bytecodePatch(
|
val videoQualityPatch = bytecodePatch(
|
||||||
name = "Video quality",
|
name = "Video quality",
|
||||||
description = "Adds options to use the advanced video quality menu and set default video qualities."
|
description = "Adds options to use the advanced video quality menu, set default video qualities, " +
|
||||||
|
"and disable video codecs such as VP9/HDR."
|
||||||
) {
|
) {
|
||||||
dependsOn(
|
dependsOn(
|
||||||
rememberVideoQualityPatch,
|
rememberVideoQualityPatch,
|
||||||
advancedVideoQualityMenuPatch,
|
advancedVideoQualityMenuPatch,
|
||||||
videoQualityDialogButtonPatch,
|
videoQualityDialogButtonPatch
|
||||||
)
|
)
|
||||||
|
|
||||||
compatibleWith(
|
compatibleWith(
|
||||||
|
|||||||
@@ -1641,10 +1641,22 @@ Enabling this can unlock higher video qualities"</string>
|
|||||||
<string name="revanced_playback_speed_default_title">Default playback speed</string>
|
<string name="revanced_playback_speed_default_title">Default playback speed</string>
|
||||||
<string name="revanced_remember_playback_speed_toast">Changed default speed to: %s</string>
|
<string name="revanced_remember_playback_speed_toast">Changed default speed to: %s</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.hdr.disableHdrPatch">
|
<patch id="video.codecs.disableVideoCodecsPatch">
|
||||||
<string name="revanced_disable_hdr_video_title">Disable HDR video</string>
|
<string name="revanced_disable_hdr_video_title">Disable HDR video</string>
|
||||||
<string name="revanced_disable_hdr_video_summary_on">HDR video is disabled</string>
|
<string name="revanced_disable_hdr_video_summary_on">HDR video is disabled</string>
|
||||||
<string name="revanced_disable_hdr_video_summary_off">HDR video is enabled</string>
|
<string name="revanced_disable_hdr_video_summary_off">HDR video is enabled</string>
|
||||||
|
<string name="revanced_force_avc_codec_title">Force AVC (H.264)</string>
|
||||||
|
<string name="revanced_force_avc_codec_summary_on">Video codec is forced to AVC (H.264)</string>
|
||||||
|
<string name="revanced_force_avc_codec_summary_off">Video codec is determined automatically</string>
|
||||||
|
<string name="revanced_force_avc_codec_user_dialog_message">"Benefits:
|
||||||
|
• Can improve battery life.
|
||||||
|
• Can restore missing video resolutions on older device.
|
||||||
|
|
||||||
|
Limitations:
|
||||||
|
• Maximum resolution is 1080p.
|
||||||
|
• Video playback will use more internet data than VP9 or AV1.
|
||||||
|
• HDR videos may not use AVC.
|
||||||
|
• Some devices cannot force AVC."</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.advancedVideoQualityMenuPatch">
|
<patch id="video.quality.advancedVideoQualityMenuPatch">
|
||||||
<string name="revanced_advanced_video_quality_menu_title">Show advanced video quality menu</string>
|
<string name="revanced_advanced_video_quality_menu_title">Show advanced video quality menu</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user