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
9 Commits
v0.105.0-d
...
v0.106.0-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27fdcfff08 | ||
|
|
f6f6c93c57 | ||
|
|
a661dac623 | ||
|
|
8cc1b6ea4a | ||
|
|
829895874b | ||
|
|
6b15514885 | ||
|
|
5b53e02613 | ||
|
|
2deacc5035 | ||
|
|
46d70a3e00 |
35
CHANGELOG.md
35
CHANGELOG.md
@@ -1,3 +1,38 @@
|
||||
# [0.106.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.105.1-dev.2...v0.106.0-dev.1) (2023-04-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/spoof-app-version:** user selectable version to spoof ([#375](https://github.com/revanced/revanced-integrations/issues/375)) ([f6f6c93](https://github.com/revanced/revanced-integrations/commit/f6f6c93c57bdbec13f09acd802f58554cb981f3a))
|
||||
|
||||
## [0.105.1-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.105.1-dev.1...v0.105.1-dev.2) (2023-04-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/spoof-signature-verification:** more fixes for subtitle window positions ([#374](https://github.com/revanced/revanced-integrations/issues/374)) ([8cc1b6e](https://github.com/revanced/revanced-integrations/commit/8cc1b6ea4af4e642fb2d97233d50f34b0113f2c0))
|
||||
|
||||
## [0.105.1-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.105.0...v0.105.1-dev.1) (2023-04-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube:** no longer need to restart the app after changing `copy-video-url` or `downloads` patch ([#372](https://github.com/revanced/revanced-integrations/issues/372)) ([6b15514](https://github.com/revanced/revanced-integrations/commit/6b155148854fbfe155c9384ba8976b5ddf3d5992))
|
||||
|
||||
# [0.105.0](https://github.com/revanced/revanced-integrations/compare/v0.104.0...v0.105.0) (2023-04-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/minimized-playback:** disable minimized playback for shorts ([#371](https://github.com/revanced/revanced-integrations/issues/371)) ([df4b03f](https://github.com/revanced/revanced-integrations/commit/df4b03fed5a0622b18bf4a8dca1940d26a590d8f))
|
||||
* **youtube/return-youtube-dislike:** fix dislikes using wrong font if dark mode is enabled during video playback ([#368](https://github.com/revanced/revanced-integrations/issues/368)) ([3b37a3b](https://github.com/revanced/revanced-integrations/commit/3b37a3b41f7bfbc4a6d6d12e2deb2acd9bb2ccc8))
|
||||
* **youtube/spoof-signature-verification:** additional fixes for subtitle window positions ([#369](https://github.com/revanced/revanced-integrations/issues/369)) ([6f2ae31](https://github.com/revanced/revanced-integrations/commit/6f2ae313cf492166d64e5e33e759f2b234191b64))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/sponsorblock:** automatically hide skip button ([#365](https://github.com/revanced/revanced-integrations/issues/365)) ([75dad2f](https://github.com/revanced/revanced-integrations/commit/75dad2f3071c19aa097ebdc7bd83d1ce9afb78ea))
|
||||
|
||||
# [0.105.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.105.0-dev.1...v0.105.0-dev.2) (2023-04-27)
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import app.revanced.integrations.shared.PlayerType;
|
||||
|
||||
public class MinimizedPlaybackPatch {
|
||||
|
||||
public static boolean playbackIsNotShort() {
|
||||
public static boolean isPlaybackNotShort() {
|
||||
return !PlayerType.getCurrent().isNoneOrHidden();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,8 @@ import app.revanced.integrations.settings.SettingsEnum;
|
||||
public class SpoofAppVersionPatch {
|
||||
|
||||
public static String getYouTubeVersionOverride(String version) {
|
||||
if (SettingsEnum.SPOOF_APP_VERSION.getBoolean()){
|
||||
// Override with the most recent version that does not show the new UI player layout.
|
||||
// If the new UI shows up for some users, then change this to an older version (such as 17.29.34).
|
||||
return "17.30.34";
|
||||
if (SettingsEnum.SPOOF_APP_VERSION.getBoolean()) {
|
||||
return SettingsEnum.SPOOF_APP_VERSION_TARGET.getString();
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
@@ -31,13 +31,27 @@ public class SpoofSignatureVerificationPatch {
|
||||
"SAFg" // Autoplay in scrim
|
||||
};
|
||||
|
||||
@Nullable
|
||||
private static String currentVideoId;
|
||||
/**
|
||||
* On app first start, the first video played usually contains a single non-default window setting value
|
||||
* and all other subtitle settings for the video are (incorrect) default shorts window settings.
|
||||
* For this situation, the shorts settings must be replaced.
|
||||
*
|
||||
* But some videos use multiple text positions on screen (such as https://youtu.be/3hW1rMNC89o),
|
||||
* and by chance many of the subtitles uses window positions that match a default shorts position.
|
||||
* To handle these videos, selectively allowing the shorts specific window settings to 'pass thru' unchanged,
|
||||
* but only if the video contains multiple non-default subtitle window positions.
|
||||
*
|
||||
* Do not enable 'pass thru mode' until this many non default subtitle settings are observed for a single video.
|
||||
*/
|
||||
private static final int NUMBER_OF_NON_DEFAULT_SUBTITLES_BEFORE_ENABLING_PASSTHRU = 2;
|
||||
|
||||
/**
|
||||
* If any of the subtitles settings encountered from the current video have been non default values.
|
||||
* The number of non default subtitle settings encountered for the current video.
|
||||
*/
|
||||
private static boolean nonDefaultSubtitlesEncountered;
|
||||
private static int numberOfNonDefaultSettingsObserved;
|
||||
|
||||
@Nullable
|
||||
private static String currentVideoId;
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
@@ -137,15 +151,19 @@ public class SpoofSignatureVerificationPatch {
|
||||
// then this will incorrectly replace the setting.
|
||||
// But, if the video uses multiple subtitles in different screen locations, then detect the non-default values
|
||||
// and do not replace any window settings for the video (regardless if they match a shorts default).
|
||||
if (signatureSpoofing && !nonDefaultSubtitlesEncountered && !PlayerType.getCurrent().isNoneOrHidden()) {
|
||||
if (signatureSpoofing && !PlayerType.getCurrent().isNoneOrHidden()
|
||||
&& numberOfNonDefaultSettingsObserved < NUMBER_OF_NON_DEFAULT_SUBTITLES_BEFORE_ENABLING_PASSTHRU) {
|
||||
for (SubtitleWindowReplacementSettings setting : SubtitleWindowReplacementSettings.values()) {
|
||||
if (setting.match(ap, ah, av, vs, sd)) {
|
||||
return setting.replacementSetting();
|
||||
}
|
||||
}
|
||||
// Settings appear to be custom subtitles.
|
||||
nonDefaultSubtitlesEncountered = true;
|
||||
LogHelper.printDebug(() -> "Non default subtitles found. Using existing settings without replacement.");
|
||||
|
||||
numberOfNonDefaultSettingsObserved++;
|
||||
LogHelper.printDebug(() ->
|
||||
numberOfNonDefaultSettingsObserved < NUMBER_OF_NON_DEFAULT_SUBTITLES_BEFORE_ENABLING_PASSTHRU
|
||||
? "Non default subtitle found."
|
||||
: "Multiple non default subtitles found. Allowing all subtitles for this video to pass thru unchanged.");
|
||||
}
|
||||
|
||||
return new int[]{ap, ah, av};
|
||||
@@ -160,7 +178,7 @@ public class SpoofSignatureVerificationPatch {
|
||||
return;
|
||||
}
|
||||
currentVideoId = videoId;
|
||||
nonDefaultSubtitlesEncountered = false;
|
||||
numberOfNonDefaultSettingsObserved = 0;
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "setCurrentVideoId failure", ex);
|
||||
}
|
||||
|
||||
@@ -19,13 +19,12 @@ import app.revanced.integrations.utils.StringRef;
|
||||
|
||||
public enum SettingsEnum {
|
||||
//Download Settings
|
||||
// TODO: DOWNLOAD_PATH("revanced_download_path", STRING, Environment.getExternalStorageDirectory().getPath() + "/Download"),
|
||||
DOWNLOADS_BUTTON_SHOWN("revanced_downloads_enabled", BOOLEAN, TRUE, true),
|
||||
DOWNLOADS_BUTTON_SHOWN("revanced_downloads_enabled", BOOLEAN, TRUE),
|
||||
DOWNLOADS_PACKAGE_NAME("revanced_downloads_package_name", STRING, "org.schabi.newpipe" /* NewPipe */, parents(DOWNLOADS_BUTTON_SHOWN)),
|
||||
|
||||
// Copy video URL settings
|
||||
COPY_VIDEO_URL_BUTTON_SHOWN("revanced_copy_video_url_enabled", BOOLEAN, TRUE, true),
|
||||
COPY_VIDEO_URL_TIMESTAMP_BUTTON_SHOWN("revanced_copy_video_url_timestamp_enabled", BOOLEAN, TRUE, true),
|
||||
COPY_VIDEO_URL_BUTTON_SHOWN("revanced_copy_video_url_enabled", BOOLEAN, TRUE),
|
||||
COPY_VIDEO_URL_TIMESTAMP_BUTTON_SHOWN("revanced_copy_video_url_timestamp_enabled", BOOLEAN, TRUE),
|
||||
|
||||
// Video settings
|
||||
OLD_STYLE_VIDEO_QUALITY_PLAYER_SETTINGS("revanced_use_old_style_quality_settings", BOOLEAN, TRUE),
|
||||
@@ -103,6 +102,7 @@ public enum SettingsEnum {
|
||||
HIDE_WATCH_IN_VR("revanced_hide_watch_in_vr", BOOLEAN, FALSE, true),
|
||||
PLAYER_POPUP_PANELS("revanced_player_popup_panels_enabled", BOOLEAN, FALSE),
|
||||
SPOOF_APP_VERSION("revanced_spoof_app_version", BOOLEAN, FALSE, true, "revanced_spoof_app_version_user_dialog_message"),
|
||||
SPOOF_APP_VERSION_TARGET("revanced_spoof_app_version_target", STRING, "17.30.35", true, parents(SPOOF_APP_VERSION)),
|
||||
USE_TABLET_MINIPLAYER("revanced_tablet_miniplayer", BOOLEAN, FALSE, true),
|
||||
WIDE_SEARCHBAR("revanced_wide_searchbar", BOOLEAN, FALSE, true),
|
||||
|
||||
|
||||
@@ -1,66 +1,64 @@
|
||||
package app.revanced.integrations.videoplayer;
|
||||
|
||||
import android.support.constraint.ConstraintLayout;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class BottomControlButton {
|
||||
WeakReference<ImageView> button = new WeakReference<>(null);
|
||||
ConstraintLayout constraintLayout;
|
||||
Boolean isButtonEnabled;
|
||||
Boolean isShowing;
|
||||
private static final Animation fadeIn = ReVancedUtils.getResourceAnimation("fade_in");
|
||||
private static final Animation fadeOut = ReVancedUtils.getResourceAnimation("fade_out");
|
||||
private final WeakReference<ImageView> buttonRef;
|
||||
private final SettingsEnum setting;
|
||||
protected boolean isVisible;
|
||||
|
||||
private Animation fadeIn;
|
||||
private Animation fadeOut;
|
||||
|
||||
public BottomControlButton(Object obj, String viewId, Boolean isEnabled, View.OnClickListener onClickListener) {
|
||||
try {
|
||||
LogHelper.printDebug(() -> "Initializing button with id: " + viewId);
|
||||
constraintLayout = (ConstraintLayout) obj;
|
||||
isButtonEnabled = isEnabled;
|
||||
|
||||
ImageView imageView = constraintLayout.findViewById(ReVancedUtils.getResourceIdentifier(viewId, "id"));
|
||||
if (imageView == null) {
|
||||
LogHelper.printException(() -> "Couldn't find ImageView with id: " + viewId);
|
||||
return;
|
||||
}
|
||||
imageView.setOnClickListener(onClickListener);
|
||||
button = new WeakReference<>(imageView);
|
||||
|
||||
fadeIn = ReVancedUtils.getResourceAnimation("fade_in");
|
||||
fadeOut = ReVancedUtils.getResourceAnimation("fade_out");
|
||||
fadeIn.setDuration(ReVancedUtils.getResourceInteger("fade_duration_fast"));
|
||||
fadeOut.setDuration(ReVancedUtils.getResourceInteger("fade_duration_scheduled"));
|
||||
|
||||
isShowing = true;
|
||||
setVisibility(false);
|
||||
} catch (Exception e) {
|
||||
LogHelper.printException(() -> "Failed to initialize button with id: " + viewId, e);
|
||||
}
|
||||
static {
|
||||
// TODO: check if these durations are correct.
|
||||
fadeIn.setDuration(ReVancedUtils.getResourceInteger("fade_duration_fast"));
|
||||
fadeOut.setDuration(ReVancedUtils.getResourceInteger("fade_duration_scheduled"));
|
||||
}
|
||||
|
||||
public void setVisibility(boolean showing) {
|
||||
if (isShowing == showing) return;
|
||||
public BottomControlButton(@NonNull ViewGroup bottomControlsViewGroup, @NonNull String imageViewButtonId,
|
||||
@NonNull SettingsEnum booleanSetting, @NonNull View.OnClickListener onClickListener) {
|
||||
LogHelper.printDebug(() -> "Initializing button: " + imageViewButtonId);
|
||||
|
||||
isShowing = showing;
|
||||
ImageView imageView = button.get();
|
||||
|
||||
if (constraintLayout == null || imageView == null)
|
||||
return;
|
||||
|
||||
if (showing && isButtonEnabled) {
|
||||
LogHelper.printDebug(() -> "Fading in");
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
imageView.startAnimation(fadeIn);
|
||||
if (booleanSetting.returnType != SettingsEnum.ReturnType.BOOLEAN) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
else if (imageView.getVisibility() == View.VISIBLE) {
|
||||
LogHelper.printDebug(() -> "Fading out");
|
||||
|
||||
setting = booleanSetting;
|
||||
|
||||
// Create the button.
|
||||
ImageView imageView = Objects.requireNonNull(bottomControlsViewGroup.findViewById(
|
||||
ReVancedUtils.getResourceIdentifier(imageViewButtonId, "id")
|
||||
));
|
||||
imageView.setOnClickListener(onClickListener);
|
||||
imageView.setVisibility(View.GONE);
|
||||
|
||||
buttonRef = new WeakReference<>(imageView);
|
||||
}
|
||||
|
||||
public void setVisibility(boolean visible) {
|
||||
if (isVisible == visible) return;
|
||||
isVisible = visible;
|
||||
|
||||
ImageView imageView = buttonRef.get();
|
||||
if (imageView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
imageView.clearAnimation();
|
||||
if (visible && setting.getBoolean()) {
|
||||
imageView.startAnimation(fadeIn);
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
} else if (imageView.getVisibility() == View.VISIBLE) {
|
||||
imageView.startAnimation(fadeOut);
|
||||
imageView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,40 @@
|
||||
package app.revanced.integrations.videoplayer;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.integrations.patches.CopyVideoUrlPatch;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
public class CopyVideoUrlButton extends BottomControlButton {
|
||||
public static CopyVideoUrlButton instance;
|
||||
@Nullable
|
||||
private static CopyVideoUrlButton instance;
|
||||
|
||||
public CopyVideoUrlButton(Object obj) {
|
||||
public CopyVideoUrlButton(ViewGroup viewGroup) {
|
||||
super(
|
||||
obj,
|
||||
viewGroup,
|
||||
"copy_video_url_button",
|
||||
SettingsEnum.COPY_VIDEO_URL_BUTTON_SHOWN.getBoolean(),
|
||||
SettingsEnum.COPY_VIDEO_URL_BUTTON_SHOWN,
|
||||
view -> CopyVideoUrlPatch.copyUrl(false)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void initializeButton(Object obj) {
|
||||
instance = new CopyVideoUrlButton(obj);
|
||||
try {
|
||||
instance = new CopyVideoUrlButton((ViewGroup) obj);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "initializeButton failure", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void changeVisibility(boolean showing) {
|
||||
if (instance != null) instance.setVisibility(showing);
|
||||
}
|
||||
|
||||
@@ -1,24 +1,40 @@
|
||||
package app.revanced.integrations.videoplayer;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.integrations.patches.CopyVideoUrlPatch;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
public class CopyVideoUrlTimestampButton extends BottomControlButton {
|
||||
public static CopyVideoUrlTimestampButton instance;
|
||||
@Nullable
|
||||
private static CopyVideoUrlTimestampButton instance;
|
||||
|
||||
public CopyVideoUrlTimestampButton(Object obj) {
|
||||
public CopyVideoUrlTimestampButton(ViewGroup bottomControlsViewGroup) {
|
||||
super(
|
||||
obj,
|
||||
bottomControlsViewGroup,
|
||||
"copy_video_url_timestamp_button",
|
||||
SettingsEnum.COPY_VIDEO_URL_TIMESTAMP_BUTTON_SHOWN.getBoolean(),
|
||||
SettingsEnum.COPY_VIDEO_URL_TIMESTAMP_BUTTON_SHOWN,
|
||||
view -> CopyVideoUrlPatch.copyUrl(true)
|
||||
);
|
||||
}
|
||||
|
||||
public static void initializeButton(Object obj) {
|
||||
instance = new CopyVideoUrlTimestampButton(obj);
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void initializeButton(Object bottomControlsViewGroup) {
|
||||
try {
|
||||
instance = new CopyVideoUrlTimestampButton((ViewGroup) bottomControlsViewGroup);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "initializeButton failure", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void changeVisibility(boolean showing) {
|
||||
if (instance != null) instance.setVisibility(showing);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ package app.revanced.integrations.videoplayer;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.integrations.patches.VideoInformation;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
@@ -11,21 +14,32 @@ import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import app.revanced.integrations.utils.StringRef;
|
||||
|
||||
public class DownloadButton extends BottomControlButton {
|
||||
public static DownloadButton instance;
|
||||
@Nullable
|
||||
private static DownloadButton instance;
|
||||
|
||||
public DownloadButton(Object obj) {
|
||||
public DownloadButton(ViewGroup viewGroup) {
|
||||
super(
|
||||
obj,
|
||||
viewGroup,
|
||||
"download_button",
|
||||
SettingsEnum.DOWNLOADS_BUTTON_SHOWN.getBoolean(),
|
||||
SettingsEnum.DOWNLOADS_BUTTON_SHOWN,
|
||||
DownloadButton::onDownloadClick
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void initializeButton(Object obj) {
|
||||
instance = new DownloadButton(obj);
|
||||
try {
|
||||
instance = new DownloadButton((ViewGroup) obj);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "initializeButton failure", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void changeVisibility(boolean showing) {
|
||||
if (instance != null) instance.setVisibility(showing);
|
||||
}
|
||||
@@ -38,7 +52,6 @@ public class DownloadButton extends BottomControlButton {
|
||||
|
||||
boolean packageEnabled = false;
|
||||
try {
|
||||
assert context != null;
|
||||
packageEnabled = context.getPackageManager().getApplicationInfo(downloaderPackageName, 0).enabled;
|
||||
} catch (PackageManager.NameNotFoundException error) {
|
||||
LogHelper.printDebug(() -> "Downloader could not be found: " + error);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
org.gradle.jvmargs = -Xmx2048m
|
||||
android.useAndroidX = true
|
||||
version = 0.105.0-dev.2
|
||||
version = 0.106.0-dev.1
|
||||
|
||||
Reference in New Issue
Block a user