You've already forked revanced-integrations
mirror of
https://github.com/revanced/revanced-integrations
synced 2025-11-21 18:35:37 +01:00
Compare commits
17 Commits
v1.0.1-dev
...
v1.1.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
098df9a4a6 | ||
|
|
6f3f88264e | ||
|
|
6ca7946e8f | ||
|
|
741ab2468d | ||
|
|
6263edce11 | ||
|
|
14396fc2c0 | ||
|
|
4397eedeeb | ||
|
|
e28b8cc59a | ||
|
|
7584090ac2 | ||
|
|
88b3ca4992 | ||
|
|
5ae2312804 | ||
|
|
0f6dee5bae | ||
|
|
d241e437ee | ||
|
|
2814d9d8c4 | ||
|
|
2003b910b1 | ||
|
|
10dfa6d695 | ||
|
|
05eddb68d5 |
56
CHANGELOG.md
56
CHANGELOG.md
@@ -1,3 +1,59 @@
|
||||
# [1.1.0-dev.7](https://github.com/ReVanced/revanced-integrations/compare/v1.1.0-dev.6...v1.1.0-dev.7) (2023-12-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Hide layout components:** Hide emergency box when enabled ([6ca7946](https://github.com/ReVanced/revanced-integrations/commit/6ca7946e8f3d5be76241b88f1d7a5a881629dda9))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube:** Add `Remove viewer discretion dialog` patch ([6f3f882](https://github.com/ReVanced/revanced-integrations/commit/6f3f88264e736b80f88103e795534f86f053c8d1))
|
||||
|
||||
# [1.1.0-dev.6](https://github.com/ReVanced/revanced-integrations/compare/v1.1.0-dev.5...v1.1.0-dev.6) (2023-12-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - VideoInformation:** Ignore video seek attempts during the last 250ms of video playback ([6263edc](https://github.com/ReVanced/revanced-integrations/commit/6263edce11077f9e9c0629d9260e2f2eaef1c0e8))
|
||||
|
||||
# [1.1.0-dev.5](https://github.com/ReVanced/revanced-integrations/compare/v1.1.0-dev.4...v1.1.0-dev.5) (2023-12-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Hide ads:** Hide new type of ad ([#545](https://github.com/ReVanced/revanced-integrations/issues/545)) ([e28b8cc](https://github.com/ReVanced/revanced-integrations/commit/e28b8cc59a445ba8f184ba6f5b9e076b7731129a))
|
||||
* **YouTube - Hide ads:** Use correct filter ([4397eed](https://github.com/ReVanced/revanced-integrations/commit/4397eedeeb21edda235cd27cd66088e94bde49e4))
|
||||
|
||||
# [1.1.0-dev.4](https://github.com/ReVanced/revanced-integrations/compare/v1.1.0-dev.3...v1.1.0-dev.4) (2023-12-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - SponsorBlock:** Do not auto skip end segments more than once if using a slow playback speed ([88b3ca4](https://github.com/ReVanced/revanced-integrations/commit/88b3ca4992e8278e1d43dbe5cc7607d4890c0eda))
|
||||
|
||||
# [1.1.0-dev.3](https://github.com/ReVanced/revanced-integrations/compare/v1.1.0-dev.2...v1.1.0-dev.3) (2023-12-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Hide ads:** Hide fullscreen ads ([0f6dee5](https://github.com/ReVanced/revanced-integrations/commit/0f6dee5bae6b8017a53830587e09079942bc24aa))
|
||||
* **YouTube - Hide layout components:** Hide search result recommendations ([d241e43](https://github.com/ReVanced/revanced-integrations/commit/d241e437ee25cc2211bf06b4a7f8fd1c295fad25))
|
||||
|
||||
# [1.1.0-dev.2](https://github.com/ReVanced/revanced-integrations/compare/v1.1.0-dev.1...v1.1.0-dev.2) (2023-12-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Tiktok - Remember clear display:** Use correct name ([2003b91](https://github.com/ReVanced/revanced-integrations/commit/2003b910b12cba445822bfaede7975e00220a81a))
|
||||
|
||||
# [1.1.0-dev.1](https://github.com/ReVanced/revanced-integrations/compare/v1.0.1-dev.2...v1.1.0-dev.1) (2023-12-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Tiktok:** Add `Remember clear mode` patch ([#544](https://github.com/ReVanced/revanced-integrations/issues/544)) ([05eddb6](https://github.com/ReVanced/revanced-integrations/commit/05eddb68d5d5de1b76545c42313d4e9f9ba6712e))
|
||||
|
||||
## [1.0.1-dev.2](https://github.com/ReVanced/revanced-integrations/compare/v1.0.1-dev.1...v1.0.1-dev.2) (2023-12-17)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class RemoveViewerDiscretionDialogPatch {
|
||||
public static void confirmDialog(AlertDialog dialog) {
|
||||
if (!SettingsEnum.REMOVE_VIEWER_DISCRETION_DIALOG.getBoolean()) {
|
||||
// Since the patch replaces the AlertDialog#show() method, we need to call the original method here.
|
||||
dialog.show();
|
||||
return;
|
||||
}
|
||||
|
||||
final var button = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
||||
button.setSoundEffectsEnabled(false);
|
||||
button.performClick();
|
||||
}
|
||||
}
|
||||
@@ -157,20 +157,29 @@ public final class VideoInformation {
|
||||
* Caution: If called from a videoTimeHook() callback,
|
||||
* this will cause a recursive call into the same videoTimeHook() callback.
|
||||
*
|
||||
* @param millisecond The millisecond to seek the video to.
|
||||
* @param seekTime The seekTime to seek the video to.
|
||||
* @return true if the seek was successful.
|
||||
*/
|
||||
public static boolean seekTo(final long millisecond) {
|
||||
final long videoLength = getVideoLength();
|
||||
|
||||
// Prevent issues such as play/ pause button or autoplay not working.
|
||||
final long seekToMilliseconds = Math.min(millisecond, VideoInformation.getVideoLength() - 250);
|
||||
|
||||
public static boolean seekTo(final long seekTime) {
|
||||
ReVancedUtils.verifyOnMainThread();
|
||||
try {
|
||||
LogHelper.printDebug(() -> "Seeking to " + seekToMilliseconds);
|
||||
final long videoTime = getVideoTime();
|
||||
final long videoLength = getVideoLength();
|
||||
|
||||
// Prevent issues such as play/ pause button or autoplay not working.
|
||||
final long adjustedSeekTime = Math.min(seekTime, videoLength - 250);
|
||||
if (videoTime <= seekTime && videoTime >= adjustedSeekTime) {
|
||||
// Both the current video time and the seekTo are in the last 250ms of the video.
|
||||
// Ignore this seek call, otherwise if a video ends with multiple closely timed segments
|
||||
// then seeking here can create an infinite loop of skip attempts.
|
||||
LogHelper.printDebug(() -> "Ignoring seekTo call as video playback is almost finished. "
|
||||
+ " videoTime: " + videoTime + " videoLength: " + videoLength + " seekTo: " + seekTime);
|
||||
return false;
|
||||
}
|
||||
|
||||
LogHelper.printDebug(() -> "Seeking to " + adjustedSeekTime);
|
||||
//noinspection DataFlowIssue
|
||||
return (Boolean) seekMethod.invoke(playerControllerRef.get(), seekToMilliseconds);
|
||||
return (Boolean) seekMethod.invoke(playerControllerRef.get(), adjustedSeekTime);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "Failed to seek", ex);
|
||||
return false;
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
package app.revanced.integrations.patches.components;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import app.revanced.integrations.utils.StringTrieSearch;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class AdsFilter extends Filter {
|
||||
// region Fullscreen ad
|
||||
private static long lastTimeClosedFullscreenAd = 0;
|
||||
private static final Instrumentation instrumentation = new Instrumentation();
|
||||
private final StringFilterGroup fullscreenAd;
|
||||
|
||||
// endregion
|
||||
|
||||
private final StringTrieSearch exceptions = new StringTrieSearch();
|
||||
private final StringFilterGroup shoppingLinks;
|
||||
|
||||
@@ -24,6 +34,7 @@ public final class AdsFilter extends Filter {
|
||||
|
||||
// Identifiers.
|
||||
|
||||
|
||||
final var carouselAd = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_GENERAL_ADS,
|
||||
"carousel_ad"
|
||||
@@ -32,6 +43,11 @@ public final class AdsFilter extends Filter {
|
||||
|
||||
// Paths.
|
||||
|
||||
fullscreenAd = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_FULLSCREEN_ADS,
|
||||
"_interstitial"
|
||||
);
|
||||
|
||||
final var buttonedAd = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_BUTTONED_ADS,
|
||||
"_buttoned_layout",
|
||||
@@ -39,7 +55,8 @@ public final class AdsFilter extends Filter {
|
||||
"_ad_with",
|
||||
"text_image_button_group_layout",
|
||||
"video_display_button_group_layout",
|
||||
"landscape_image_wide_button_layout"
|
||||
"landscape_image_wide_button_layout",
|
||||
"video_display_carousel_button_group_layout"
|
||||
);
|
||||
|
||||
final var generalAds = new StringFilterGroup(
|
||||
@@ -102,6 +119,7 @@ public final class AdsFilter extends Filter {
|
||||
merchandise,
|
||||
viewProducts,
|
||||
selfSponsor,
|
||||
fullscreenAd,
|
||||
webLinkPanel,
|
||||
shoppingLinks,
|
||||
movieAds
|
||||
@@ -112,7 +130,11 @@ public final class AdsFilter extends Filter {
|
||||
public boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
if (exceptions.matches(path))
|
||||
return false;
|
||||
return false;
|
||||
|
||||
if (matchedGroup == fullscreenAd && path.contains("|ImageType|")) {
|
||||
closeFullscreenAd();
|
||||
}
|
||||
|
||||
// Check for the index because of likelihood of false positives.
|
||||
if (matchedGroup == shoppingLinks && contentIndex != 0)
|
||||
@@ -129,4 +151,21 @@ public final class AdsFilter extends Filter {
|
||||
public static void hideAdAttributionView(View view) {
|
||||
ReVancedUtils.hideViewBy1dpUnderCondition(SettingsEnum.HIDE_GENERAL_ADS, view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the fullscreen ad.
|
||||
* <p>
|
||||
* The strategy is to send a back button event to the app to close the fullscreen ad using the back button event.
|
||||
*/
|
||||
private static void closeFullscreenAd() {
|
||||
final var currentTime = System.currentTimeMillis();
|
||||
|
||||
// Prevent spamming the back button.
|
||||
if (currentTime - lastTimeClosedFullscreenAd < 10000) return;
|
||||
lastTimeClosedFullscreenAd = currentTime;
|
||||
|
||||
LogHelper.printDebug(() -> "Closing fullscreen ad");
|
||||
|
||||
ReVancedUtils.runOnMainThreadDelayed(() -> instrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK), 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
private final StringFilterGroup inFeedSurvey;
|
||||
private final StringFilterGroup notifyMe;
|
||||
private final StringFilterGroup expandableMetadata;
|
||||
private final ByteArrayFilterGroup searchResultRecommendations;
|
||||
private final StringFilterGroup searchResultVideo;
|
||||
|
||||
static {
|
||||
mixPlaylistsExceptions.addPatterns(
|
||||
@@ -41,6 +43,7 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
exceptions.addPatterns(
|
||||
"home_video_with_context",
|
||||
"related_video_with_context",
|
||||
"search_video_with_context",
|
||||
"comment_thread", // Whitelist comments
|
||||
"|comment.", // Whitelist comment replies
|
||||
"library_recent_shelf"
|
||||
@@ -85,7 +88,6 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
"sponsorships_comments_upsell"
|
||||
);
|
||||
|
||||
|
||||
final var channelMemberShelf = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_CHANNEL_MEMBER_SHELF,
|
||||
"member_recognition_shelf"
|
||||
@@ -128,6 +130,11 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
"channel_guidelines_entry_banner"
|
||||
);
|
||||
|
||||
final var emergencyBox = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_EMERGENCY_BOX,
|
||||
"emergency_onebox"
|
||||
);
|
||||
|
||||
// The player audio track button does the exact same function as the audio track flyout menu option.
|
||||
// But if the copy url button is shown, these button clashes and the the audio button does not work.
|
||||
// Previously this was a setting to show/hide the player button.
|
||||
@@ -208,6 +215,16 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
"mixed_content_shelf"
|
||||
);
|
||||
|
||||
searchResultVideo = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SEARCH_RESULT_RECOMMENDATIONS,
|
||||
"search_video_with_context.eml"
|
||||
);
|
||||
|
||||
searchResultRecommendations = new ByteArrayFilterGroup(
|
||||
SettingsEnum.HIDE_SEARCH_RESULT_RECOMMENDATIONS,
|
||||
"endorsement_header_footer"
|
||||
);
|
||||
|
||||
addPathCallbacks(
|
||||
custom,
|
||||
expandableMetadata,
|
||||
@@ -216,6 +233,7 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
channelBar,
|
||||
communityPosts,
|
||||
paidContent,
|
||||
searchResultVideo,
|
||||
latestPosts,
|
||||
channelWatermark,
|
||||
communityGuidelines,
|
||||
@@ -226,6 +244,7 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
medicalPanel,
|
||||
videoQualityMenuFooter,
|
||||
infoPanel,
|
||||
emergencyBox,
|
||||
subscribersCommunityGuidelines,
|
||||
channelGuidelines,
|
||||
audioTrackButton,
|
||||
@@ -240,10 +259,15 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
@Override
|
||||
public boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
if (matchedGroup == searchResultVideo) {
|
||||
if (searchResultRecommendations.check(protobufBufferArray).isFiltered()) {
|
||||
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// The groups are excluded from the filter due to the exceptions list below.
|
||||
// Filter them separately here.
|
||||
if (matchedGroup == notifyMe || matchedGroup == inFeedSurvey || matchedGroup == expandableMetadata)
|
||||
if (matchedGroup == notifyMe || matchedGroup == inFeedSurvey || matchedGroup == expandableMetadata)
|
||||
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
|
||||
|
||||
if (matchedGroup != custom && exceptions.matches(path))
|
||||
|
||||
@@ -43,6 +43,7 @@ public enum SettingsEnum {
|
||||
"0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true),
|
||||
|
||||
// Ads
|
||||
HIDE_FULLSCREEN_ADS("revanced_hide_fullscreen_ads", BOOLEAN, TRUE),
|
||||
HIDE_BUTTONED_ADS("revanced_hide_buttoned_ads", BOOLEAN, TRUE),
|
||||
HIDE_GENERAL_ADS("revanced_hide_general_ads", BOOLEAN, TRUE),
|
||||
HIDE_GET_PREMIUM("revanced_hide_get_premium", BOOLEAN, TRUE),
|
||||
@@ -121,6 +122,7 @@ public enum SettingsEnum {
|
||||
HIDE_VIDEO_CHANNEL_WATERMARK("revanced_hide_channel_watermark", BOOLEAN, TRUE),
|
||||
HIDE_FOR_YOU_SHELF("revanced_hide_for_you_shelf", BOOLEAN, TRUE),
|
||||
HIDE_VIDEO_QUALITY_MENU_FOOTER("revanced_hide_video_quality_menu_footer", BOOLEAN, TRUE),
|
||||
HIDE_SEARCH_RESULT_RECOMMENDATIONS("revanced_hide_search_result_recommendations", BOOLEAN, TRUE),
|
||||
PLAYER_OVERLAY_OPACITY("revanced_player_overlay_opacity", INTEGER, 100, true),
|
||||
PLAYER_POPUP_PANELS("revanced_hide_player_popup_panels", BOOLEAN, FALSE),
|
||||
SPOOF_APP_VERSION("revanced_spoof_app_version", BOOLEAN, FALSE, true, "revanced_spoof_app_version_user_dialog_message"),
|
||||
@@ -207,6 +209,8 @@ public enum SettingsEnum {
|
||||
ANNOUNCEMENT_CONSUMER("revanced_announcement_consumer", STRING, ""),
|
||||
ANNOUNCEMENT_LAST_HASH("revanced_announcement_last_hash", STRING, ""),
|
||||
REMOVE_TRACKING_QUERY_PARAMETER("revanced_remove_tracking_query_parameter", BOOLEAN, TRUE),
|
||||
REMOVE_VIEWER_DISCRETION_DIALOG("revanced_remove_viewer_discretion_dialog", BOOLEAN, FALSE,
|
||||
"revanced_remove_viewer_discretion_dialog_user_dialog_message"),
|
||||
|
||||
// Swipe controls
|
||||
SWIPE_BRIGHTNESS("revanced_swipe_brightness", BOOLEAN, TRUE),
|
||||
|
||||
@@ -510,15 +510,18 @@ public class SegmentPlaybackController {
|
||||
SponsorBlockViewController.hideSkipHighlightButton();
|
||||
SponsorBlockViewController.hideSkipSegmentButton();
|
||||
|
||||
// If trying to seek to end of the video, YouTube can seek just before of the actual end.
|
||||
// (especially if the video does not end on a whole second boundary).
|
||||
// This causes additional segment skip attempts, even though it cannot seek any closer to the desired time.
|
||||
// Check for and ignore repeated skip attempts of the same segment over a small time period.
|
||||
final long now = System.currentTimeMillis();
|
||||
final long minimumMillisecondsBetweenSkippingSameSegment = 500;
|
||||
if ((lastSegmentSkipped == segmentToSkip) && (now - lastSegmentSkippedTime < minimumMillisecondsBetweenSkippingSameSegment)) {
|
||||
LogHelper.printDebug(() -> "Ignoring skip segment request (already skipped as close as possible): " + segmentToSkip);
|
||||
return;
|
||||
if (lastSegmentSkipped == segmentToSkip) {
|
||||
// If trying to seek to end of the video, YouTube can seek just before of the actual end.
|
||||
// (especially if the video does not end on a whole second boundary).
|
||||
// This causes additional segment skip attempts, even though it cannot seek any closer to the desired time.
|
||||
// Check for and ignore repeated skip attempts of the same segment over a small time period.
|
||||
final long minTimeBetweenSkippingSameSegment = Math.max(500,
|
||||
(long) (500 / VideoInformation.getPlaybackSpeed()));
|
||||
if (now - lastSegmentSkippedTime < minTimeBetweenSkippingSameSegment) {
|
||||
LogHelper.printDebug(() -> "Ignoring skip segment request (already skipped as close as possible): " + segmentToSkip);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LogHelper.printDebug(() -> "Skipping segment: " + segmentToSkip);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package app.revanced.tiktok.cleardisplay;
|
||||
|
||||
import app.revanced.tiktok.settings.SettingsEnum;
|
||||
|
||||
public class RememberClearDisplayPatch {
|
||||
public static boolean getClearDisplayState() {
|
||||
return SettingsEnum.CLEAR_DISPLAY.getBoolean();
|
||||
}
|
||||
public static void rememberClearDisplayState(boolean newState) {
|
||||
SettingsEnum.CLEAR_DISPLAY.saveValue(newState);
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ public enum SettingsEnum {
|
||||
MIN_MAX_LIKES("min_max_likes", STRING, "0-" + Long.MAX_VALUE, true),
|
||||
DOWNLOAD_PATH("down_path", STRING, "DCIM/TikTok"),
|
||||
DOWNLOAD_WATERMARK("down_watermark", BOOLEAN, TRUE),
|
||||
CLEAR_DISPLAY("clear_display", BOOLEAN, FALSE),
|
||||
SIM_SPOOF("simspoof", BOOLEAN, TRUE, true),
|
||||
SIM_SPOOF_ISO("simspoof_iso", STRING, "us"),
|
||||
SIMSPOOF_MCCMNC("simspoof_mccmnc", STRING, "310160"),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
org.gradle.parallel = true
|
||||
org.gradle.caching = true
|
||||
android.useAndroidX = true
|
||||
version = 1.0.1-dev.2
|
||||
version = 1.1.0-dev.7
|
||||
|
||||
Reference in New Issue
Block a user