mirror of
				https://github.com/SoPat712/YTLitePlus.git
				synced 2025-11-03 12:59:26 -05:00 
			
		
		
		
	added files via upload
This commit is contained in:
		
							
								
								
									
										357
									
								
								Tweaks/YouPiP/LegacyPiPCompat.x
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										357
									
								
								Tweaks/YouPiP/LegacyPiPCompat.x
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,357 @@
 | 
			
		||||
#import "Header.h"
 | 
			
		||||
#import <version.h>
 | 
			
		||||
#import "../YouTubeHeader/MLAVPlayer.h"
 | 
			
		||||
#import "../YouTubeHeader/MLHAMQueuePlayer.h"
 | 
			
		||||
#import "../YouTubeHeader/MLPIPController.h"
 | 
			
		||||
#import "../YouTubeHeader/MLPlayerPool.h"
 | 
			
		||||
#import "../YouTubeHeader/MLPlayerPoolImpl.h"
 | 
			
		||||
#import "../YouTubeHeader/MLVideoDecoderFactory.h"
 | 
			
		||||
#import "../YouTubeHeader/MLDefaultPlayerViewFactory.h"
 | 
			
		||||
#import "../YouTubeHeader/YTHotConfig.h"
 | 
			
		||||
#import "../YouTubeHeader/YTPlayerPIPController.h"
 | 
			
		||||
#import "../YouTubeHeader/YTBackgroundabilityPolicy.h"
 | 
			
		||||
#import "../YouTubeHeader/YTPlayerViewControllerConfig.h"
 | 
			
		||||
#import "../YouTubeHeader/YTSystemNotifications.h"
 | 
			
		||||
#import "../YouTubeHeader/YTAutonavEndscreenController.h"
 | 
			
		||||
 | 
			
		||||
extern BOOL TweakEnabled();
 | 
			
		||||
extern BOOL isPictureInPictureActive(MLPIPController *);
 | 
			
		||||
 | 
			
		||||
BOOL hasSampleBufferPiP;
 | 
			
		||||
BOOL isLegacyVersion;
 | 
			
		||||
 | 
			
		||||
BOOL LegacyPiP() {
 | 
			
		||||
    return isLegacyVersion ? YES : [[NSUserDefaults standardUserDefaults] boolForKey:CompatibilityModeKey];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void forceRenderViewTypeBase(YTIHamplayerConfig *hamplayerConfig) {
 | 
			
		||||
    if (!LegacyPiP()) return;
 | 
			
		||||
    hamplayerConfig.renderViewType = 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void forceRenderViewTypeHot(YTIHamplayerHotConfig *hamplayerHotConfig) {
 | 
			
		||||
    if (!LegacyPiP()) return;
 | 
			
		||||
    hamplayerHotConfig.renderViewType = 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void forceRenderViewType(YTHotConfig *hotConfig) {
 | 
			
		||||
    YTIHamplayerHotConfig *hamplayerHotConfig = [hotConfig hamplayerHotConfig];
 | 
			
		||||
    forceRenderViewTypeHot(hamplayerHotConfig);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MLPIPController *(*InjectMLPIPController)(void);
 | 
			
		||||
static YTSystemNotifications *(*InjectYTSystemNotifications)(void);
 | 
			
		||||
static YTBackgroundabilityPolicy *(*InjectYTBackgroundabilityPolicy)(void);
 | 
			
		||||
static YTPlayerViewControllerConfig *(*InjectYTPlayerViewControllerConfig)(void);
 | 
			
		||||
YTHotConfig *(*InjectYTHotConfig)(void);
 | 
			
		||||
 | 
			
		||||
%group WithInjection
 | 
			
		||||
 | 
			
		||||
YTPlayerPIPController *initPlayerPiPControllerIfNeeded(YTPlayerPIPController *controller, id delegate, id parentResponder) {
 | 
			
		||||
    if (controller) return controller;
 | 
			
		||||
    controller = [[%c(YTPlayerPIPController) alloc] init];
 | 
			
		||||
    MLPIPController *pip = InjectMLPIPController();
 | 
			
		||||
    YTSystemNotifications *systemNotifications = InjectYTSystemNotifications();
 | 
			
		||||
    YTBackgroundabilityPolicy *bgPolicy = InjectYTBackgroundabilityPolicy();
 | 
			
		||||
    YTPlayerViewControllerConfig *playerConfig = InjectYTPlayerViewControllerConfig();
 | 
			
		||||
    [controller setValue:pip forKey:@"_pipController"];
 | 
			
		||||
    [controller setValue:bgPolicy forKey:@"_backgroundabilityPolicy"];
 | 
			
		||||
    [controller setValue:playerConfig forKey:@"_config"];
 | 
			
		||||
    @try {
 | 
			
		||||
        YTHotConfig *config = InjectYTHotConfig();
 | 
			
		||||
        [controller setValue:config forKey:@"_hotConfig"];
 | 
			
		||||
    } @catch (id ex) {}
 | 
			
		||||
    if (parentResponder) {
 | 
			
		||||
        @try {
 | 
			
		||||
            [controller setValue:parentResponder forKey:@"_parentResponder"];
 | 
			
		||||
        } @catch (id ex) {}
 | 
			
		||||
    }
 | 
			
		||||
    [controller setValue:delegate forKey:@"_delegate"];
 | 
			
		||||
    [bgPolicy addBackgroundabilityPolicyObserver:controller];
 | 
			
		||||
    [pip addPIPControllerObserver:controller];
 | 
			
		||||
    [systemNotifications addSystemNotificationsObserver:controller];
 | 
			
		||||
    return controller;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%hook YTPlayerPIPController
 | 
			
		||||
 | 
			
		||||
- (instancetype)initWithDelegate:(id)delegate {
 | 
			
		||||
    return initPlayerPiPControllerIfNeeded(%orig, delegate, nil);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (instancetype)initWithDelegate:(id)delegate parentResponder:(id)parentResponder {
 | 
			
		||||
    return initPlayerPiPControllerIfNeeded(%orig, delegate, parentResponder);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%hook YTAutonavEndscreenController
 | 
			
		||||
 | 
			
		||||
- (instancetype)initWithParentResponder:(id)arg1 config:(id)arg2 imageService:(id)arg3 lastActionController:(id)arg4 reachabilityController:(id)arg5 endscreenDelegate:(id)arg6 {
 | 
			
		||||
    self = %orig;
 | 
			
		||||
    if ([self valueForKey:@"_pipController"] == nil)
 | 
			
		||||
        [self setValue:InjectMLPIPController() forKey:@"_pipController"];
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%hook MLHAMQueuePlayer
 | 
			
		||||
 | 
			
		||||
- (instancetype)initWithStickySettings:(MLPlayerStickySettings *)stickySettings playerViewProvider:(MLPlayerPoolImpl *)playerViewProvider playerConfiguration:(void *)playerConfiguration {
 | 
			
		||||
    self = %orig;
 | 
			
		||||
    if ([self valueForKey:@"_pipController"] == nil)
 | 
			
		||||
        [self setValue:InjectMLPIPController() forKey:@"_pipController"];
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%hook MLAVPlayer
 | 
			
		||||
 | 
			
		||||
- (bool)isPictureInPictureActive {
 | 
			
		||||
    return isPictureInPictureActive(InjectMLPIPController());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%hook MLPlayerPoolImpl
 | 
			
		||||
 | 
			
		||||
- (instancetype)init {
 | 
			
		||||
    self = %orig;
 | 
			
		||||
    if (self)
 | 
			
		||||
        [self setValue:InjectMLPIPController() forKey:@"_pipController"];
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%hook MLAVPIPPlayerLayerView
 | 
			
		||||
 | 
			
		||||
- (id)initWithPlaceholderPlayerItem:(AVPlayerItem *)playerItem {
 | 
			
		||||
    self = %orig;
 | 
			
		||||
    if ([self valueForKey:@"_pipController"] == nil)
 | 
			
		||||
        [self setValue:InjectMLPIPController() forKey:@"_pipController"];
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%group Legacy
 | 
			
		||||
 | 
			
		||||
static MLAVPlayer *makeAVPlayer(id self, MLVideo *video, MLInnerTubePlayerConfig *playerConfig, MLPlayerStickySettings *stickySettings, BOOL gimmeAlloc) {
 | 
			
		||||
    BOOL externalPlaybackActive = [(MLAVPlayer *)[self valueForKey:@"_activePlayer"] externalPlaybackActive];
 | 
			
		||||
    MLAVPlayer *player = gimmeAlloc ? [((MLPlayerPool *)self).gimme allocOf:%c(MLAVPlayer)] : [%c(MLAVPlayer) alloc];
 | 
			
		||||
    player = [player initWithVideo:video playerConfig:playerConfig stickySettings:stickySettings externalPlaybackActive:externalPlaybackActive];
 | 
			
		||||
    if (stickySettings)
 | 
			
		||||
        player.rate = stickySettings.rate;
 | 
			
		||||
    return player;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%hook MLPIPController
 | 
			
		||||
 | 
			
		||||
- (void)activatePiPController {
 | 
			
		||||
    if (!isPictureInPictureActive(self)) {
 | 
			
		||||
        AVPictureInPictureController *pip = [self valueForKey:@"_pictureInPictureController"];
 | 
			
		||||
        if (!pip) {
 | 
			
		||||
            MLAVPIPPlayerLayerView *avpip = [self valueForKey:@"_AVPlayerView"];
 | 
			
		||||
            if (avpip) {
 | 
			
		||||
                AVPlayerLayer *playerLayer = [avpip playerLayer];
 | 
			
		||||
                pip = [[AVPictureInPictureController alloc] initWithPlayerLayer:playerLayer];
 | 
			
		||||
                [self setValue:pip forKey:@"_pictureInPictureController"];
 | 
			
		||||
                pip.delegate = self;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)deactivatePiPController {
 | 
			
		||||
    AVPictureInPictureController *pip = [self valueForKey:@"_pictureInPictureController"];
 | 
			
		||||
    [pip stopPictureInPicture];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%hook MLPlayerPoolImpl
 | 
			
		||||
 | 
			
		||||
- (id)acquirePlayerForVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig stickySettings:(MLPlayerStickySettings *)stickySettings {
 | 
			
		||||
    return makeAVPlayer(self, video, playerConfig, stickySettings, NO);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)acquirePlayerForVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig stickySettings:(MLPlayerStickySettings *)stickySettings latencyLogger:(id)latencyLogger {
 | 
			
		||||
    return makeAVPlayer(self, video, playerConfig, stickySettings, NO);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)acquirePlayerForVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig stickySettings:(MLPlayerStickySettings *)stickySettings latencyLogger:(id)latencyLogger reloadContext:(id)reloadContext {
 | 
			
		||||
    return makeAVPlayer(self, video, playerConfig, stickySettings, NO);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (MLAVPlayerLayerView *)playerViewForVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig {
 | 
			
		||||
    MLDefaultPlayerViewFactory *factory = [self valueForKey:@"_playerViewFactory"];
 | 
			
		||||
    return [factory AVPlayerViewForVideo:video playerConfig:playerConfig];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)canQueuePlayerPlayVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig {
 | 
			
		||||
    return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%hook MLPlayerPool
 | 
			
		||||
 | 
			
		||||
- (id)acquirePlayerForVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig stickySettings:(MLPlayerStickySettings *)stickySettings {
 | 
			
		||||
    return makeAVPlayer(self, video, playerConfig, stickySettings, YES);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)acquirePlayerForVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig stickySettings:(MLPlayerStickySettings *)stickySettings latencyLogger:(id)latencyLogger {
 | 
			
		||||
    return makeAVPlayer(self, video, playerConfig, stickySettings, YES);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (MLAVPlayerLayerView *)playerViewForVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig {
 | 
			
		||||
    MLDefaultPlayerViewFactory *factory = [self valueForKey:@"_playerViewFactory"];
 | 
			
		||||
    return [factory AVPlayerViewForVideo:video playerConfig:playerConfig];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)canUsePlayerView:(id)playerView forVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig {
 | 
			
		||||
    forceRenderViewTypeBase([playerConfig hamplayerConfig]);
 | 
			
		||||
    return %orig;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)canQueuePlayerPlayVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig {
 | 
			
		||||
    return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%hook MLDefaultPlayerViewFactory
 | 
			
		||||
 | 
			
		||||
- (id)hamPlayerViewForVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig {
 | 
			
		||||
    forceRenderViewType([self valueForKey:@"_hotConfig"]);
 | 
			
		||||
    forceRenderViewTypeBase([playerConfig hamplayerConfig]);
 | 
			
		||||
    return %orig;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)canUsePlayerView:(id)playerView forVideo:(MLVideo *)video playerConfig:(MLInnerTubePlayerConfig *)playerConfig {
 | 
			
		||||
    forceRenderViewTypeBase([playerConfig hamplayerConfig]);
 | 
			
		||||
    return %orig;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%hook MLVideoDecoderFactory
 | 
			
		||||
 | 
			
		||||
- (void)prepareDecoderForFormatDescription:(id)formatDescription delegateQueue:(id)delegateQueue {
 | 
			
		||||
    forceRenderViewTypeHot([self valueForKey:@"_hotConfig"]);
 | 
			
		||||
    %orig;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%group Compat
 | 
			
		||||
 | 
			
		||||
%hook AVPictureInPictureController
 | 
			
		||||
 | 
			
		||||
%new(v@:)
 | 
			
		||||
- (void)invalidatePlaybackState {}
 | 
			
		||||
 | 
			
		||||
%new(v@:)
 | 
			
		||||
- (void)sampleBufferDisplayLayerDidDisappear {}
 | 
			
		||||
 | 
			
		||||
%new(v@:)
 | 
			
		||||
- (void)sampleBufferDisplayLayerDidAppear {}
 | 
			
		||||
 | 
			
		||||
%new
 | 
			
		||||
- (void)sampleBufferDisplayLayerRenderSizeDidChangeToSize:(CGSize)size {}
 | 
			
		||||
 | 
			
		||||
%new
 | 
			
		||||
- (void)setRequiresLinearPlayback:(BOOL)linear {}
 | 
			
		||||
 | 
			
		||||
%new(v@:)
 | 
			
		||||
- (void)reloadPrerollAttributes {}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
#pragma clang diagnostic push
 | 
			
		||||
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
 | 
			
		||||
 | 
			
		||||
%group AVKit_iOS14_2_Up
 | 
			
		||||
 | 
			
		||||
%hook AVPictureInPictureControllerContentSource
 | 
			
		||||
 | 
			
		||||
%property (assign) bool hasInitialRenderSize;
 | 
			
		||||
 | 
			
		||||
- (id)initWithSampleBufferDisplayLayer:(AVSampleBufferDisplayLayer *)sampleBufferDisplayLayer initialRenderSize:(CGSize)initialRenderSize playbackDelegate:(id)playbackDelegate {
 | 
			
		||||
    self = %orig;
 | 
			
		||||
    if (self)
 | 
			
		||||
        self.hasInitialRenderSize = true;
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%group AVKit_preiOS14_2
 | 
			
		||||
 | 
			
		||||
%hook AVPictureInPictureControllerContentSource
 | 
			
		||||
 | 
			
		||||
%property (assign) bool hasInitialRenderSize;
 | 
			
		||||
 | 
			
		||||
%new
 | 
			
		||||
- (instancetype)initWithSampleBufferDisplayLayer:(AVSampleBufferDisplayLayer *)sampleBufferDisplayLayer initialRenderSize:(CGSize)initialRenderSize playbackDelegate:(id <AVPictureInPictureSampleBufferPlaybackDelegate>)playbackDelegate {
 | 
			
		||||
    return [self initWithSampleBufferDisplayLayer:sampleBufferDisplayLayer playbackDelegate:playbackDelegate];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%hook AVPictureInPictureController
 | 
			
		||||
 | 
			
		||||
%new
 | 
			
		||||
- (void)setCanStartPictureInPictureAutomaticallyFromInline:(BOOL)canStartFromInline {}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
#pragma clang diagnostic pop
 | 
			
		||||
 | 
			
		||||
%ctor {
 | 
			
		||||
    if (!TweakEnabled()) return;
 | 
			
		||||
    NSString *frameworkPath = [NSString stringWithFormat:@"%@/Frameworks/Module_Framework.framework/Module_Framework", NSBundle.mainBundle.bundlePath];
 | 
			
		||||
    NSBundle *bundle = [NSBundle bundleWithPath:frameworkPath];
 | 
			
		||||
    if (!bundle.loaded) [bundle load];
 | 
			
		||||
    MSImageRef ref = MSGetImageByName([frameworkPath UTF8String]);
 | 
			
		||||
    InjectMLPIPController = MSFindSymbol(ref, "_InjectMLPIPController");
 | 
			
		||||
    if (InjectMLPIPController) {
 | 
			
		||||
        InjectYTSystemNotifications = MSFindSymbol(ref, "_InjectYTSystemNotifications");
 | 
			
		||||
        InjectYTBackgroundabilityPolicy = MSFindSymbol(ref, "_InjectYTBackgroundabilityPolicy");
 | 
			
		||||
        InjectYTPlayerViewControllerConfig = MSFindSymbol(ref, "_InjectYTPlayerViewControllerConfig");
 | 
			
		||||
        InjectYTHotConfig = MSFindSymbol(ref, "_InjectYTHotConfig");
 | 
			
		||||
        %init(WithInjection);
 | 
			
		||||
    } else {
 | 
			
		||||
        NSString *currentVersion = [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey];
 | 
			
		||||
        hasSampleBufferPiP = isLegacyVersion = [currentVersion compare:@"15.33.4" options:NSNumericSearch] == NSOrderedDescending;
 | 
			
		||||
        hasSampleBufferPiP &= IS_IOS_OR_NEWER(iOS_13_0);
 | 
			
		||||
    }
 | 
			
		||||
    if (!IS_IOS_OR_NEWER(iOS_14_0)) {
 | 
			
		||||
        %init(Compat);
 | 
			
		||||
        if (!IS_IOS_OR_NEWER(iOS_13_0))
 | 
			
		||||
            isLegacyVersion = YES;
 | 
			
		||||
    }
 | 
			
		||||
    if (LegacyPiP()) {
 | 
			
		||||
        %init(Legacy);
 | 
			
		||||
    }
 | 
			
		||||
    if (!IS_IOS_OR_NEWER(iOS_14_0) || IS_IOS_OR_NEWER(iOS_15_0))
 | 
			
		||||
        return;
 | 
			
		||||
    if (IS_IOS_OR_NEWER(iOS_14_2)) {
 | 
			
		||||
        %init(AVKit_iOS14_2_Up);
 | 
			
		||||
    } else {
 | 
			
		||||
        %init(AVKit_preiOS14_2);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user