mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-24 03:01:03 +00:00
feat(YouTube): Add Pause on audio interrupt patch (#6464)
Co-authored-by: bengross <bengross@vecta.com> Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class PauseOnAudioInterruptPatch {
|
||||||
|
|
||||||
|
private static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = -3;
|
||||||
|
private static final int AUDIOFOCUS_LOSS_TRANSIENT = -2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point for AudioFocusRequest builder.
|
||||||
|
* Returns true if audio ducking should be disabled (willPauseWhenDucked = true).
|
||||||
|
*/
|
||||||
|
public static boolean shouldPauseOnAudioInterrupt() {
|
||||||
|
return Settings.PAUSE_ON_AUDIO_INTERRUPT.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point for onAudioFocusChange callback.
|
||||||
|
* Converts AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK to AUDIOFOCUS_LOSS_TRANSIENT
|
||||||
|
* when the setting is enabled, causing YouTube to pause instead of ducking.
|
||||||
|
*/
|
||||||
|
public static int overrideAudioFocusChange(int focusChange) {
|
||||||
|
if (Settings.PAUSE_ON_AUDIO_INTERRUPT.get() && focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
|
||||||
|
return AUDIOFOCUS_LOSS_TRANSIENT;
|
||||||
|
}
|
||||||
|
return focusChange;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -356,6 +356,7 @@ public class Settings extends BaseSettings {
|
|||||||
public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1, false, false);
|
public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1, false, false);
|
||||||
public static final BooleanSetting LOOP_VIDEO = new BooleanSetting("revanced_loop_video", FALSE);
|
public static final BooleanSetting LOOP_VIDEO = new BooleanSetting("revanced_loop_video", FALSE);
|
||||||
public static final BooleanSetting LOOP_VIDEO_BUTTON = new BooleanSetting("revanced_loop_video_button", FALSE);
|
public static final BooleanSetting LOOP_VIDEO_BUTTON = new BooleanSetting("revanced_loop_video_button", FALSE);
|
||||||
|
public static final BooleanSetting PAUSE_ON_AUDIO_INTERRUPT = new BooleanSetting("revanced_pause_on_audio_interrupt", FALSE, true);
|
||||||
public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE);
|
public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE);
|
||||||
public static final BooleanSetting DISABLE_HAPTIC_FEEDBACK_CHAPTERS = new BooleanSetting("revanced_disable_haptic_feedback_chapters", FALSE);
|
public static final BooleanSetting DISABLE_HAPTIC_FEEDBACK_CHAPTERS = new BooleanSetting("revanced_disable_haptic_feedback_chapters", FALSE);
|
||||||
public static final BooleanSetting DISABLE_HAPTIC_FEEDBACK_PRECISE_SEEKING = new BooleanSetting("revanced_disable_haptic_feedback_precise_seeking", FALSE);
|
public static final BooleanSetting DISABLE_HAPTIC_FEEDBACK_PRECISE_SEEKING = new BooleanSetting("revanced_disable_haptic_feedback_precise_seeking", FALSE);
|
||||||
|
|||||||
@@ -1696,6 +1696,10 @@ public final class app/revanced/patches/youtube/misc/announcements/Announcements
|
|||||||
public static final fun getAnnouncementsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getAnnouncementsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/youtube/misc/audiofocus/PauseOnAudioInterruptPatchKt {
|
||||||
|
public static final fun getPauseOnAudioInterruptPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatchKt {
|
public final class app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatchKt {
|
||||||
public static final fun getAutoRepeatPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getAutoRepeatPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.audiofocus
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint
|
||||||
|
|
||||||
|
internal val audioFocusChangeListenerFingerprint = fingerprint {
|
||||||
|
strings(
|
||||||
|
"AudioFocus DUCK",
|
||||||
|
"AudioFocus loss; Will lower volume",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val audioFocusRequestBuilderFingerprint = fingerprint {
|
||||||
|
strings("Can't build an AudioFocusRequestCompat instance without a listener")
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.audiofocus
|
||||||
|
|
||||||
|
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.patch.bytecodePatch
|
||||||
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
|
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
|
||||||
|
|
||||||
|
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/PauseOnAudioInterruptPatch;"
|
||||||
|
|
||||||
|
val pauseOnAudioInterruptPatch = bytecodePatch(
|
||||||
|
name = "Pause on audio interrupt",
|
||||||
|
description = "Adds an option to pause playback instead of lowering volume when other audio plays.",
|
||||||
|
) {
|
||||||
|
dependsOn(
|
||||||
|
sharedExtensionPatch,
|
||||||
|
settingsPatch,
|
||||||
|
addResourcesPatch,
|
||||||
|
)
|
||||||
|
|
||||||
|
compatibleWith(
|
||||||
|
"com.google.android.youtube"(
|
||||||
|
"20.14.43",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
addResources("youtube", "misc.audiofocus.pauseOnAudioInterruptPatch")
|
||||||
|
|
||||||
|
PreferenceScreen.MISC.addPreferences(
|
||||||
|
SwitchPreference("revanced_pause_on_audio_interrupt"),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Hook the builder method that creates AudioFocusRequest.
|
||||||
|
// At the start, set the willPauseWhenDucked field (b) to true if setting is enabled.
|
||||||
|
val builderMethod = audioFocusRequestBuilderFingerprint.method
|
||||||
|
val builderClass = builderMethod.definingClass
|
||||||
|
|
||||||
|
builderMethod.addInstructionsWithLabels(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->shouldPauseOnAudioInterrupt()Z
|
||||||
|
move-result v0
|
||||||
|
if-eqz v0, :skip_override
|
||||||
|
const/4 v0, 0x1
|
||||||
|
iput-boolean v0, p0, $builderClass->b:Z
|
||||||
|
""",
|
||||||
|
ExternalLabel("skip_override", builderMethod.getInstruction(0)),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Also hook the audio focus change listener as a backup.
|
||||||
|
audioFocusChangeListenerFingerprint.method.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->overrideAudioFocusChange(I)I
|
||||||
|
move-result p1
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1558,6 +1558,11 @@ Tap here to learn more about DeArrow"</string>
|
|||||||
<string name="revanced_loop_video_button_toast_on">Loop video is on</string>
|
<string name="revanced_loop_video_button_toast_on">Loop video is on</string>
|
||||||
<string name="revanced_loop_video_button_toast_off">Loop video is off</string>
|
<string name="revanced_loop_video_button_toast_off">Loop video is off</string>
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="misc.audiofocus.pauseOnAudioInterruptPatch">
|
||||||
|
<string name="revanced_pause_on_audio_interrupt_title">Pause on audio interrupt</string>
|
||||||
|
<string name="revanced_pause_on_audio_interrupt_summary_on">Playback pauses when other audio plays (e.g. navigation)</string>
|
||||||
|
<string name="revanced_pause_on_audio_interrupt_summary_off">Volume lowers when other audio plays</string>
|
||||||
|
</patch>
|
||||||
<patch id="misc.dimensions.spoof.spoofDeviceDimensionsPatch">
|
<patch id="misc.dimensions.spoof.spoofDeviceDimensionsPatch">
|
||||||
<string name="revanced_spoof_device_dimensions_title">Spoof device dimensions</string>
|
<string name="revanced_spoof_device_dimensions_title">Spoof device dimensions</string>
|
||||||
<string name="revanced_spoof_device_dimensions_summary_on">"Device dimensions spoofed
|
<string name="revanced_spoof_device_dimensions_summary_on">"Device dimensions spoofed
|
||||||
|
|||||||
Reference in New Issue
Block a user