From 3e8437ae559487362fae3525beb79c534c213a51 Mon Sep 17 00:00:00 2001
From: 单军华
Date: Thu, 12 Jul 2018 13:44:34 +0800
Subject: [PATCH] bug修复和功能优化

---
 screendisplay/Pods/ZFPlayer/ZFPlayer/Classes/Core/ZFPlayerController.m |  875 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 875 insertions(+), 0 deletions(-)

diff --git a/screendisplay/Pods/ZFPlayer/ZFPlayer/Classes/Core/ZFPlayerController.m b/screendisplay/Pods/ZFPlayer/ZFPlayer/Classes/Core/ZFPlayerController.m
new file mode 100644
index 0000000..ff3be56
--- /dev/null
+++ b/screendisplay/Pods/ZFPlayer/ZFPlayer/Classes/Core/ZFPlayerController.m
@@ -0,0 +1,875 @@
+//
+//  ZFPlayer.m
+//  ZFPlayer
+//
+// Copyright (c) 2016��� ��������� ( http://github.com/renzifeng )
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import "ZFPlayerController.h"
+#import <objc/runtime.h>
+#import <MediaPlayer/MediaPlayer.h>
+#import <AVFoundation/AVFoundation.h>
+#import "ZFPlayerNotification.h"
+#import "UIScrollView+ZFPlayer.h"
+#import "ZFReachabilityManager.h"
+#import "ZFPlayer.h"
+
+@interface ZFPlayerController ()
+
+@property (nonatomic, strong) UIView *containerView;
+@property (nonatomic, strong) ZFPlayerNotification *notification;
+@property (nonatomic, strong) id<ZFPlayerMediaPlayback> currentPlayerManager;
+@property (nonatomic, strong, nullable) UIScrollView *scrollView;
+@property (nonatomic, assign, getter=isPauseByUser) BOOL pauseByUser;
+@property (nonatomic, strong) UISlider *volumeViewSlider;
+@property (nonatomic, assign) NSTimeInterval currentTime;
+@property (nonatomic, assign) NSTimeInterval totalTime;
+@property (nonatomic, assign) NSTimeInterval bufferTime;
+/// The view tag that the player display in scrollView.
+@property (nonatomic, assign) NSInteger containerViewTag;
+
+@end
+
+@implementation ZFPlayerController
+
+- (instancetype)init {
+    self = [super init];
+    if (self) {
+        @weakify(self)
+        [[ZFReachabilityManager sharedManager] startMonitoring];
+        [[ZFReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(ZFReachabilityStatus status) {
+            @strongify(self)
+            if ([self.controlView respondsToSelector:@selector(videoPlayer:reachabilityChanged:)]) {
+                [self.controlView videoPlayer:self reachabilityChanged:status];
+            }
+        }];
+        [self configureVolume];
+    }
+    return self;
+}
+
+/// Get system volume
+- (void)configureVolume {
+    MPVolumeView *volumeView = [[MPVolumeView alloc] init];
+    self.volumeViewSlider = nil;
+    for (UIView *view in [volumeView subviews]){
+        if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
+            self.volumeViewSlider = (UISlider *)view;
+            break;
+        }
+    }
+    // Apps using this category don't mute when the phone's mute button is turned on, but play sound when the phone is silent
+    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
+    [[AVAudioSession sharedInstance] setActive:YES error:nil];
+}
+
+- (void)dealloc {
+    [self.currentPlayerManager stop];
+}
+
++ (instancetype)playerWithPlayerManager:(id<ZFPlayerMediaPlayback>)playerManager containerView:(nonnull UIView *)containerView {
+    ZFPlayerController *player = [[self alloc] init];
+    player.currentPlayerManager = playerManager;
+    player.containerView = containerView;
+    return player;
+}
+
++ (instancetype)playerWithScrollView:(UIScrollView *)scrollView playerManager:(id<ZFPlayerMediaPlayback>)playerManager containerViewTag:(NSInteger)containerViewTag {
+    ZFPlayerController *player = [[self alloc] init];
+    player.scrollView = scrollView;
+    player.currentPlayerManager = playerManager;
+    player.containerViewTag = containerViewTag;
+    return player;
+}
+
+- (instancetype)initWithPlayerManager:(id<ZFPlayerMediaPlayback>)playerManager containerView:(nonnull UIView *)containerView {
+    ZFPlayerController *player = [self init];
+    player.currentPlayerManager = playerManager;
+    player.containerView = containerView;
+    return player;
+}
+
+- (instancetype)initWithScrollView:(UIScrollView *)scrollView playerManager:(id<ZFPlayerMediaPlayback>)playerManager containerViewTag:(NSInteger)containerViewTag {
+    ZFPlayerController *player = [self init];
+    player.scrollView = scrollView;
+    player.currentPlayerManager = playerManager;
+    player.containerViewTag = containerViewTag;
+    return player;
+}
+
+- (void)playerManagerCallbcak {
+    @weakify(self)
+    self.currentPlayerManager.playerPlayTimeChanged = ^(id<ZFPlayerMediaPlayback>  _Nonnull asset, NSTimeInterval currentTime, NSTimeInterval duration) {
+        @strongify(self)
+        self.currentTime = currentTime;
+        self.totalTime = duration;
+        if ([self.controlView respondsToSelector:@selector(videoPlayer:currentTime:totalTime:)]) {
+            [self.controlView videoPlayer:self currentTime:currentTime totalTime:duration];
+        }
+    };
+    
+    self.currentPlayerManager.playerBufferTimeChanged = ^(id<ZFPlayerMediaPlayback>  _Nonnull asset, NSTimeInterval bufferTime) {
+        @strongify(self)
+        self.bufferTime = bufferTime;
+        if ([self.controlView respondsToSelector:@selector(videoPlayer:bufferTime:)]) {
+            [self.controlView videoPlayer:self bufferTime:bufferTime];
+        }
+    };
+    
+    self.currentPlayerManager.playerPrepareToPlay = ^(id<ZFPlayerMediaPlayback>  _Nonnull asset, NSURL * _Nonnull assetURL) {
+        @strongify(self)
+        self.currentPlayerManager.view.hidden = NO;
+        if ([self.controlView respondsToSelector:@selector(videoPlayer:prepareToPlay:)]) {
+            [self.controlView videoPlayer:self prepareToPlay:assetURL];
+        }
+    };
+    
+    self.currentPlayerManager.playerPlayStatChanged = ^(id  _Nonnull asset, ZFPlayerPlaybackState playState) {
+        @strongify(self)
+        if ([self.controlView respondsToSelector:@selector(videoPlayer:playStateChanged:)]) {
+            [self.controlView videoPlayer:self playStateChanged:playState];
+        }
+    };
+    
+    self.currentPlayerManager.playerLoadStatChanged = ^(id  _Nonnull asset, ZFPlayerLoadState loadState) {
+        @strongify(self)
+        if ([self.controlView respondsToSelector:@selector(videoPlayer:loadStateChanged:)]) {
+            [self.controlView videoPlayer:self loadStateChanged:loadState];
+        }
+    };
+    
+    self.currentPlayerManager.playerDidToEnd = ^(id  _Nonnull asset) {
+        @strongify(self)
+        if (self.playerDidToEnd) self.playerDidToEnd(asset);
+        if ([self.controlView respondsToSelector:@selector(videoPlayerPlayEnd:)]) {
+            [self.controlView videoPlayerPlayEnd:self];
+        }
+    };
+}
+
+- (void)layoutPlayerSubViews {
+    self.containerView.userInteractionEnabled = YES;
+    [self.containerView addSubview:self.currentPlayerManager.view];
+    [self.currentPlayerManager.view addSubview:self.controlView];
+    
+    self.currentPlayerManager.view.frame = self.controlView.bounds;
+    self.currentPlayerManager.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+    self.controlView.frame = self.currentPlayerManager.view.bounds;
+    self.controlView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+}
+
+#pragma mark - getter
+
+- (ZFPlayerNotification *)notification {
+    if (!_notification) {
+        _notification = [[ZFPlayerNotification alloc] init];
+        @weakify(self)
+        _notification.willResignActive = ^(ZFPlayerNotification * _Nonnull registrar) {
+            @strongify(self)
+            if (self.pauseWhenAppResignActive && self.currentPlayerManager.isPlaying) {
+                [self.currentPlayerManager pause];
+                self.pauseByUser = YES;
+            }
+        };
+        _notification.didBecomeActive = ^(ZFPlayerNotification * _Nonnull registrar) {
+            @strongify(self)
+            if (self.isPauseByUser) {
+                [self.currentPlayerManager play];
+                self.pauseByUser = NO;
+            }
+        };
+        _notification.oldDeviceUnavailable = ^(ZFPlayerNotification * _Nonnull registrar) {
+            @strongify(self)
+            if (self.currentPlayerManager.isPlaying) {
+                [self.currentPlayerManager play];
+            }
+        };
+    }
+    return _notification;
+}
+
+#pragma mark - setter
+
+- (void)setCurrentPlayerManager:(id<ZFPlayerMediaPlayback>)currentPlayerManager {
+    if (!currentPlayerManager) return;
+    _currentPlayerManager = currentPlayerManager;
+    _currentPlayerManager.view.hidden = YES;
+    self.gestureControl.disableTypes = self.disableGestureTypes;
+    [self.gestureControl addGestureToView:currentPlayerManager.view];
+    [self playerManagerCallbcak];
+    [self.notification addNotification];
+}
+
+- (void)setContainerView:(UIView *)containerView {
+    if (!containerView) return;
+    _containerView = containerView;
+    containerView.userInteractionEnabled = YES;
+    [containerView addSubview:self.currentPlayerManager.view];
+    self.currentPlayerManager.view.frame = containerView.bounds;
+    self.currentPlayerManager.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+    [self.orientationObserver addDeviceOrientationObserver];
+}
+
+- (void)setControlView:(UIView<ZFPlayerMediaControl> *)controlView {
+    if (!controlView) return;
+    _controlView = controlView;
+    controlView.player = self;
+    [self.currentPlayerManager.view addSubview:controlView];
+    controlView.frame = self.currentPlayerManager.view.bounds;
+    controlView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+}
+
+@end
+
+@implementation ZFPlayerController (ZFPlayerTimeControl)
+
+- (float)progress {
+    if (self.totalTime == 0) return 0;
+    return self.currentTime/self.totalTime;
+}
+
+- (float)bufferProgress {
+    if (self.totalTime == 0) return 0;
+    return self.bufferTime/self.totalTime;
+}
+
+- (void)seekToTime:(NSTimeInterval)time completionHandler:(void (^)(BOOL))completionHandler {
+    [self.currentPlayerManager seekToTime:time completionHandler:completionHandler];
+}
+
+@end
+
+@implementation ZFPlayerController (ZFPlayerPlaybackControl)
+
+- (void)stop {
+    [self.notification removeNotification];
+    [self.orientationObserver removeDeviceOrientationObserver];
+    [self.currentPlayerManager stop];
+    
+    [self.currentPlayerManager.view removeFromSuperview];
+}
+
+- (void)replaceCurrentPlayerManager:(id<ZFPlayerMediaPlayback>)manager {
+    if (self.currentPlayerManager.isPreparedToPlay) {
+        [self.notification removeNotification];
+        [self.orientationObserver removeDeviceOrientationObserver];
+        [self stop];
+    }
+    [self.gestureControl removeGestureToView:self.currentPlayerManager.view];
+    self.currentPlayerManager = manager;
+    [self layoutPlayerSubViews];
+}
+
+- (void)playTheNext {
+    if (self.assetURLs.count > 0) {
+        NSInteger index = self.currentPlayIndex + 1;
+        if (index >= self.assetURLs.count) return;
+        NSURL *assetURL = [self.assetURLs objectAtIndex:index];
+        self.assetURL = assetURL;
+        self.currentPlayIndex = [self.assetURLs indexOfObject:assetURL];
+    }
+}
+
+- (void)playThePrevious {
+    if (self.assetURLs.count > 0) {
+        NSInteger index = self.currentPlayIndex - 1;
+        if (index < 0) return;
+        NSURL *assetURL = [self.assetURLs objectAtIndex:index];
+        self.assetURL = assetURL;
+        self.currentPlayIndex = [self.assetURLs indexOfObject:assetURL];
+    }
+}
+
+- (void)playTheIndex:(NSInteger)index {
+    if (self.assetURLs.count > 0) {
+        if (index >= self.assetURLs.count) return;
+        NSURL *assetURL = [self.assetURLs objectAtIndex:index];
+        self.assetURL = assetURL;
+        self.currentPlayIndex = index;
+    }
+}
+
+#pragma mark - getter
+
+- (NSURL *)assetURL {
+    return objc_getAssociatedObject(self, _cmd);
+}
+
+- (NSArray<NSURL *> *)assetURLs {
+    return objc_getAssociatedObject(self, _cmd);
+}
+
+- (BOOL)isLastAssetURL {
+    if (self.assetURLs.count > 0) {
+        return self.assetURL == self.assetURLs.lastObject;
+    }
+    return NO;
+}
+
+- (BOOL)isFirstAssetURL {
+    if (self.assetURLs.count > 0) {
+        return self.assetURL == self.assetURLs.firstObject;
+    }
+    return NO;
+}
+
+- (BOOL)isWWANAutoPlay {
+    NSNumber *number = objc_getAssociatedObject(self, _cmd);
+    if (number) return number.boolValue;
+    self.WWANAutoPlay = YES;
+    return YES;
+}
+
+- (float)brightness {
+    return [UIScreen mainScreen].brightness;
+}
+
+- (float)volume {
+    CGFloat volume = self.volumeViewSlider.value;
+    if (volume == 0) {
+        volume = [[AVAudioSession sharedInstance] outputVolume];
+    }
+    return volume;
+}
+
+- (BOOL)isMuted {
+    return self.volume == 0;
+}
+
+- (float)lastVolumeValue {
+    return [objc_getAssociatedObject(self, _cmd) floatValue];
+}
+
+- (ZFPlayerPlaybackState)playState {
+    return self.currentPlayerManager.playState;
+}
+
+- (BOOL)isPlaying {
+    return self.currentPlayerManager.isPlaying;
+}
+
+- (BOOL)pauseWhenAppResignActive {
+    NSNumber *number = objc_getAssociatedObject(self, _cmd);
+    if (number) return number.boolValue;
+    self.pauseWhenAppResignActive = YES;
+    return YES;
+}
+
+- (void (^)(id _Nonnull))playerDidToEnd {
+    return objc_getAssociatedObject(self, _cmd);
+}
+
+- (NSInteger)currentPlayIndex {
+    return [objc_getAssociatedObject(self, _cmd) integerValue];
+}
+
+#pragma mark - setter
+
+- (void)setAssetURL:(NSURL *)assetURL {
+    objc_setAssociatedObject(self, @selector(assetURL), assetURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    if (self.currentPlayerManager.isPreparedToPlay) [self.currentPlayerManager stop];
+    if (!self.currentPlayerManager.view.superview) self.containerView = self.containerView;
+    self.currentPlayerManager.assetURL = assetURL;
+}
+
+- (void)setAssetURLs:(NSArray<NSURL *> * _Nullable)assetURLs {
+    objc_setAssociatedObject(self, @selector(assetURLs), assetURLs, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (void)setWWANAutoPlay:(BOOL)WWANAutoPlay {
+    objc_setAssociatedObject(self, @selector(isWWANAutoPlay), @(WWANAutoPlay), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    if (self.scrollView) self.scrollView.zf_WWANAutoPlay = self.isWWANAutoPlay;
+}
+
+- (void)setVolume:(float)volume {
+    volume = MIN(MAX(0, volume), 1);
+    objc_setAssociatedObject(self, @selector(volume), @(volume), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    self.volumeViewSlider.value = volume;
+}
+
+- (void)setMuted:(BOOL)muted {
+    if (muted) {
+        self.lastVolumeValue = self.volumeViewSlider.value;
+        self.volumeViewSlider.value = 0;
+    } else {
+        self.volumeViewSlider.value = self.lastVolumeValue;
+    }
+}
+
+- (void)setLastVolumeValue:(float)lastVolumeValue {
+    objc_setAssociatedObject(self, @selector(lastVolumeValue), @(lastVolumeValue), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (void)setBrightness:(float)brightness {
+    brightness = MIN(MAX(0, brightness), 1);
+    objc_setAssociatedObject(self, @selector(brightness), @(brightness), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    [UIScreen mainScreen].brightness = brightness;
+}
+
+- (void)setPauseWhenAppResignActive:(BOOL)pauseWhenAppResignActive {
+    objc_setAssociatedObject(self, @selector(pauseWhenAppResignActive), @(pauseWhenAppResignActive), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (void)setPlayerDidToEnd:(void (^)(id _Nonnull))playerDidToEnd {
+    objc_setAssociatedObject(self, @selector(playerDidToEnd), playerDidToEnd, OBJC_ASSOCIATION_COPY);
+}
+
+- (void)setCurrentPlayIndex:(NSInteger)currentPlayIndex {
+    objc_setAssociatedObject(self, @selector(currentPlayIndex), @(currentPlayIndex), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+@end
+
+@implementation ZFPlayerController (ZFPlayerOrientationRotation)
+
+- (void)addDeviceOrientationObserver {
+    [self.orientationObserver addDeviceOrientationObserver];
+}
+
+- (void)removeDeviceOrientationObserver {
+    [self.orientationObserver removeDeviceOrientationObserver];
+}
+
+- (void)enterLandscapeFullScreen:(UIInterfaceOrientation)orientation animated:(BOOL)animated {
+    self.orientationObserver.fullScreenMode = ZFFullScreenModeLandscape;
+    [self.orientationObserver enterLandscapeFullScreen:orientation animated:animated];
+}
+
+- (void)enterPortraitFullScreen:(BOOL)fullScreen animated:(BOOL)animated {
+    self.orientationObserver.fullScreenMode = ZFFullScreenModePortrait;
+    [self.orientationObserver enterPortraitFullScreen:fullScreen animated:YES];
+}
+
+- (void)enterFullScreen:(BOOL)fullScreen animated:(BOOL)animated {
+    if (self.orientationObserver.fullScreenMode == ZFFullScreenModePortrait) {
+        [self.orientationObserver enterPortraitFullScreen:fullScreen animated:YES];
+    } else {
+        UIInterfaceOrientation orientation = UIInterfaceOrientationUnknown;
+        orientation = fullScreen? UIInterfaceOrientationLandscapeRight : UIInterfaceOrientationPortrait;
+        [self.orientationObserver enterLandscapeFullScreen:orientation animated:animated];
+    }
+}
+
+#pragma mark - getter
+
+- (ZFOrientationObserver *)orientationObserver {
+    if (!self.currentPlayerManager.view && !self.containerView) return nil;
+    @weakify(self)
+    ZFOrientationObserver *orientationObserver = objc_getAssociatedObject(self, _cmd);
+    if (!orientationObserver) {
+        orientationObserver = [[ZFOrientationObserver alloc] initWithRotateView:self.currentPlayerManager.view containerView:self.containerView];
+        orientationObserver.orientationWillChange = ^(ZFOrientationObserver * _Nonnull observer, BOOL isFullScreen) {
+            @strongify(self)
+            if (self.orientationWillChange) self.orientationWillChange(self, isFullScreen);
+            if ([self.controlView respondsToSelector:@selector(videoPlayer:orientationWillChange:)]) {
+                [self.controlView videoPlayer:self orientationWillChange:observer];
+            }
+            [self.controlView setNeedsLayout];
+            [self.controlView layoutIfNeeded];
+        };
+        orientationObserver.orientationDidChanged = ^(ZFOrientationObserver * _Nonnull observer, BOOL isFullScreen) {
+            @strongify(self)
+            if (self.orientationDidChanged) self.orientationDidChanged(self, isFullScreen);
+            if ([self.controlView respondsToSelector:@selector(videoPlayer:orientationDidChanged:)]) {
+                [self.controlView videoPlayer:self orientationDidChanged:observer];
+            }
+        };
+        objc_setAssociatedObject(self, _cmd, orientationObserver, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    }
+    return orientationObserver;
+}
+
+- (void (^)(ZFPlayerController * _Nonnull, BOOL))orientationWillChange {
+    return objc_getAssociatedObject(self, _cmd);
+}
+
+- (void (^)(ZFPlayerController * _Nonnull, BOOL))orientationDidChanged {
+    return objc_getAssociatedObject(self, _cmd);
+}
+
+- (BOOL)isFullScreen {
+    return self.orientationObserver.isFullScreen;
+}
+
+- (UIInterfaceOrientation)currentOrientation {
+    return self.orientationObserver.currentOrientation;
+}
+
+- (BOOL)isStatusBarHidden {
+    return self.orientationObserver.isStatusBarHidden;
+}
+
+- (BOOL)isLockedScreen {
+    return self.orientationObserver.isLockedScreen;
+}
+
+- (BOOL)shouldAutorotate {
+    return self.orientationObserver.shouldAutorotate;
+}
+
+#pragma mark - setter
+
+- (void)setOrientationWillChange:(void (^)(ZFPlayerController * _Nonnull, BOOL))orientationWillChange {
+    objc_setAssociatedObject(self, @selector(orientationWillChange), orientationWillChange, OBJC_ASSOCIATION_COPY_NONATOMIC);
+}
+
+- (void)setOrientationDidChanged:(void (^)(ZFPlayerController * _Nonnull, BOOL))orientationDidChanged {
+    objc_setAssociatedObject(self, @selector(orientationDidChanged), orientationDidChanged, OBJC_ASSOCIATION_COPY_NONATOMIC);
+}
+
+- (void)setStatusBarHidden:(BOOL)statusBarHidden {
+    objc_setAssociatedObject(self, @selector(isStatusBarHidden), @(statusBarHidden), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    self.orientationObserver.statusBarHidden = statusBarHidden;
+}
+
+- (void)setLockedScreen:(BOOL)lockedScreen {
+    objc_setAssociatedObject(self, @selector(isLockedScreen), @(lockedScreen), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    self.orientationObserver.lockedScreen = lockedScreen;
+    if ([self.controlView respondsToSelector:@selector(lockedVideoPlayer:lockedScreen:)]) {
+        [self.controlView lockedVideoPlayer:self lockedScreen:lockedScreen];
+    }
+}
+
+- (void)setShouldAutorotate:(BOOL)shouldAutorotate {
+    objc_setAssociatedObject(self, @selector(shouldAutorotate), @(shouldAutorotate), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    self.orientationObserver.shouldAutorotate = shouldAutorotate;
+}
+
+@end
+
+
+@implementation ZFPlayerController (ZFPlayerViewGesture)
+
+#pragma mark - getter
+
+- (ZFPlayerGestureControl *)gestureControl {
+    ZFPlayerGestureControl *gestureControl = objc_getAssociatedObject(self, _cmd);
+    if (!gestureControl) {
+        gestureControl = [[ZFPlayerGestureControl alloc] init];
+        @weakify(self)
+        gestureControl.triggerCondition = ^BOOL(ZFPlayerGestureControl * _Nonnull control, ZFPlayerGestureType type, UIGestureRecognizer * _Nonnull gesture, UITouch *touch) {
+            @strongify(self)
+            if ([self.controlView respondsToSelector:@selector(gestureTriggerCondition:gestureType:gestureRecognizer:touch:)]) {
+                return [self.controlView gestureTriggerCondition:control gestureType:type gestureRecognizer:gesture touch:touch];
+            }
+            return YES;
+        };
+        
+        gestureControl.singleTapped = ^(ZFPlayerGestureControl * _Nonnull control) {
+            @strongify(self)
+            if ([self.controlView respondsToSelector:@selector(gestureSingleTapped:)]) {
+                [self.controlView gestureSingleTapped:control];
+            }
+        };
+        
+        gestureControl.doubleTapped = ^(ZFPlayerGestureControl * _Nonnull control) {
+            @strongify(self)
+            if ([self.controlView respondsToSelector:@selector(gestureDoubleTapped:)]) {
+                [self.controlView gestureDoubleTapped:control];
+            }
+        };
+        
+        gestureControl.beganPan = ^(ZFPlayerGestureControl * _Nonnull control, ZFPanDirection direction, ZFPanLocation location) {
+            @strongify(self)
+            if ([self.controlView respondsToSelector:@selector(gestureBeganPan:panDirection:panLocation:)]) {
+                [self.controlView gestureBeganPan:control panDirection:direction panLocation:location];
+            }
+        };
+        
+        gestureControl.changedPan = ^(ZFPlayerGestureControl * _Nonnull control, ZFPanDirection direction, ZFPanLocation location, CGPoint velocity) {
+            @strongify(self)
+            if ([self.controlView respondsToSelector:@selector(gestureChangedPan:panDirection:panLocation:withVelocity:)]) {
+                [self.controlView gestureChangedPan:control panDirection:direction panLocation:location withVelocity:velocity];
+            }
+        };
+        
+        gestureControl.endedPan = ^(ZFPlayerGestureControl * _Nonnull control, ZFPanDirection direction, ZFPanLocation location) {
+            @strongify(self)
+            if ([self.controlView respondsToSelector:@selector(gestureEndedPan:panDirection:panLocation:)]) {
+                [self.controlView gestureEndedPan:control panDirection:direction panLocation:location];
+            }
+        };
+        
+        gestureControl.pinched = ^(ZFPlayerGestureControl * _Nonnull control, float scale) {
+            @strongify(self)
+            if ([self.controlView respondsToSelector:@selector(gesturePinched:scale:)]) {
+                [self.controlView gesturePinched:control scale:scale];
+            }
+        };
+        objc_setAssociatedObject(self, _cmd, gestureControl, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    }
+    return gestureControl;
+}
+
+- (ZFPlayerDisableGestureTypes)disableGestureTypes {
+    return [objc_getAssociatedObject(self, _cmd) unsignedIntegerValue];
+}
+
+#pragma mark - setter
+
+- (void)setDisableGestureTypes:(ZFPlayerDisableGestureTypes)disableGestureTypes {
+    objc_setAssociatedObject(self, @selector(disableGestureTypes), @(disableGestureTypes), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    self.gestureControl.disableTypes = disableGestureTypes;
+}
+
+@end
+
+@implementation ZFPlayerController (ZFPlayerScrollView)
+
++ (void)load {
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        SEL selectors[] = {
+            NSSelectorFromString(@"dealloc")
+        };
+        
+        for (NSInteger index = 0; index < sizeof(selectors) / sizeof(SEL); ++index) {
+            SEL originalSelector = selectors[index];
+            SEL swizzledSelector = NSSelectorFromString([@"zf_" stringByAppendingString:NSStringFromSelector(originalSelector)]);
+            Method originalMethod = class_getInstanceMethod(self, originalSelector);
+            Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
+            if (class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) {
+                class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
+            } else {
+                method_exchangeImplementations(originalMethod, swizzledMethod);
+            }
+        }
+    });
+}
+
+- (void)zf_dealloc {
+    [self.smallFloatView removeFromSuperview];
+    self.smallFloatView = nil;
+    [self zf_dealloc];
+}
+
+//// Add video to the cell
+- (void)addPlayerViewToCell {
+    self.isSmallFloatViewShow = NO;
+    self.smallFloatView.hidden = YES;
+    UIView *cell = [self.scrollView zf_getCellForIndexPath:self.playingIndexPath];
+    self.containerView = [cell viewWithTag:self.containerViewTag];
+    [self.containerView addSubview:self.currentPlayerManager.view];
+    self.currentPlayerManager.view.frame = self.containerView.bounds;
+    self.currentPlayerManager.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+    [self.orientationObserver cellModelRotateView:self.currentPlayerManager.view rotateViewAtCell:cell playerViewTag:self.containerViewTag];
+}
+
+/// Add to the keyWindow
+- (void)addPlayerViewToKeyWindow {
+    self.isSmallFloatViewShow = YES;
+    self.smallFloatView.hidden = NO;
+    [self.smallFloatView addSubview:self.currentPlayerManager.view];
+    self.currentPlayerManager.view.frame = self.smallFloatView.bounds;
+    self.currentPlayerManager.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+    [self.orientationObserver cellSmallModelRotateView:self.currentPlayerManager.view containerView:self.smallFloatView];
+}
+
+#pragma mark - setter
+
+- (void)setScrollView:(UIScrollView *)scrollView {
+    objc_setAssociatedObject(self, @selector(scrollView), scrollView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    self.scrollView.zf_WWANAutoPlay = self.isWWANAutoPlay;
+    @weakify(self)
+    scrollView.zf_enableScrollHook = YES;
+    scrollView.zf_playerDidAppearInScrollView = ^(NSIndexPath * _Nonnull indexPath) {
+        @strongify(self)
+        if (self.isFullScreen) return;
+        if ([self.controlView respondsToSelector:@selector(playerDidAppearInScrollView:)]) {
+            [self.controlView playerDidAppearInScrollView:self];
+        }
+        if (!self.stopWhileNotVisible) {
+            [self addPlayerViewToCell];
+        }
+    };
+    
+    scrollView.zf_playerWillDisappearInScrollView = ^(NSIndexPath * _Nonnull indexPath) {
+        @strongify(self)
+        if (self.isFullScreen) return;
+        if ([self.controlView respondsToSelector:@selector(playerWillDisappearInScrollView:)]) {
+            [self.controlView playerWillDisappearInScrollView:self];
+        }
+    };
+    
+    scrollView.zf_playerDisappearHalfInScrollView = ^(NSIndexPath * _Nonnull indexPath) {
+        @strongify(self)
+        if (self.isFullScreen) return;
+        if ([self.controlView respondsToSelector:@selector(playerDisappearHalfInScrollView:)]) {
+            [self.controlView playerDisappearHalfInScrollView:self];
+        }
+        if (self.stopWhileNotVisible) {
+            [self stopCurrentPlayingCell];
+        }
+    };
+    
+    scrollView.zf_playerDidDisappearInScrollView = ^(NSIndexPath * _Nonnull indexPath) {
+        @strongify(self)
+        if (self.isFullScreen) return;
+        if ([self.controlView respondsToSelector:@selector(playerDidDisappearInScrollView:)]) {
+            [self.controlView playerDidDisappearInScrollView:self];
+        }
+        if (!self.stopWhileNotVisible) {
+            [self addPlayerViewToKeyWindow];
+        } else {
+            [self stopCurrentPlayingCell];
+        }
+    };
+}
+
+- (void)setStopWhileNotVisible:(BOOL)stopWhileNotVisible {
+    self.scrollView.zf_stopWhileNotVisible = stopWhileNotVisible;
+    objc_setAssociatedObject(self, @selector(stopWhileNotVisible), @(stopWhileNotVisible), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (void)setContainerViewTag:(NSInteger)containerViewTag {
+    objc_setAssociatedObject(self, @selector(containerViewTag), @(containerViewTag), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    self.scrollView.zf_containerViewTag = containerViewTag;
+}
+
+- (void)setPlayingIndexPath:(NSIndexPath *)playingIndexPath {
+    objc_setAssociatedObject(self, @selector(playingIndexPath), playingIndexPath, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    if (playingIndexPath) {
+        [self stopCurrentPlayingCell];
+        UIView *cell = [self.scrollView zf_getCellForIndexPath:playingIndexPath];
+        self.containerView = [cell viewWithTag:self.containerViewTag];
+        [self.orientationObserver cellModelRotateView:self.currentPlayerManager.view rotateViewAtCell:cell playerViewTag:self.containerViewTag];
+        [self.orientationObserver addDeviceOrientationObserver];
+        self.scrollView.zf_playingIndexPath = playingIndexPath;
+    }
+}
+
+- (void)setShouldAutoPlay:(BOOL)shouldAutoPlay {
+    self.scrollView.zf_shouldAutoPlay = shouldAutoPlay;
+}
+
+- (void)setSectionAssetURLs:(NSArray<NSArray<NSURL *> *> * _Nullable)sectionAssetURLs {
+    objc_setAssociatedObject(self, @selector(sectionAssetURLs), sectionAssetURLs, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (void)setSmallFloatView:(ZFFloatView * _Nullable)smallFloatView {
+    objc_setAssociatedObject(self, @selector(smallFloatView), smallFloatView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (void)setIsSmallFloatViewShow:(BOOL)isSmallFloatViewShow {
+    objc_setAssociatedObject(self, @selector(isSmallFloatViewShow), @(isSmallFloatViewShow), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+#pragma mark - getter
+
+- (UIScrollView *)scrollView {
+    UIScrollView *scrollView = objc_getAssociatedObject(self, _cmd);
+    return scrollView;
+}
+
+- (BOOL)stopWhileNotVisible {
+    NSNumber *number = objc_getAssociatedObject(self, _cmd);
+    if (number) return number.boolValue;
+    self.stopWhileNotVisible = YES;
+    return YES;
+}
+
+- (NSInteger)containerViewTag {
+    return [objc_getAssociatedObject(self, _cmd) integerValue];
+}
+
+- (ZFFloatView *)smallFloatView {
+    ZFFloatView *smallFloatView = objc_getAssociatedObject(self, _cmd);
+    if (!smallFloatView) {
+        smallFloatView = [[ZFFloatView alloc] init];
+        smallFloatView.parentView = [UIApplication sharedApplication].keyWindow;
+        smallFloatView.hidden = YES;
+        self.smallFloatView = smallFloatView;
+    }
+    return smallFloatView;
+}
+
+- (BOOL)isSmallFloatViewShow {
+    return [objc_getAssociatedObject(self, _cmd) boolValue];
+}
+
+- (NSIndexPath *)playingIndexPath {
+    return objc_getAssociatedObject(self, _cmd);
+}
+
+- (NSArray<NSArray<NSURL *> *> *)sectionAssetURLs {
+    return objc_getAssociatedObject(self, _cmd);
+}
+
+- (BOOL)shouldAutoPlay {
+    return self.scrollView.zf_shouldAutoPlay;
+}
+
+- (void)playTheIndexPath:(NSIndexPath *)indexPath scrollToTop:(BOOL)scrollToTop completionHandler:(void (^ _Nullable)(void))completionHandler {
+    NSURL *assetURL;
+    if (self.sectionAssetURLs.count) {
+        assetURL = self.sectionAssetURLs[indexPath.section][indexPath.row];
+    } else if (self.assetURLs.count) {
+        assetURL = self.assetURLs[indexPath.row];
+        self.currentPlayIndex = indexPath.row;
+    }
+    if (scrollToTop) {
+        @weakify(self)
+        [self.scrollView zf_scrollToRowAtIndexPath:indexPath completionHandler:^{
+            @strongify(self)
+            if (completionHandler) completionHandler();
+            self.playingIndexPath = indexPath;
+            self.assetURL = assetURL;
+            [self.scrollView zf_scrollViewDidStopScroll];
+        }];
+    } else {
+        if (completionHandler) completionHandler();
+        self.playingIndexPath = indexPath;
+        self.assetURL = assetURL;
+    }
+}
+
+- (void)playTheIndexPath:(NSIndexPath *)indexPath scrollToTop:(BOOL)scrollToTop {
+    self.playingIndexPath = indexPath;
+    NSURL *assetURL;
+    if (self.sectionAssetURLs.count) {
+        assetURL = self.sectionAssetURLs[indexPath.section][indexPath.row];
+    } else if (self.assetURLs.count) {
+        assetURL = self.assetURLs[indexPath.row];
+        self.currentPlayIndex = indexPath.row;
+    }
+    self.assetURL = assetURL;
+    if (scrollToTop) {
+        [self.scrollView zf_scrollToRowAtIndexPath:indexPath completionHandler:nil];
+    }
+}
+
+- (void)playTheIndexPath:(NSIndexPath *)indexPath assetURL:(NSURL *)assetURL scrollToTop:(BOOL)scrollToTop {
+    self.playingIndexPath = indexPath;
+    self.assetURL = assetURL;
+    if (scrollToTop) {
+        [self.scrollView zf_scrollToRowAtIndexPath:indexPath completionHandler:nil];
+    }
+}
+
+- (void)stopCurrentPlayingCell {
+    if (self.scrollView.zf_playingIndexPath) {
+        [self stop];
+        self.isSmallFloatViewShow = NO;
+        self.scrollView.zf_playingIndexPath = nil;
+        if (self.smallFloatView) self.smallFloatView.hidden = YES;
+    }
+}
+
+@end

--
Gitblit v1.8.0