mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-26 02:44:08 +01:00
Compare commits
7 Commits
v5.40.0-de
...
v5.40.0-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb1d07fd98 | ||
|
|
651d358096 | ||
|
|
0d15c5f338 | ||
|
|
5c7c8b5364 | ||
|
|
729997ec3e | ||
|
|
767f1e3695 | ||
|
|
7857876551 |
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,3 +1,24 @@
|
||||
# [5.40.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.4...v5.40.0-dev.5) (2025-09-20)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube Music:** Add `Hide cast button` and `Navigation bar` patches ([#5934](https://github.com/ReVanced/revanced-patches/issues/5934)) ([651d358](https://github.com/ReVanced/revanced-patches/commit/651d3580967a252b57cbf4afbba02d6a4601ccfe))
|
||||
|
||||
# [5.40.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.3...v5.40.0-dev.4) (2025-09-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Spoof video streams:** Resolve occasional playback stuttering ([5c7c8b5](https://github.com/ReVanced/revanced-patches/commit/5c7c8b536416ec53cd98f7d59d11850aa1b70f11))
|
||||
|
||||
# [5.40.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.2...v5.40.0-dev.3) (2025-09-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Instagram - Limit feed to followed profiles:** Change patch to default off ([767f1e3](https://github.com/ReVanced/revanced-patches/commit/767f1e3695327bdbc4daea8b50a80d4c0a38456a))
|
||||
|
||||
# [5.40.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.1...v5.40.0-dev.2) (2025-09-18)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package app.revanced.extension.music.patches;
|
||||
|
||||
import static app.revanced.extension.shared.Utils.hideViewBy0dpUnderCondition;
|
||||
|
||||
import android.view.View;
|
||||
import app.revanced.extension.music.settings.Settings;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class HideCastButtonPatch {
|
||||
|
||||
/**
|
||||
* Injection point
|
||||
*/
|
||||
public static int hideCastButton(int original) {
|
||||
return Settings.HIDE_CAST_BUTTON.get() ? View.GONE : original;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point
|
||||
*/
|
||||
public static void hideCastButton(View view) {
|
||||
hideViewBy0dpUnderCondition(Settings.HIDE_CAST_BUTTON.get(), view);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package app.revanced.extension.music.patches;
|
||||
|
||||
import static app.revanced.extension.shared.Utils.hideViewUnderCondition;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.extension.music.settings.Settings;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class NavigationBarPatch {
|
||||
@NonNull
|
||||
private static String lastYTNavigationEnumName = "";
|
||||
|
||||
public static void setLastAppNavigationEnum(@Nullable Enum<?> ytNavigationEnumName) {
|
||||
if (ytNavigationEnumName != null) {
|
||||
lastYTNavigationEnumName = ytNavigationEnumName.name();
|
||||
}
|
||||
}
|
||||
|
||||
public static void hideNavigationLabel(TextView textview) {
|
||||
hideViewUnderCondition(Settings.HIDE_NAVIGATION_BAR_LABEL.get(), textview);
|
||||
}
|
||||
|
||||
public static void hideNavigationButton(@NonNull View view) {
|
||||
// Hide entire navigation bar.
|
||||
if (Settings.HIDE_NAVIGATION_BAR.get() && view.getParent() != null) {
|
||||
hideViewUnderCondition(true, (View) view.getParent());
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide navigation buttons based on their type.
|
||||
for (NavigationButton button : NavigationButton.values()) {
|
||||
if (button.ytEnumNames.equals(lastYTNavigationEnumName)) {
|
||||
hideViewUnderCondition(button.hidden, view);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum NavigationButton {
|
||||
HOME(
|
||||
"TAB_HOME",
|
||||
Settings.HIDE_NAVIGATION_BAR_HOME_BUTTON.get()
|
||||
),
|
||||
SAMPLES(
|
||||
"TAB_SAMPLES",
|
||||
Settings.HIDE_NAVIGATION_BAR_SAMPLES_BUTTON.get()
|
||||
),
|
||||
EXPLORE(
|
||||
"TAB_EXPLORE",
|
||||
Settings.HIDE_NAVIGATION_BAR_EXPLORE_BUTTON.get()
|
||||
),
|
||||
LIBRARY(
|
||||
"LIBRARY_MUSIC",
|
||||
Settings.HIDE_NAVIGATION_BAR_LIBRARY_BUTTON.get()
|
||||
),
|
||||
UPGRADE(
|
||||
"TAB_MUSIC_PREMIUM",
|
||||
Settings.HIDE_NAVIGATION_BAR_UPGRADE_BUTTON.get()
|
||||
);
|
||||
|
||||
private final String ytEnumNames;
|
||||
private final boolean hidden;
|
||||
|
||||
NavigationButton(@NonNull String ytEnumNames, boolean hidden) {
|
||||
this.ytEnumNames = ytEnumNames;
|
||||
this.hidden = hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,15 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting HIDE_UPGRADE_BUTTON = new BooleanSetting("revanced_music_hide_upgrade_button", TRUE, true);
|
||||
|
||||
// General
|
||||
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_music_hide_cast_button", FALSE, false);
|
||||
public static final BooleanSetting HIDE_CATEGORY_BAR = new BooleanSetting("revanced_music_hide_category_bar", FALSE, true);
|
||||
public static final BooleanSetting HIDE_NAVIGATION_BAR_HOME_BUTTON = new BooleanSetting("revanced_music_hide_navigation_bar_home_button", FALSE, true);
|
||||
public static final BooleanSetting HIDE_NAVIGATION_BAR_SAMPLES_BUTTON = new BooleanSetting("revanced_music_hide_navigation_bar_samples_button", FALSE, true);
|
||||
public static final BooleanSetting HIDE_NAVIGATION_BAR_EXPLORE_BUTTON = new BooleanSetting("revanced_music_hide_navigation_bar_explore_button", FALSE, true);
|
||||
public static final BooleanSetting HIDE_NAVIGATION_BAR_LIBRARY_BUTTON = new BooleanSetting("revanced_music_hide_navigation_bar_library_button", FALSE, true);
|
||||
public static final BooleanSetting HIDE_NAVIGATION_BAR_UPGRADE_BUTTON = new BooleanSetting("revanced_music_hide_navigation_bar_upgrade_button", TRUE, true);
|
||||
public static final BooleanSetting HIDE_NAVIGATION_BAR = new BooleanSetting("revanced_music_hide_navigation_bar", FALSE, true);
|
||||
public static final BooleanSetting HIDE_NAVIGATION_BAR_LABEL = new BooleanSetting("revanced_music_hide_navigation_bar_labels", FALSE, true);
|
||||
|
||||
// Player
|
||||
public static final BooleanSetting PERMANENT_REPEAT = new BooleanSetting("revanced_music_play_permanent_repeat", FALSE, true);
|
||||
|
||||
@@ -97,6 +97,35 @@ public class SpoofVideoStreamsPatch {
|
||||
return playerRequestUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*
|
||||
* Blocks /get_watch requests by returning an unreachable URI.
|
||||
* /att/get requests are used to obtain a PoToken challenge.
|
||||
* See: <a href="https://github.com/FreeTubeApp/FreeTube/blob/4b7208430bc1032019a35a35eb7c8a84987ddbd7/src/botGuardScript.js#L15">botGuardScript.js#L15</a>
|
||||
* <p>
|
||||
* Since the Spoof streaming data patch was implemented because a valid PoToken cannot be obtained,
|
||||
* Blocking /att/get requests are not a problem.
|
||||
*/
|
||||
public static String blockGetAttRequest(String originalUrlString) {
|
||||
if (SPOOF_STREAMING_DATA) {
|
||||
try {
|
||||
var originalUri = Uri.parse(originalUrlString);
|
||||
String path = originalUri.getPath();
|
||||
|
||||
if (path != null && path.contains("att/get")) {
|
||||
Logger.printDebug(() -> "Blocking 'att/get' by returning internet connection check uri");
|
||||
|
||||
return INTERNET_CONNECTION_CHECK_URI_STRING;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "blockGetAttRequest failure", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return originalUrlString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
* <p>
|
||||
@@ -130,7 +159,7 @@ public class SpoofVideoStreamsPatch {
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
* Only invoked when playing a livestream on an iOS client.
|
||||
* Only invoked when playing a livestream on an Apple client.
|
||||
*/
|
||||
public static boolean fixHLSCurrentTime(boolean original) {
|
||||
if (!SPOOF_STREAMING_DATA) {
|
||||
@@ -139,6 +168,14 @@ public class SpoofVideoStreamsPatch {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Injection point.
|
||||
* Fix audio stuttering in YouTube Music.
|
||||
*/
|
||||
public static boolean disableSABR() {
|
||||
return SPOOF_STREAMING_DATA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
* Turns off a feature flag that interferes with spoofing.
|
||||
|
||||
@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
|
||||
org.gradle.parallel = true
|
||||
android.useAndroidX = true
|
||||
kotlin.code.style = official
|
||||
version = 5.40.0-dev.2
|
||||
version = 5.40.0-dev.5
|
||||
|
||||
@@ -372,10 +372,18 @@ public final class app/revanced/patches/music/interaction/permanentshuffle/Perma
|
||||
public static final fun getPermanentShufflePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/music/layout/castbutton/HideCastButtonKt {
|
||||
public static final fun getHideCastButton ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/music/layout/compactheader/HideCategoryBarKt {
|
||||
public static final fun getHideCategoryBar ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/music/layout/navigationbar/NavigationBarPatchKt {
|
||||
public static final fun getNavigationBarPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/music/layout/premium/HideGetPremiumPatchKt {
|
||||
public static final fun getHideGetPremiumPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/instagr
|
||||
val limitFeedToFollowedProfiles = bytecodePatch(
|
||||
name = "Limit feed to followed profiles",
|
||||
description = "Filters the home feed to display only content from profiles you follow.",
|
||||
use = false
|
||||
) {
|
||||
compatibleWith("com.instagram.android")
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package app.revanced.patches.music.layout.castbutton
|
||||
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.util.literal
|
||||
|
||||
internal val mediaRouteButtonFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
|
||||
returns("Z")
|
||||
strings("MediaRouteButton")
|
||||
}
|
||||
|
||||
internal val playerOverlayChipFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("L")
|
||||
literal { playerOverlayChip }
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package app.revanced.patches.music.layout.castbutton
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
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.music.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.music.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.music.misc.settings.settingsPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
internal var playerOverlayChip = -1L
|
||||
private set
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/HideCastButtonPatch;"
|
||||
|
||||
@Suppress("unused")
|
||||
val hideCastButton = bytecodePatch(
|
||||
name = "Hide cast button",
|
||||
description = "Adds an option to hide the cast button."
|
||||
) {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
settingsPatch,
|
||||
addResourcesPatch,
|
||||
)
|
||||
|
||||
compatibleWith(
|
||||
"com.google.android.apps.youtube.music"(
|
||||
"7.29.52"
|
||||
)
|
||||
)
|
||||
|
||||
execute {
|
||||
addResources("music", "layout.castbutton.hideCastButton")
|
||||
|
||||
PreferenceScreen.GENERAL.addPreferences(
|
||||
SwitchPreference("revanced_music_hide_cast_button"),
|
||||
)
|
||||
|
||||
mediaRouteButtonFingerprint.classDef.apply {
|
||||
val setVisibilityMethod = methods.first { method -> method.name == "setVisibility" }
|
||||
|
||||
setVisibilityMethod.addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->hideCastButton(I)I
|
||||
move-result p1
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
playerOverlayChipFingerprint.method.apply {
|
||||
val resourceIndex = indexOfFirstLiteralInstructionOrThrow(playerOverlayChip)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(resourceIndex, Opcode.MOVE_RESULT)
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
targetIndex + 1,
|
||||
"invoke-static { v$targetRegister }, $EXTENSION_CLASS_DESCRIPTOR->hideCastButton(Landroid/view/View;)V"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package app.revanced.patches.music.layout.navigationbar
|
||||
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import app.revanced.util.literal
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal val tabLayoutTextFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("V")
|
||||
parameters("L")
|
||||
opcodes(
|
||||
Opcode.IGET,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IF_NEZ,
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT
|
||||
)
|
||||
strings("FEmusic_search")
|
||||
literal { text1 }
|
||||
custom { method, _ ->
|
||||
indexOfGetVisibilityInstruction(method) >= 0
|
||||
}
|
||||
}
|
||||
|
||||
internal fun indexOfGetVisibilityInstruction(method: Method) =
|
||||
method.indexOfFirstInstruction {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "getVisibility"
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package app.revanced.patches.music.layout.navigationbar
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
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.music.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.music.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.music.misc.settings.settingsPatch
|
||||
import app.revanced.patches.shared.misc.mapping.get
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
|
||||
internal var text1 = -1L
|
||||
private set
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/NavigationBarPatch;"
|
||||
|
||||
@Suppress("unused")
|
||||
val navigationBarPatch = bytecodePatch(
|
||||
name = "Navigation bar",
|
||||
description = "Adds options to hide navigation bar, labels and buttons."
|
||||
) {
|
||||
dependsOn(
|
||||
resourceMappingPatch,
|
||||
sharedExtensionPatch,
|
||||
settingsPatch,
|
||||
addResourcesPatch
|
||||
)
|
||||
|
||||
compatibleWith(
|
||||
"com.google.android.apps.youtube.music"(
|
||||
"7.29.52"
|
||||
)
|
||||
)
|
||||
|
||||
execute {
|
||||
text1 = resourceMappings[
|
||||
"id",
|
||||
"text1",
|
||||
]
|
||||
|
||||
addResources("music", "layout.navigationbar.navigationBarPatch")
|
||||
|
||||
PreferenceScreen.GENERAL.addPreferences(
|
||||
PreferenceScreenPreference(
|
||||
key = "revanced_music_navigation_bar_screen",
|
||||
sorting = PreferenceScreenPreference.Sorting.UNSORTED,
|
||||
preferences = setOf(
|
||||
SwitchPreference("revanced_music_hide_navigation_bar_home_button"),
|
||||
SwitchPreference("revanced_music_hide_navigation_bar_samples_button"),
|
||||
SwitchPreference("revanced_music_hide_navigation_bar_explore_button"),
|
||||
SwitchPreference("revanced_music_hide_navigation_bar_library_button"),
|
||||
SwitchPreference("revanced_music_hide_navigation_bar_upgrade_button"),
|
||||
|
||||
SwitchPreference("revanced_music_hide_navigation_bar"),
|
||||
SwitchPreference("revanced_music_hide_navigation_bar_labels"),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
tabLayoutTextFingerprint.method.apply {
|
||||
/**
|
||||
* Hide navigation labels.
|
||||
*/
|
||||
val constIndex = indexOfFirstLiteralInstructionOrThrow(text1)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
val targetParameter = getInstruction<ReferenceInstruction>(targetIndex).reference
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
if (!targetParameter.toString().endsWith("Landroid/widget/TextView;"))
|
||||
throw PatchException("Method signature parameter did not match: $targetParameter")
|
||||
|
||||
addInstruction(
|
||||
targetIndex + 1,
|
||||
"invoke-static { v$targetRegister }, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationLabel(Landroid/widget/TextView;)V"
|
||||
)
|
||||
|
||||
/**
|
||||
* Set navigation enum and hide navigation buttons.
|
||||
*/
|
||||
val enumIndex = tabLayoutTextFingerprint.patternMatch!!.startIndex + 3
|
||||
val enumRegister = getInstruction<OneRegisterInstruction>(enumIndex).registerA
|
||||
val insertEnumIndex = indexOfFirstInstructionOrThrow(Opcode.AND_INT_LIT8) - 2
|
||||
|
||||
val pivotTabIndex = indexOfGetVisibilityInstruction(this)
|
||||
val pivotTabRegister = getInstruction<FiveRegisterInstruction>(pivotTabIndex).registerC
|
||||
|
||||
addInstruction(
|
||||
pivotTabIndex,
|
||||
"invoke-static { v$pivotTabRegister }, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationButton(Landroid/view/View;)V"
|
||||
)
|
||||
|
||||
addInstruction(
|
||||
insertEnumIndex,
|
||||
"invoke-static { v$enumRegister }, $EXTENSION_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,9 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/HideUpgradeButtonPatch;"
|
||||
|
||||
@Deprecated("This patch will be removed in the future.")
|
||||
@Suppress("unused")
|
||||
val hideUpgradeButton = bytecodePatch(
|
||||
name = "Hide upgrade button",
|
||||
description = "Hides the upgrade tab from the pivot bar.",
|
||||
) {
|
||||
dependsOn(
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
package app.revanced.patches.shared.misc.spoof
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import app.revanced.util.literal
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal val buildInitPlaybackRequestFingerprint = fingerprint {
|
||||
returns("Lorg/chromium/net/UrlRequest\$Builder;")
|
||||
@@ -40,10 +37,7 @@ internal val buildRequestFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("Lorg/chromium/net/UrlRequest") // UrlRequest; or UrlRequest$Builder;
|
||||
custom { methodDef, _ ->
|
||||
if (methodDef.indexOfFirstInstruction {
|
||||
val reference = getReference<MethodReference>()
|
||||
reference?.name == "newUrlRequestBuilder"
|
||||
} < 0) {
|
||||
if (indexOfNewUrlRequestBuilderInstruction(methodDef) < 0) {
|
||||
return@custom false
|
||||
}
|
||||
|
||||
@@ -142,6 +136,17 @@ internal val hlsCurrentTimeFingerprint = fingerprint {
|
||||
}
|
||||
}
|
||||
|
||||
internal const val DISABLED_BY_SABR_STREAMING_URI_STRING = "DISABLED_BY_SABR_STREAMING_URI"
|
||||
|
||||
internal val mediaFetchEnumConstructorFingerprint = fingerprint {
|
||||
returns("V")
|
||||
strings(
|
||||
"ENABLED",
|
||||
"DISABLED_FOR_PLAYBACK",
|
||||
DISABLED_BY_SABR_STREAMING_URI_STRING
|
||||
)
|
||||
}
|
||||
|
||||
internal val nerdsStatsVideoFormatBuilderFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("Ljava/lang/String;")
|
||||
|
||||
@@ -5,23 +5,28 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.instructions
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.util.findFreeRegister
|
||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.insertLiteralOverride
|
||||
import app.revanced.util.returnEarly
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
@@ -31,6 +36,9 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/shared/spoof/SpoofVideoStreamsPatch;"
|
||||
|
||||
private lateinit var buildRequestMethod: MutableMethod
|
||||
private var buildRequestMethodUrlRegister = -1
|
||||
|
||||
fun spoofVideoStreamsPatch(
|
||||
block: BytecodePatchBuilder.() -> Unit = {},
|
||||
fixMediaFetchHotConfigChanges: BytecodePatchBuilder.() -> Boolean = { false },
|
||||
@@ -91,18 +99,17 @@ fun spoofVideoStreamsPatch(
|
||||
// region Get replacement streams at player requests.
|
||||
|
||||
buildRequestFingerprint.method.apply {
|
||||
val newRequestBuilderIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "newUrlRequestBuilder"
|
||||
}
|
||||
val urlRegister = getInstruction<FiveRegisterInstruction>(newRequestBuilderIndex).registerD
|
||||
val freeRegister = findFreeRegister(newRequestBuilderIndex, urlRegister)
|
||||
buildRequestMethod = this
|
||||
|
||||
val newRequestBuilderIndex = indexOfNewUrlRequestBuilderInstruction(this)
|
||||
buildRequestMethodUrlRegister = getInstruction<FiveRegisterInstruction>(newRequestBuilderIndex).registerD
|
||||
val freeRegister = findFreeRegister(newRequestBuilderIndex, buildRequestMethodUrlRegister)
|
||||
|
||||
addInstructions(
|
||||
newRequestBuilderIndex,
|
||||
"""
|
||||
move-object v$freeRegister, p1
|
||||
invoke-static { v$urlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
|
||||
invoke-static { v$buildRequestMethodUrlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
|
||||
"""
|
||||
)
|
||||
}
|
||||
@@ -187,6 +194,21 @@ fun spoofVideoStreamsPatch(
|
||||
|
||||
// endregion
|
||||
|
||||
// region block getAtt request
|
||||
|
||||
buildRequestMethod.apply {
|
||||
val insertIndex = indexOfNewUrlRequestBuilderInstruction(this)
|
||||
|
||||
addInstructions(
|
||||
insertIndex, """
|
||||
invoke-static { v$buildRequestMethodUrlRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockGetAttRequest(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$buildRequestMethodUrlRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Remove /videoplayback request body to fix playback.
|
||||
// It is assumed, YouTube makes a request with a body tuned for Android.
|
||||
// Requesting streams intended for other platforms with a body tuned for Android could be the cause of 400 errors.
|
||||
@@ -243,6 +265,50 @@ fun spoofVideoStreamsPatch(
|
||||
|
||||
// endregion
|
||||
|
||||
// region Disable SABR playback.
|
||||
// If SABR is disabled, it seems 'MediaFetchHotConfig' may no longer need an override (not confirmed).
|
||||
|
||||
val (mediaFetchEnumClass, sabrFieldReference) = with(mediaFetchEnumConstructorFingerprint.method) {
|
||||
val stringIndex = mediaFetchEnumConstructorFingerprint.stringMatches!!.first {
|
||||
it.string == DISABLED_BY_SABR_STREAMING_URI_STRING
|
||||
}.index
|
||||
|
||||
val mediaFetchEnumClass = definingClass
|
||||
val sabrFieldIndex = indexOfFirstInstructionOrThrow(stringIndex) {
|
||||
opcode == Opcode.SPUT_OBJECT &&
|
||||
getReference<FieldReference>()?.type == mediaFetchEnumClass
|
||||
}
|
||||
|
||||
Pair(
|
||||
mediaFetchEnumClass,
|
||||
getInstruction<ReferenceInstruction>(sabrFieldIndex).reference
|
||||
)
|
||||
}
|
||||
|
||||
fingerprint {
|
||||
returns(mediaFetchEnumClass)
|
||||
opcodes(
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.RETURN_OBJECT,
|
||||
)
|
||||
custom { method, _ ->
|
||||
!method.parameterTypes.isEmpty()
|
||||
}
|
||||
}.method.addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->disableSABR()Z
|
||||
move-result v0
|
||||
if-eqz v0, :ignore
|
||||
sget-object v0, $sabrFieldReference
|
||||
return-object v0
|
||||
:ignore
|
||||
nop
|
||||
"""
|
||||
)
|
||||
|
||||
// endregion
|
||||
|
||||
// region turn off stream config replacement feature flag.
|
||||
|
||||
if (fixMediaFetchHotConfigChanges()) {
|
||||
@@ -271,3 +337,12 @@ fun spoofVideoStreamsPatch(
|
||||
executeBlock()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun indexOfNewUrlRequestBuilderInstruction(method: Method) = method.indexOfFirstInstruction {
|
||||
opcode == Opcode.INVOKE_VIRTUAL && getReference<MethodReference>().toString() ==
|
||||
"Lorg/chromium/net/CronetEngine;" +
|
||||
"->newUrlRequestBuilder(" +
|
||||
"Ljava/lang/String;Lorg/chromium/net/UrlRequest${'$'}Callback;" +
|
||||
"Ljava/util/concurrent/Executor;" +
|
||||
")Lorg/chromium/net/UrlRequest${'$'}Builder;"
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ Um neue Sprachen zu übersetzen, besuchen Sie translate.revanced.app"</string>
|
||||
<string name="revanced_pref_import_export_summary">ReVanced-Einstellungen importieren/exportieren</string>
|
||||
<!-- Settings about dialog. -->
|
||||
<string name="revanced_settings_about_links_body">Sie verwenden ReVanced-Patches Version <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">Notiz</string>
|
||||
<string name="revanced_settings_about_links_dev_header">Hinweis</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Diese Version ist eine Vorabversion, es kann zu unerwarteten Problemen kommen</string>
|
||||
<string name="revanced_settings_about_links_header">Offizielle Links</string>
|
||||
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||
@@ -79,21 +79,23 @@ Folgen Sie der Anleitung \"Don't kill my app\" für Ihr Gerät und wenden Sie di
|
||||
|
||||
Dies ist erforderlich, damit die App funktioniert."</string>
|
||||
<string name="gms_core_dialog_open_website_text">Website öffnen</string>
|
||||
<string name="gms_core_dialog_not_whitelisted_using_battery_optimizations_message">"Die Batterieoptimierung von MicroG GmsCore muss deaktiviert werden, um Probleme zu vermeiden.
|
||||
Die Deaktivierung der Batterieoptimierung für MicroG hat keinen negativen Einfluss auf den Batterieverbrauch.
|
||||
<string name="gms_core_dialog_not_whitelisted_using_battery_optimizations_message">"Die Akku-Optimierung muss für MicroG GmsCore deaktiviert werden, um Probleme zu vermeiden.
|
||||
|
||||
Die Deaktivierung der Akku-Optimierung für MicroG hat keinen negativen Einfluss auf den Akkuverbrauch.
|
||||
|
||||
Tippen Sie auf die Schaltfläche \"Fortfahren\" und erlauben Sie die Optimierungsänderungen."</string>
|
||||
<string name="gms_core_dialog_continue_text">Weiter</string>
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
|
||||
<string name="revanced_spoof_video_streams_screen_title">Spoof-Video-Streams</string>
|
||||
<string name="revanced_spoof_video_streams_screen_summary">Spoof der Client-Videostreams um Wiedergabeprobleme zu verhindern</string>
|
||||
<string name="revanced_spoof_video_streams_screen_title">Video-Streams vortäuschen</string>
|
||||
<string name="revanced_spoof_video_streams_screen_summary">Die Client-Video-Streams vortäuschen, um Wiedergabeprobleme zu verhindern</string>
|
||||
<string name="revanced_spoof_video_streams_title">Spoof-Video-Streams</string>
|
||||
<string name="revanced_spoof_video_streams_screen_title">Spoofe Video-Streams</string>
|
||||
<string name="revanced_spoof_video_streams_screen_summary">Spoofe die Client-Videostreams um Wiedergabeprobleme zu verhindern</string>
|
||||
<string name="revanced_spoof_video_streams_screen_title">Spoofe Video-Streams</string>
|
||||
<string name="revanced_spoof_video_streams_screen_summary">Spoofe die Client-Video-Streams, um Wiedergabeprobleme zu verhindern</string>
|
||||
<string name="revanced_spoof_video_streams_title">Spoofe Video-Streams</string>
|
||||
<string name="revanced_spoof_video_streams_summary_on">"Videostreams werden gespooft
|
||||
|
||||
Wenn Sie ein YouTube Premium-Nutzer sind, ist diese Einstellung möglicherweise nicht erforderlich"</string>
|
||||
<string name="revanced_spoof_video_streams_summary_off">"Video-Streams werden nicht vorgetäuscht
|
||||
<string name="revanced_spoof_video_streams_summary_off">"Video-Streams werden nicht gespooft
|
||||
|
||||
Die Wiedergabe funktioniert möglicherweise nicht"</string>
|
||||
<string name="revanced_spoof_video_streams_user_dialog_message">Das Deaktivieren dieser Einstellung kann Wiedergabeprobleme verursachen.</string>
|
||||
@@ -136,9 +138,9 @@ Die Wiedergabe funktioniert möglicherweise nicht"</string>
|
||||
<string name="revanced_settings_search_history_summary_off">Der Suchverlauf der Einstellungen wird nicht angezeigt</string>
|
||||
</patch>
|
||||
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
||||
<string name="revanced_shorts_disable_background_playback_title">Shorts-Hintergrundwiedergabe deaktivieren</string>
|
||||
<string name="revanced_shorts_disable_background_playback_summary_on">Shorts-Hintergrundwiedergabe ist deaktiviert</string>
|
||||
<string name="revanced_shorts_disable_background_playback_summary_off">Shorts-Hintergrundwiedergabe ist aktiviert</string>
|
||||
<string name="revanced_shorts_disable_background_playback_title">Hintergrundwiedergabe von Shorts deaktivieren</string>
|
||||
<string name="revanced_shorts_disable_background_playback_summary_on">Hintergrundwiedergabe von Shorts ist deaktiviert</string>
|
||||
<string name="revanced_shorts_disable_background_playback_summary_off">Hintergrundwiedergabe von Shorts ist aktiviert</string>
|
||||
</patch>
|
||||
<patch id="misc.debugging.enableDebuggingPatch">
|
||||
<string name="revanced_debug_protobuffer_title">Protokollpuffer protokollieren</string>
|
||||
@@ -154,20 +156,20 @@ Wenn Sie dies aktivieren, werden jedoch auch einige Benutzerdaten wie Ihre IP-Ad
|
||||
<string name="revanced_debug_stacktrace_summary_off">Debug-Logs enthalten keine Stack-Traces</string>
|
||||
<string name="revanced_debug_toast_on_error_title">Toast bei ReVanced Fehler anzeigen</string>
|
||||
<string name="revanced_debug_toast_on_error_summary_on">Ein Toast wird angezeigt, wenn ein Fehler auftritt</string>
|
||||
<string name="revanced_debug_toast_on_error_summary_off">Es wird keine Toast-Nachricht angezeigt, wenn ein Fehler Auftritt</string>
|
||||
<string name="revanced_debug_toast_on_error_summary_off">Es wird keine Toast-Nachricht angezeigt, wenn ein Fehler auftritt</string>
|
||||
<string name="revanced_debug_toast_on_error_user_dialog_message">"Das Ausschalten von Fehler-Toasts blendet alle Benachrichtigungen über Fehler in ReVanced aus.
|
||||
|
||||
Sie werden nicht über unerwartete Ereignisse informiert."</string>
|
||||
</patch>
|
||||
<patch id="layout.hide.general.hideLayoutComponentsPatch">
|
||||
<string name="revanced_hide_album_cards_title">Albumkarten ausblenden</string>
|
||||
<string name="revanced_hide_album_cards_summary_on">Albumkarten sind ausgeblendet</string>
|
||||
<string name="revanced_hide_album_cards_summary_on">Albumkarten werden ausgeblendet</string>
|
||||
<string name="revanced_hide_album_cards_summary_off">Albumkarten werden angezeigt</string>
|
||||
<string name="revanced_hide_artist_cards_title">Interpretenkarten ausblenden</string>
|
||||
<string name="revanced_hide_artist_cards_summary_on">Künstlerkarten sind ausgeblendet</string>
|
||||
<string name="revanced_hide_artist_cards_summary_on">Interpretenkarten sind ausgeblendet</string>
|
||||
<string name="revanced_hide_artist_cards_summary_off">Interpretenkarten werden angezeigt</string>
|
||||
<string name="revanced_hide_chips_shelf_title">Chips ausblenden</string>
|
||||
<string name="revanced_hide_chips_shelf_summary_on">Chips sind ausgeblendet</string>
|
||||
<string name="revanced_hide_chips_shelf_summary_on">Chips werden ausgeblendet</string>
|
||||
<string name="revanced_hide_chips_shelf_summary_off">Chips werden angezeigt</string>
|
||||
<string name="revanced_hide_community_posts_title">Communitybeiträge ausblenden</string>
|
||||
<string name="revanced_hide_community_posts_summary_on">Communitybeiträge sind ausgeblendet</string>
|
||||
@@ -180,10 +182,10 @@ Sie werden nicht über unerwartete Ereignisse informiert."</string>
|
||||
<string name="revanced_hide_crowdfunding_box_summary_off">Crowdfunding-Box wird angezeigt</string>
|
||||
<string name="revanced_hide_expandable_card_title">Ausklappbare Karte ausblenden</string>
|
||||
<string name="revanced_hide_expandable_card_summary_on">Ausklappbare Karte unter Videos ist ausgeblendet</string>
|
||||
<string name="revanced_hide_expandable_card_summary_off">Ausklappbare Karte unter Videos ist angezeigt</string>
|
||||
<string name="revanced_hide_floating_microphone_button_title">Schwebende Mikrofon-Taste ausblenden</string>
|
||||
<string name="revanced_hide_floating_microphone_button_summary_on">Schwebende Mikrofonschaltfläche in der Suche ist ausgeblendet</string>
|
||||
<string name="revanced_hide_floating_microphone_button_summary_off">Der schwebende Mikrofon-Button in der Suche wird angezeigt</string>
|
||||
<string name="revanced_hide_expandable_card_summary_off">Ausklappbare Karte unter Videos wird angezeigt</string>
|
||||
<string name="revanced_hide_floating_microphone_button_title">Schwebende Mikrofon-Schaltfläche ausblenden</string>
|
||||
<string name="revanced_hide_floating_microphone_button_summary_on">Schwebende Mikrofon-Schaltfläche wird in der Suche ausgeblendet</string>
|
||||
<string name="revanced_hide_floating_microphone_button_summary_off">Schwebende Mikrofon-Schaltfläche wird in der Suche angezeigt</string>
|
||||
<string name="revanced_hide_horizontal_shelves_title">Horizontale Reihe ausblenden</string>
|
||||
<string name="revanced_hide_horizontal_shelves_summary_on">"Horizontale Regale sind ausgeblendet, wie zum Beispiel:
|
||||
• Aktuelle Nachrichten
|
||||
@@ -197,29 +199,29 @@ Sie werden nicht über unerwartete Ereignisse informiert."</string>
|
||||
<string name="revanced_hide_image_shelf_summary_on">Bild-Regal in den Suchergebnissen ist ausgeblendet</string>
|
||||
<string name="revanced_hide_image_shelf_summary_off">Bild-Regal in den Suchergebnissen ist angezeigt</string>
|
||||
<string name="revanced_hide_latest_posts_title">Neueste Beiträge ausblenden</string>
|
||||
<string name="revanced_hide_latest_posts_summary_on">Neueste Beiträge sind ausgeblendet</string>
|
||||
<string name="revanced_hide_latest_posts_summary_on">Neueste Beiträge werden ausgeblendet</string>
|
||||
<string name="revanced_hide_latest_posts_summary_off">Neueste Beiträge werden angezeigt</string>
|
||||
<string name="revanced_hide_mix_playlists_title">Mix-Wiedergabelisten ausblenden</string>
|
||||
<string name="revanced_hide_mix_playlists_summary_on">Mix-Wiedergabelisten sind ausgeblendet</string>
|
||||
<string name="revanced_hide_mix_playlists_summary_on">Mix-Wiedergabelisten werden ausgeblendet</string>
|
||||
<string name="revanced_hide_mix_playlists_summary_off">Mix-Wiedergabelisten werden angezeigt</string>
|
||||
<string name="revanced_hide_movies_section_title">Filme-Bereich ausblenden</string>
|
||||
<string name="revanced_hide_movies_section_summary_on">Film Abschnitt ist ausgeblendet</string>
|
||||
<string name="revanced_hide_movies_section_summary_off">Film Bereich wird angezeigt</string>
|
||||
<string name="revanced_hide_movies_section_title">Film-Bereich ausblenden</string>
|
||||
<string name="revanced_hide_movies_section_summary_on">Film-Bereich wird ausgeblendet</string>
|
||||
<string name="revanced_hide_movies_section_summary_off">Film-Bereich wird angezeigt</string>
|
||||
<!-- 'Notify me' should be translated using the same localized wording YouTube displays.
|
||||
This item appear in the Subscriptions feed for future livestreams or unreleased videos. -->
|
||||
<string name="revanced_hide_notify_me_button_title">\'Benachrichtigungen\' Button ausblenden</string>
|
||||
<string name="revanced_hide_notify_me_button_summary_on">Schaltfläche \"Benachrichtige mich\" ist ausgeblendet</string>
|
||||
<string name="revanced_hide_notify_me_button_title">Schaltfläche \"Benachrichtige mich\" ausblenden</string>
|
||||
<string name="revanced_hide_notify_me_button_summary_on">Schaltfläche \"Benachrichtige mich\" wird ausgeblendet</string>
|
||||
<string name="revanced_hide_notify_me_button_summary_off">Schaltfläche \"Benachrichtige mich\" wird angezeigt</string>
|
||||
<string name="revanced_hide_playables_title">Playables ausblenden</string>
|
||||
<string name="revanced_hide_playables_summary_on">Spiele sind ausgeblendet</string>
|
||||
<string name="revanced_hide_playables_summary_off">Spielbare werden angezeigt</string>
|
||||
<string name="revanced_hide_playables_summary_on">Playables sind ausgeblendet</string>
|
||||
<string name="revanced_hide_playables_summary_off">Playables werden angezeigt</string>
|
||||
<!-- 'Show more' should be translated with the same localized wording that YouTube displays.
|
||||
This button usually appears when searching for a YT creator. -->
|
||||
<string name="revanced_hide_show_more_button_title">\'Mehr anzeigen\' Button ausblenden</string>
|
||||
<string name="revanced_hide_show_more_button_summary_on">Schaltfläche \"Mehr anzeigen\" in den Suchergebnissen ist ausgeblendet</string>
|
||||
<string name="revanced_hide_show_more_button_summary_off">Schaltfläche \"Mehr anzeigen\" in den Suchergebnissen wird angezeigt</string>
|
||||
<string name="revanced_hide_surveys_title">Umfragen ausblenden</string>
|
||||
<string name="revanced_hide_surveys_summary_on">Umfragen sind ausgeblendet</string>
|
||||
<string name="revanced_hide_surveys_summary_on">Umfragen werden ausgeblendet</string>
|
||||
<string name="revanced_hide_surveys_summary_off">Umfragen werden angezeigt</string>
|
||||
<string name="revanced_hide_ticket_shelf_title">Ticket-Reihe ausblenden</string>
|
||||
<string name="revanced_hide_ticket_shelf_summary_on">Ticket-Reihe ist ausgeblendet</string>
|
||||
@@ -421,14 +423,14 @@ Diese Funktion ist nur für ältere Geräte verfügbar"</string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_fullscreen_ads_feature_not_available_toast">Vollbild-Werbung ausblenden funktioniert nur mit älteren Geräten</string>
|
||||
<string name="revanced_hide_general_ads_title">Allgemeine Werbung ausblenden</string>
|
||||
<string name="revanced_hide_general_ads_summary_on">Allgemeine Anzeigen sind ausgeblendet</string>
|
||||
<string name="revanced_hide_general_ads_summary_off">Allgemeine Anzeigen werden angezeigt</string>
|
||||
<string name="revanced_hide_general_ads_summary_on">Allgemeine Werbung werden ausgeblendet</string>
|
||||
<string name="revanced_hide_general_ads_summary_off">Allgemeine Werbung werden angezeigt</string>
|
||||
<string name="revanced_hide_merchandise_banners_title">Merchandise-Banner ausblenden</string>
|
||||
<string name="revanced_hide_merchandise_banners_summary_on">Merchandise-Banner sind ausgeblendet</string>
|
||||
<string name="revanced_hide_merchandise_banners_summary_off">Warenbanner werden angezeigt</string>
|
||||
<string name="revanced_hide_paid_promotion_label_title">Bezahltes Werbe-Label ausblenden</string>
|
||||
<string name="revanced_hide_paid_promotion_label_summary_on">Bezahltes Werbelabel ist ausgeblendet</string>
|
||||
<string name="revanced_hide_paid_promotion_label_summary_off">Bezahltes Werbe-Label wird angezeigt</string>
|
||||
<string name="revanced_hide_paid_promotion_label_title">\"Enthält bezahlte Werbung\"-Hinweis ausblenden</string>
|
||||
<string name="revanced_hide_paid_promotion_label_summary_on">\"Enthält bezahlte Werbung\"-Hinweis wird ausgeblendet</string>
|
||||
<string name="revanced_hide_paid_promotion_label_summary_off">\"Enthält bezahlte Werbung\"-Hinweis wird angezeigt</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_title">Selbst gesponserte Karten ausblenden</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_on">Selbst gesponserte Karten sind ausgeblendet</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_off">Selbstgesponserte Karten werden angezeigt</string>
|
||||
@@ -1002,22 +1004,22 @@ Diese Funktion funktioniert am besten mit einer Videoqualität von 720p oder nie
|
||||
</patch>
|
||||
<patch id="layout.sponsorblock.sponsorBlockResourcePatch">
|
||||
<string name="revanced_sb_enable_sb">SponsorBlock aktivieren</string>
|
||||
<string name="revanced_sb_enable_sb_sum">SponsorBlock ist ein Crowdsourcing-System zum Überspringen von nervigen Teilen von YouTube-Videos</string>
|
||||
<string name="revanced_sb_enable_sb_sum">SponsorBlock ist ein Crowdsourcing-System zum Überspringen von nervigen Segmenten von YouTube-Videos</string>
|
||||
<string name="revanced_sb_appearance_category">Darstellung</string>
|
||||
<string name="revanced_sb_enable_voting">Stimmen-Button anzeigen</string>
|
||||
<string name="revanced_sb_enable_voting_sum_on">Segmentstimmen Button wird angezeigt</string>
|
||||
<string name="revanced_sb_enable_voting_sum_off">Segmentstimmen Button wird nicht angezeigt</string>
|
||||
<string name="revanced_sb_square_layout">Quadratisches Layout verwenden</string>
|
||||
<string name="revanced_sb_enable_voting">Like-Button anzeigen</string>
|
||||
<string name="revanced_sb_enable_voting_sum_on">Segmentbewertungs-Button wird angezeigt</string>
|
||||
<string name="revanced_sb_enable_voting_sum_off">Segmentbewertungs-Button wird nicht angezeigt</string>
|
||||
<string name="revanced_sb_square_layout">Quadratische Bedienelemente verwenden</string>
|
||||
<string name="revanced_sb_square_layout_sum_on">Schaltflächen und Steuerelemente sind quadratisch</string>
|
||||
<string name="revanced_sb_square_layout_sum_off">Schaltflächen und Bedienelemente sind abgerundet</string>
|
||||
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title'. -->
|
||||
<string name="revanced_sb_enable_compact_skip_button">Kompakten Überspringen-Button verwenden</string>
|
||||
<string name="revanced_sb_enable_compact_skip_button_sum_on">Überspringe Taste für minimale Breite</string>
|
||||
<string name="revanced_sb_enable_compact_skip_button_sum_off">Überspringen-Button für beste Darstellung gestaltet</string>
|
||||
<string name="revanced_sb_enable_compact_skip_button_sum_on">Überspringen-Button wird mit minimale Breite angezeigt</string>
|
||||
<string name="revanced_sb_enable_compact_skip_button_sum_off">Überspringen-Button wird mit bestem Aussehen angezeigt</string>
|
||||
<string name="revanced_sb_enable_auto_hide_skip_segment_button">Überspringen-Button automatisch ausblenden</string>
|
||||
<string name="revanced_sb_enable_auto_hide_skip_segment_button_sum_on">Überspringe Taste verbirgt sich nach ein paar Sekunden</string>
|
||||
<string name="revanced_sb_enable_auto_hide_skip_segment_button_sum_off">Die Schaltfläche \"Überspringen\" wird für das gesamte Segment angezeigt</string>
|
||||
<string name="revanced_sb_auto_hide_skip_button_duration">Dauer des Überspringen-Buttons</string>
|
||||
<string name="revanced_sb_enable_auto_hide_skip_segment_button_sum_on">Überspringen-Button wird nach ein paar Sekunden ausgeblendet</string>
|
||||
<string name="revanced_sb_enable_auto_hide_skip_segment_button_sum_off">Überspringen-Button wird während des ganzen Segmentes angezeigt</string>
|
||||
<string name="revanced_sb_auto_hide_skip_button_duration">Anzeigedauer des Überspringen-Buttons</string>
|
||||
<string name="revanced_sb_auto_hide_skip_button_duration_sum">Wie lange die Schaltflächen zum Überspringen und zum Hervorheben angezeigt werden sollen, bevor sie automatisch ausgeblendet werden</string>
|
||||
<string name="revanced_sb_general_skiptoast">Toast zum Rückgängigmachen des Überspringens anzeigen</string>
|
||||
<string name="revanced_sb_general_skiptoast_sum_on">Ein Toast wird angezeigt, wenn ein Segment automatisch übersprungen wird. Tippen Sie auf die Toast-Benachrichtigung, um das Überspringen rückgängig zu machen</string>
|
||||
@@ -1082,25 +1084,25 @@ Ihre Benutzer-ID ist wie ein Passwort und sollte niemals weitergegeben werden.
|
||||
<string name="revanced_sb_settings_revanced_export_user_id_warning_dismiss">Nicht wieder anzeigen</string>
|
||||
<string name="revanced_sb_diff_segments">Segmentverhalten ändern</string>
|
||||
<string name="revanced_sb_segments_sponsor">Sponsor</string>
|
||||
<string name="revanced_sb_segments_sponsor_sum">Bezahlte Förderung, bezahlte Empfehlungen und direkte Werbung. Nicht für Selbstwerbung oder kostenlose Shoutouts an Ursachen/Webseiten/Produkte, die ihnen gefallen</string>
|
||||
<string name="revanced_sb_segments_selfpromo">Unbezahlt/Eigenwerbung</string>
|
||||
<string name="revanced_sb_segments_sponsor_sum">Bezahlte Werbung, bezahlte Empfehlungen und direkte Werbung. Nicht für Eigenwerbung oder kostenlose Shoutouts an Zwecke/Webseiten/Produkte, die ihnen gefallen</string>
|
||||
<string name="revanced_sb_segments_selfpromo">Unbezahlte oder Eigenwerbung</string>
|
||||
<string name="revanced_sb_segments_selfpromo_sum">Ähnlich wie Sponsor, jedoch für unbezahlte oder Eigenwerbung. Enthält Abschnitte über Merchandise, Spenden oder Informationen darüber, mit wem sie zusammengearbeitet haben</string>
|
||||
<string name="revanced_sb_segments_interaction">Interaktionserinnerung (Abonnieren)</string>
|
||||
<string name="revanced_sb_segments_interaction_sum">Eine kurze Erinnerung, sie in der Mitte des Inhalts zu zitieren, zu abonnieren oder zu verfolgen. Wenn es lang ist oder etwas Konkretes ist, sollte es stattdessen unter Selbstförderung stehen</string>
|
||||
<string name="revanced_sb_segments_highlight">Hervorheben</string>
|
||||
<string name="revanced_sb_segments_interaction_sum">Eine kurze Erinnerung, sie in der Mitte des Inhalts zu liken, abonnieren oder folgen. Wenn er lang ist oder es um etwas Bestimmtes geht, sollte es stattdessen als Eigenwerbung gekennzeichnet sein</string>
|
||||
<string name="revanced_sb_segments_highlight">Highlight</string>
|
||||
<string name="revanced_sb_segments_highlight_sum">Der Teil des Videos, nach dem die meisten Menschen suchen</string>
|
||||
<string name="revanced_sb_segments_intro">Unterbrechung/Introanimation</string>
|
||||
<string name="revanced_sb_segments_intro_sum">Ein Intervall ohne aktuellen Inhalt. Kann eine Pause, ein statischer Rahmen oder eine Wiederholung der Animation sein. Enthält keine Übergänge mit Informationen</string>
|
||||
<string name="revanced_sb_segments_outro">Endkarten / Credits</string>
|
||||
<string name="revanced_sb_segments_outro_sum">Credits oder wenn die YouTube-Endkarten erscheinen. Nicht für Schlussfolgerungen mit Informationen</string>
|
||||
<string name="revanced_sb_segments_intro_sum">Ein Intervall ohne aktuellen Inhalt. Kann eine Pause, ein statischer Frame oder eine wiederholende Animation sein. Enthält keine Übergänge mit Informationen</string>
|
||||
<string name="revanced_sb_segments_outro">Endkarte / Credits</string>
|
||||
<string name="revanced_sb_segments_outro_sum">Credits oder wenn die YouTube-Endkarten erscheinen. Nicht für Fazite mit Informationen</string>
|
||||
<string name="revanced_sb_segments_hook">Hook / Begrüßungen</string>
|
||||
<string name="revanced_sb_segments_hook_sum">Erzählte Trailer für das kommende Video, Begrüßungen und Verabschiedungen. Enthält keine Abschnitte, die zusätzlichen Inhalt hinzufügen</string>
|
||||
<string name="revanced_sb_segments_hook_sum">Erzählte Trailer für das kommende Video, Begrüßungen und Verabschiedungen. Enthält keine Segmente, die zusätzlichen Inhalt hinzufügen</string>
|
||||
<string name="revanced_sb_segments_preview">Vorschau / Rückblick</string>
|
||||
<string name="revanced_sb_segments_preview_sum">Sammlung von Clips, die zeigen, was im Video oder in anderen Videos einer Serie vor sich geht, wo alle Informationen andernorts wiederholt werden</string>
|
||||
<string name="revanced_sb_segments_preview_sum">Sammlung von Clips, die zeigen, was im Video oder in anderen Videos einer Serie passiert ist, wo alle Informationen andernorts wiederholt werden</string>
|
||||
<string name="revanced_sb_segments_filler">Abschweifung / Witze</string>
|
||||
<string name="revanced_sb_segments_filler_sum">Tangentiale Szenen oder Witze, die nicht erforderlich sind, um den Hauptinhalt des Videos zu verstehen. Dies sollte keine Segmente enthalten, die Kontext oder Hintergrunddetails liefern</string>
|
||||
<string name="revanced_sb_segments_nomusic">Musik: Nicht-Musik-Sektion</string>
|
||||
<string name="revanced_sb_segments_nomusic_sum">Nur für die Verwendung in Musikvideos. Abschnitte von Musikvideos ohne Musik, die noch nicht von einer anderen Kategorie abgedeckt sind</string>
|
||||
<string name="revanced_sb_segments_filler_sum">Tangentiale Szenen oder Witze, die nicht erforderlich sind, um den Hauptinhalt des Videos zu verstehen. Enthält keine Segmente, die Kontext oder Hintergrunddetails liefern</string>
|
||||
<string name="revanced_sb_segments_nomusic">Musikvideos: Nicht-Musik-Passagen</string>
|
||||
<string name="revanced_sb_segments_nomusic_sum">Nur für die Verwendung in Musikvideos. Abschnitte von Musikvideos ohne Musik, die noch nicht von einer anderen Kategorie abgedeckt werden</string>
|
||||
<string name="revanced_sb_skip_button_compact">Überspringen</string>
|
||||
<string name="revanced_sb_skip_button_compact_highlight">Hervorheben</string>
|
||||
<string name="revanced_sb_skip_button_sponsor">Sponsor überspringen</string>
|
||||
@@ -1375,29 +1377,29 @@ Durch Aktivieren dieser Option können fehlende Bilder behoben werden, die in ei
|
||||
<!-- 'Subscriptions' should be translated using the same localized wording YouTube displays for the Subscriptions tab. -->
|
||||
<string name="revanced_alt_thumbnail_subscription_title">Abos-Tab</string>
|
||||
<!-- 'You' should be translated using the same localized wording YouTube displays for the You (Library) tab. -->
|
||||
<string name="revanced_alt_thumbnail_library_title">Tab</string>
|
||||
<string name="revanced_alt_thumbnail_library_title">Mein YouTube-Tab</string>
|
||||
<string name="revanced_alt_thumbnail_player_title">Player-Wiedergabelisten & Empfehlungen</string>
|
||||
<string name="revanced_alt_thumbnail_search_title">Suchergebnisse</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_1">Original-Miniaturansichten</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_2">Pfeil & Original-Miniaturansichten</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_3">Pfeil & immer noch erfasst</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_4">Noch Aufnahmen</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_about_summary">"DeArrow bietet von der Community bereitgestellte Miniaturansichten für YouTube-Videos. Diese Miniaturansichten sind oft relevanter als die von YouTube bereitgestellten.
|
||||
<string name="revanced_alt_thumbnail_options_entry_1">Original-Vorschaubilder</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_2">Pfeil & Original-Vorschaubilder</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_3">Pfeil & Standbild</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_4">Standbild</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_about_summary">"DeArrow bietet von der Community bereitgestellte Vorschaubilder für YouTube-Videos. Diese Vorschaubilder sind oft relevanter als die von YouTube bereitgestellten.
|
||||
|
||||
Wenn diese Option aktiviert ist, werden Video-URLs an den API-Server gesendet und keine anderen Daten werden gesendet. Wenn ein Video keine DeArrow-Miniaturansichten hat, werden die Original- oder Still-Captures angezeigt.
|
||||
Wenn diese Option aktiviert ist, werden Video-URLs an den API-Server gesendet und keine anderen Daten werden gesendet. Wenn ein Video keine DeArrow-Vorschaubilder hat, wird das originale Vorschaubild oder ein Standbild angezeigt.
|
||||
|
||||
Tippen Sie hier, um mehr über DeArrow zu erfahren"</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_title">Einen Toast anzeigen, wenn die API nicht verfügbar ist</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_on">Toast wird angezeigt, wenn der Pfeil nicht verfügbar ist</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_off">Toast wird nicht angezeigt, wenn der Pfeil nicht verfügbar ist</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_title">Ein Toast anzeigen, wenn die API nicht verfügbar ist</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_on">Toast wird angezeigt, wenn DeArrow nicht verfügbar ist</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_off">Toast wird nicht angezeigt, wenn DeArrow nicht verfügbar ist</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_api_url_title">DeArrow API-Endpunkt</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_api_url_summary">Die URL des Cache Endpunkts der DeArrow Thumbnails</string>
|
||||
<string name="revanced_alt_thumbnail_stills_about_title">Noch Videoaufnahmen</string>
|
||||
<string name="revanced_alt_thumbnail_stills_about_summary">Die Aufnahmen werden immer noch von Anfang an / Mitte / Ende jedes Videos übernommen. Diese Bilder sind in YouTube eingebaut und es wird keine externe API verwendet</string>
|
||||
<string name="revanced_alt_thumbnail_stills_fast_title">Schnelle Stand-Captures verwenden</string>
|
||||
<string name="revanced_alt_thumbnail_stills_fast_summary_on">Die Verwendung von mittlerer Qualität bleibt erhalten. Die Vorschaubilder werden schneller geladen, aber Live-Streams, unveröffentlichte oder sehr alte Videos können leere Thumbnails anzeigen</string>
|
||||
<string name="revanced_alt_thumbnail_stills_fast_summary_off">Verwendung hoher Qualität immer noch Captures</string>
|
||||
<string name="revanced_alt_thumbnail_stills_time_title">Videozeit für Aufnahmen von</string>
|
||||
<string name="revanced_alt_thumbnail_stills_about_title">Standbilder</string>
|
||||
<string name="revanced_alt_thumbnail_stills_about_summary">Die Standbilder werden vom Anfang / Mitte / Ende jedes Videos erstellt. Diese Bilder stammen von YouTube und es wird keine externe API verwendet</string>
|
||||
<string name="revanced_alt_thumbnail_stills_fast_title">Schnelle Standbilder verwenden</string>
|
||||
<string name="revanced_alt_thumbnail_stills_fast_summary_on">Standbilder in mittlerer Qualität verwenden. Die Vorschaubilder werden schneller geladen, aber Livestreams, unveröffentlichte oder sehr alte Videos können leere Vorschaubilder anzeigen.</string>
|
||||
<string name="revanced_alt_thumbnail_stills_fast_summary_off">Standbilder in hoher Qualität verwenden</string>
|
||||
<string name="revanced_alt_thumbnail_stills_time_title">Videozeitpunkt von dem Standbilder aufgenommen werden</string>
|
||||
<string name="revanced_alt_thumbnail_stills_time_entry_1">Beginn des Videos</string>
|
||||
<string name="revanced_alt_thumbnail_stills_time_entry_2">Mitte des Videos</string>
|
||||
<string name="revanced_alt_thumbnail_stills_time_entry_3">Ende des Videos</string>
|
||||
|
||||
@@ -1163,20 +1163,20 @@ Il existe déjà."</string>
|
||||
<string name="revanced_sb_vote_upvote">Voter pour</string>
|
||||
<string name="revanced_sb_vote_downvote">Voter contre</string>
|
||||
<string name="revanced_sb_vote_category">Modifier la catégorie</string>
|
||||
<string name="revanced_sb_vote_no_segments">Il n\'y a pas de segments où voter</string>
|
||||
<string name="revanced_sb_vote_no_segments">Il n\'y a pas de segments sur lesquels voter</string>
|
||||
<!-- A segment start and end time, such as "02:10 to 03:40". -->
|
||||
<string name="revanced_sb_vote_segment_time_to_from">%1$s – %2$s</string>
|
||||
<string name="revanced_sb_new_segment_choose_category">Choisissez la catégorie du segment</string>
|
||||
<string name="revanced_sb_new_segment_disabled_category">La catégorie est désactivée dans les paramètres. Activez la catégorie pour soumettre.</string>
|
||||
<string name="revanced_sb_new_segment_disabled_category">Catégorie désact. ds paramètres. Activer pr soumettre.</string>
|
||||
<string name="revanced_sb_new_segment_title">Nouveau segment SponsorBlock</string>
|
||||
<string name="revanced_sb_new_segment_mark_time_as_question">Définir %s comme début ou fin du nouveau segment ?</string>
|
||||
<string name="revanced_sb_new_segment_mark_time_as_question">Définir %s comme début ou fin d\'un nouveau segment ?</string>
|
||||
<string name="revanced_sb_new_segment_mark_start">Début</string>
|
||||
<string name="revanced_sb_new_segment_mark_end">Fin</string>
|
||||
<string name="revanced_sb_new_segment_now">Maint.</string>
|
||||
<string name="revanced_sb_new_segment_now">Maintenant</string>
|
||||
<string name="revanced_sb_new_segment_time_start">Instant de début du segment</string>
|
||||
<string name="revanced_sb_new_segment_time_end">Instant de fin du segment</string>
|
||||
<string name="revanced_sb_new_segment_confirm_title">Est-ce que ces valeurs sont correctes ?</string>
|
||||
<string name="revanced_sb_new_segment_confirm_content">"Le segment dure de
|
||||
<string name="revanced_sb_new_segment_confirm_title">Ces valeurs sont-elles correctes ?</string>
|
||||
<string name="revanced_sb_new_segment_confirm_content">"Le segment s'étend de
|
||||
|
||||
%1$s
|
||||
à
|
||||
@@ -1184,10 +1184,10 @@ Il existe déjà."</string>
|
||||
|
||||
(%3$s)
|
||||
|
||||
Prêt à soumettre ?"</string>
|
||||
<string name="revanced_sb_new_segment_start_is_before_end">Le début doit être avant la fin</string>
|
||||
Prêt à le soumettre ?"</string>
|
||||
<string name="revanced_sb_new_segment_start_is_before_end">Le début doit précéder la fin</string>
|
||||
<string name="revanced_sb_new_segment_mark_locations_first">Marquez d\'abord deux emplacements sur la barre de progression</string>
|
||||
<string name="revanced_sb_new_segment_preview_segment_first">Regardez la vidéo au moment du segment, et assurez-vous qu\'il est ignoré de manière fluide</string>
|
||||
<string name="revanced_sb_new_segment_preview_segment_first">Prévisualisez segment + contrôlez fluidité du saut</string>
|
||||
<string name="revanced_sb_new_segment_edit_by_hand_title">Modifier la durée du segment manuellement</string>
|
||||
<string name="revanced_sb_new_segment_edit_by_hand_content">Voulez-vous modifier le début ou la fin du segment ?</string>
|
||||
<string name="revanced_sb_new_segment_edit_by_hand_parse_error">Temps fourni invalide</string>
|
||||
@@ -1209,7 +1209,7 @@ Prêt à soumettre ?"</string>
|
||||
<string name="revanced_sb_stats_saved_sum">Cela représente <b>%s</b> de leur vie.<br>Appuyez ici pour voir le classement</string>
|
||||
<string name="revanced_sb_stats_self_saved">Vous avez passé <b>%s</b> segments</string>
|
||||
<string name="revanced_sb_stats_self_saved_sum">Pour un total de <b>%s</b></string>
|
||||
<string name="revanced_sb_stats_self_saved_reset_title">Réinitialiser le compteur de segments ignorés ?</string>
|
||||
<string name="revanced_sb_stats_self_saved_reset_title">Réinitialiser le compteur de segments passés ?</string>
|
||||
<string name="revanced_sb_stats_saved_hour_format">%1$s heures et %2$s minutes</string>
|
||||
<string name="revanced_sb_stats_saved_minute_format">%1$s minutes et %2$s secondes</string>
|
||||
<string name="revanced_sb_stats_saved_second_format">%s secondes</string>
|
||||
@@ -1478,7 +1478,7 @@ Activer cette option peut déverrouiller des qualités vidéo supérieures"</str
|
||||
<string name="revanced_force_original_audio_summary_on">Utilisation de la langue audio d\'origine</string>
|
||||
<string name="revanced_force_original_audio_summary_off">Utilisation de l\'audio par défaut</string>
|
||||
<!-- 'Spoof video streams' should be the same translation used for 'revanced_spoof_video_streams_screen_title'. -->
|
||||
<string name="revanced_force_original_audio_not_available">Pour utiliser cette fonctionnalité, changez \"Simuler les flux vidéo\" pour tout client sauf Android Studio</string>
|
||||
<string name="revanced_force_original_audio_not_available">Pour utiliser cette fonctionnalité, définissez \"Falsifier les flux vidéo\" sur n\'importe quel client, sauf Android Studio</string>
|
||||
</patch>
|
||||
<patch id="video.quality.rememberVideoQualityPatch">
|
||||
<!-- Translations should use the same text as 'revanced_custom_playback_speeds_auto'. -->
|
||||
|
||||
@@ -624,9 +624,9 @@ YouTube Premium ユーザーの場合、この設定は必要ない可能性が
|
||||
<string name="revanced_hide_clip_button_summary_on">クリップボタンは表示されません</string>
|
||||
<string name="revanced_hide_clip_button_summary_off">クリップボタンは表示されます</string>
|
||||
<!-- 'Shop' should be translated with the same localized wording that YouTube displays. -->
|
||||
<string name="revanced_hide_shop_button_title">「ショップ」を非表示</string>
|
||||
<string name="revanced_hide_shop_button_summary_on">ショップボタンは表示されません</string>
|
||||
<string name="revanced_hide_shop_button_summary_off">ショップボタンは表示されます</string>
|
||||
<string name="revanced_hide_shop_button_title">購入ボタンを非表示</string>
|
||||
<string name="revanced_hide_shop_button_summary_on">購入ボタンは表示されません</string>
|
||||
<string name="revanced_hide_shop_button_summary_off">購入ボタンは表示されます</string>
|
||||
<!-- 'Save' should be translated with the same localized wording that YouTube displays. -->
|
||||
<string name="revanced_hide_save_button_title">「保存」を非表示にする</string>
|
||||
<string name="revanced_hide_save_button_summary_on">「保存」ボタンは表示されません</string>
|
||||
@@ -1314,12 +1314,12 @@ Automotive レイアウト
|
||||
<string name="revanced_miniplayer_rounded_corners_title">丸角を有効化</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">ミニプレーヤーの角は丸角です</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">ミニプレーヤーの角は直角です</string>
|
||||
<string name="revanced_miniplayer_double_tap_action_title">「ダブルタップとピンチでサイズ変更」を有効化</string>
|
||||
<string name="revanced_miniplayer_double_tap_action_summary_on">"「ダブルタップとピンチでサイズ変更」は有効です
|
||||
<string name="revanced_miniplayer_double_tap_action_title">ダブルタップとピンチによるサイズ変更を有効化</string>
|
||||
<string name="revanced_miniplayer_double_tap_action_summary_on">"ダブルタップとピンチによるサイズ変更は有効です
|
||||
|
||||
• ダブルタップすると、ミニプレーヤーのサイズが大きくなる
|
||||
• もう一度ダブルタップすると、元のサイズに戻る"</string>
|
||||
<string name="revanced_miniplayer_double_tap_action_summary_off">「 ダブルタップとピンチでサイズ変更」は無効です</string>
|
||||
<string name="revanced_miniplayer_double_tap_action_summary_off">ダブルタップとピンチによるサイズ変更は無効です</string>
|
||||
<string name="revanced_miniplayer_drag_and_drop_title">ドラッグ&ドロップを有効化</string>
|
||||
<string name="revanced_miniplayer_drag_and_drop_summary_on">"ドラッグ&ドロップは有効です
|
||||
|
||||
@@ -1479,7 +1479,7 @@ Automotive レイアウト
|
||||
<string name="revanced_force_original_audio_summary_on">オリジナルの音声トラック (言語) を使用します\n\nオートダビングを含む吹き替えの音声トラックは使用しません</string>
|
||||
<string name="revanced_force_original_audio_summary_off">アプリが選択した音声トラック (言語) を使用します\n\nオートダビングを含む吹き替えの音声トラックを使用する場合があります</string>
|
||||
<!-- 'Spoof video streams' should be the same translation used for 'revanced_spoof_video_streams_screen_title'. -->
|
||||
<string name="revanced_force_original_audio_not_available">この機能を使用するには、「動画ストリームを偽装」のクライアントを Android Studio を除く任意のクライアントに変更してください</string>
|
||||
<string name="revanced_force_original_audio_not_available">この機能を使用するには、「動画ストリームを偽装」のクライアントを Android Studio 以外の任意のクライアントに変更してください</string>
|
||||
</patch>
|
||||
<patch id="video.quality.rememberVideoQualityPatch">
|
||||
<!-- Translations should use the same text as 'revanced_custom_playback_speeds_auto'. -->
|
||||
@@ -1585,7 +1585,7 @@ Automotive レイアウト
|
||||
<patch id="interaction.permanentrepeat.permanentRepeatPatch">
|
||||
<string name="revanced_music_play_permanent_repeat_title">常時リピートを有効化</string>
|
||||
<string name="revanced_music_play_permanent_repeat_summary_on">常時リピートは有効です\n\nリピート設定が保存され常時適用されます</string>
|
||||
<string name="revanced_music_play_permanent_repeat_summary_off">常時リピートは無効です\n\nリピート設定は保存されません</string>
|
||||
<string name="revanced_music_play_permanent_repeat_summary_off">常時リピートは無効です\n\nリピート設定は保存されず毎回リセットされます</string>
|
||||
</patch>
|
||||
<patch id="layout.compactheader.hideCategoryBar">
|
||||
<string name="revanced_music_hide_category_bar_title">カテゴリバーを非表示</string>
|
||||
|
||||
@@ -1484,7 +1484,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 탭하세요"</string>
|
||||
<string name="revanced_force_original_audio_summary_on">원본 오디오 스트림 언어를 사용 중입니다</string>
|
||||
<string name="revanced_force_original_audio_summary_off">기본 오디오 스트림 언어를 사용 중입니다</string>
|
||||
<!-- 'Spoof video streams' should be the same translation used for 'revanced_spoof_video_streams_screen_title'. -->
|
||||
<string name="revanced_force_original_audio_not_available">이 기능을 사용하려면, \'동영상 스트림 변경하기\'를 Android Studio를 제외한 다른 클라이언트로 변경하세요.</string>
|
||||
<string name="revanced_force_original_audio_not_available">이 기능을 사용하려면, \'동영상 스트림 변경하기\'에서 기본 클라이언트를 Android Studio를 제외한 다른 클라이언트로 변경하세요</string>
|
||||
</patch>
|
||||
<patch id="video.quality.rememberVideoQualityPatch">
|
||||
<!-- Translations should use the same text as 'revanced_custom_playback_speeds_auto'. -->
|
||||
|
||||
@@ -1663,11 +1663,46 @@ Enabling this can unlock higher video qualities"</string>
|
||||
<string name="revanced_music_play_permanent_repeat_summary_on">Permanent repeat is enabled</string>
|
||||
<string name="revanced_music_play_permanent_repeat_summary_off">Permanent repeat is disabled</string>
|
||||
</patch>
|
||||
<patch id="layout.castbutton.hideCastButton">
|
||||
<string name="revanced_music_hide_cast_button_title">Hide cast button</string>
|
||||
<string name="revanced_music_hide_cast_button_summary_on">Cast button is hidden</string>
|
||||
<string name="revanced_music_hide_cast_button_summary_off">Cast button is shown</string>
|
||||
</patch>
|
||||
<patch id="layout.compactheader.hideCategoryBar">
|
||||
<string name="revanced_music_hide_category_bar_title">Hide category bar</string>
|
||||
<string name="revanced_music_hide_category_bar_summary_on">Category bar is hidden</string>
|
||||
<string name="revanced_music_hide_category_bar_summary_off">Category bar is shown</string>
|
||||
</patch>
|
||||
<patch id="layout.navigationbar.navigationBarPatch">
|
||||
<string name="revanced_music_navigation_bar_screen_title">Navigation bar</string>
|
||||
<string name="revanced_music_navigation_bar_screen_summary">Hide or change navigation bar buttons</string>
|
||||
<!-- 'Home' should be translated using the same localized wording YouTube Music displays for the tab. -->
|
||||
<string name="revanced_music_hide_navigation_bar_home_button_title">Hide Home button</string>
|
||||
<string name="revanced_music_hide_navigation_bar_home_button_summary_on">Home button is hidden</string>
|
||||
<string name="revanced_music_hide_navigation_bar_home_button_summary_off">Home button is shown</string>
|
||||
<!-- 'Samples' should be translated using the same localized wording YouTube Music displays for the tab. -->
|
||||
<string name="revanced_music_hide_navigation_bar_samples_button_title">Hide Samples button</string>
|
||||
<string name="revanced_music_hide_navigation_bar_samples_button_summary_on">Samples button is hidden</string>
|
||||
<string name="revanced_music_hide_navigation_bar_samples_button_summary_off">Samples button is shown</string>
|
||||
<!-- 'Explore' should be translated using the same localized wording YouTube Music displays for the tab. -->
|
||||
<string name="revanced_music_hide_navigation_bar_explore_button_title">Hide Explore button</string>
|
||||
<string name="revanced_music_hide_navigation_bar_explore_button_summary_on">Explore button is hidden</string>
|
||||
<string name="revanced_music_hide_navigation_bar_explore_button_summary_off">Explore button is shown</string>
|
||||
<!-- 'Library' should be translated using the same localized wording YouTube Music displays for the tab. -->
|
||||
<string name="revanced_music_hide_navigation_bar_library_button_title">Hide Library button</string>
|
||||
<string name="revanced_music_hide_navigation_bar_library_button_summary_on">Library button is hidden</string>
|
||||
<string name="revanced_music_hide_navigation_bar_library_button_summary_off">Library button is shown</string>
|
||||
<!-- 'Upgrade' should be translated using the same localized wording YouTube Music displays for the tab. -->
|
||||
<string name="revanced_music_hide_navigation_bar_upgrade_button_title">Hide Upgrade button</string>
|
||||
<string name="revanced_music_hide_navigation_bar_upgrade_button_summary_on">Upgrade button is hidden</string>
|
||||
<string name="revanced_music_hide_navigation_bar_upgrade_button_summary_off">Upgrade button is shown</string>
|
||||
<string name="revanced_music_hide_navigation_bar_title">Hide navigation bar</string>
|
||||
<string name="revanced_music_hide_navigation_bar_summary_on">Navigation bar is hidden</string>
|
||||
<string name="revanced_music_hide_navigation_bar_summary_off">Navigation bar is shown</string>
|
||||
<string name="revanced_music_hide_navigation_bar_labels_title">Hide navigation button labels</string>
|
||||
<string name="revanced_music_hide_navigation_bar_labels_summary_on">Labels are hidden</string>
|
||||
<string name="revanced_music_hide_navigation_bar_labels_summary_off">Labels are shown</string>
|
||||
</patch>
|
||||
<patch id="layout.premium.hideGetPremiumPatch">
|
||||
<string name="revanced_music_hide_get_premium_label_title">Hide \'Get Music Premium\' label</string>
|
||||
<string name="revanced_music_hide_get_premium_label_summary_on">Label is hidden</string>
|
||||
|
||||
Reference in New Issue
Block a user