Repository: SoulLights/SLPlayer Branch: master Commit: 65747b57ab5c Files: 35 Total size: 147.4 KB Directory structure: gitextract_v6rpag0q/ ├── .gitignore ├── LICENSE └── SLPlayerDemo/ ├── Podfile ├── SLPlayerDemo/ │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets/ │ │ ├── AppIcon.appiconset/ │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj/ │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── SLPlayer/ │ │ ├── SLBrightnessView.h │ │ ├── SLBrightnessView.m │ │ ├── SLMarco.h │ │ ├── SLPlayer.h │ │ ├── SLPlayerControlView.h │ │ ├── SLPlayerControlView.m │ │ ├── SLPlayerControlViewDelagate.h │ │ ├── SLPlayerModel.h │ │ ├── SLPlayerModel.m │ │ ├── SLPlayerView.h │ │ ├── SLPlayerView.m │ │ ├── UIView+ControlView.h │ │ ├── UIView+ControlView.m │ │ ├── UIViewController+SDPlayerRotation.h │ │ └── UIViewController+SDPlayerRotation.m │ ├── SimpleAlignCell.h │ ├── SimpleAlignCell.m │ ├── SimpleAlignCell.xib │ ├── Test1ViewController.h │ ├── Test1ViewController.m │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── SLPlayerDemo.xcodeproj/ │ ├── project.pbxproj │ └── project.xcworkspace/ │ └── contents.xcworkspacedata └── SLPlayerDemo.xcworkspace/ └── contents.xcworkspacedata ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore *.md ## Build generated build/ DerivedData/ ## Various settings *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata/ ## Other *.moved-aside *.xccheckout *.xcscmblueprint ## Obj-C/Swift specific *.hmap *.ipa *.dSYM.zip *.dSYM # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control # Pods/ # Carthage # # Add this line if you want to avoid checking in source code from Carthage dependencies. # Carthage/Checkouts Carthage/Build # fastlane # # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the # screenshots whenever they are needed. # For more information about the recommended setup visit: # https://docs.fastlane.tools/best-practices/source-control/#source-control fastlane/report.xml fastlane/Preview.html fastlane/screenshots fastlane/test_output # Code Injection # # After new code Injection tools there's a generated folder /iOSInjectionProject # https://github.com/johnno1962/injectionforxcode iOSInjectionProject/ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2017 SoulLights 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. ================================================ FILE: SLPlayerDemo/Podfile ================================================ platform :ios, '8.0' inhibit_all_warnings! target 'SLPlayerDemo' do pod 'Masonry' end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/AppDelegate.h ================================================ // // AppDelegate.h // SLPlayerDemo // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/AppDelegate.m ================================================ // // AppDelegate.m // SLPlayerDemo // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import "AppDelegate.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. return YES; } - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } - (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "20x20", "scale" : "2x" }, { "idiom" : "iphone", "size" : "20x20", "scale" : "3x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "3x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "3x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "3x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "1x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "2x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "1x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "2x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "2x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "1x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "2x" }, { "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" }, { "idiom" : "ios-marketing", "size" : "1024x1024", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: SLPlayerDemo/SLPlayerDemo/Assets.xcassets/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: SLPlayerDemo/SLPlayerDemo/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: SLPlayerDemo/SLPlayerDemo/Base.lproj/Main.storyboard ================================================ ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/SLBrightnessView.h ================================================ // // SLBrightnessView.h // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import @interface SLBrightnessView : UIView @property (nonatomic, assign) BOOL isLockScreen; @property (nonatomic, assign) BOOL isAllowLandscape; @property (nonatomic, assign) BOOL isStatusBarHidden; @property (nonatomic, assign) BOOL isLandscape; + (instancetype)sharedBrightnessView; @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/SLBrightnessView.m ================================================ // // SLBrightnessView.m // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import "SLBrightnessView.h" #import "SLMarco.h" @interface SLBrightnessView () @property (nonatomic, strong) UIImageView *backImage; @property (nonatomic, strong) UILabel *title; @property (nonatomic, strong) UIView *longView; @property (nonatomic, strong) NSMutableArray *tipArray; @property (nonatomic, assign) BOOL orientationDidChange; @end @implementation SLBrightnessView + (instancetype)sharedBrightnessView { static SLBrightnessView *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[SLBrightnessView alloc] init]; [[UIApplication sharedApplication].keyWindow addSubview:instance]; }); return instance; } - (instancetype)init { if (self = [super init]) { self.frame = CGRectMake(ScreenWidth * 0.5, ScreenHeight * 0.5, 155, 155); self.layer.cornerRadius = 10; self.layer.masksToBounds = YES; UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:self.bounds]; toolbar.alpha = 0.97; [self addSubview:toolbar]; self.backImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 79, 76)]; self.backImage.image = SLPlayerImage(@"SLPlayer_brightness"); [self addSubview:self.backImage]; self.title = [[UILabel alloc] initWithFrame:CGRectMake(0, 5, self.bounds.size.width, 30)]; self.title.font = [UIFont boldSystemFontOfSize:16]; self.title.textColor = [UIColor colorWithRed:0.25f green:0.22f blue:0.21f alpha:1.00f]; self.title.textAlignment = NSTextAlignmentCenter; self.title.text = @"亮度"; [self addSubview:self.title]; self.longView = [[UIView alloc]initWithFrame:CGRectMake(13, 132, self.bounds.size.width - 26, 7)]; self.longView.backgroundColor = [UIColor colorWithRed:0.25f green:0.22f blue:0.21f alpha:1.00f]; [self addSubview:self.longView]; [self createTips]; [self addNotification]; [self addObserver]; self.alpha = 0.0; } return self; } - (void)createTips { self.tipArray = [NSMutableArray arrayWithCapacity:16]; CGFloat tipW = (self.longView.bounds.size.width - 17) / 16; CGFloat tipH = 5; CGFloat tipY = 1; for (int i = 0; i < 16; i++) { CGFloat tipX = i * (tipW + 1) + 1; UIImageView *image = [[UIImageView alloc] init]; image.backgroundColor = [UIColor whiteColor]; image.frame = CGRectMake(tipX, tipY, tipW, tipH); [self.longView addSubview:image]; [self.tipArray addObject:image]; } [self updateLongView:[UIScreen mainScreen].brightness]; } #pragma makr - 通知 KVO - (void)addNotification { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateLayer:) name:UIDeviceOrientationDidChangeNotification object:nil]; } - (void)addObserver { [[UIScreen mainScreen] addObserver:self forKeyPath:@"brightness" options:NSKeyValueObservingOptionNew context:NULL]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { CGFloat sound = [change[@"new"] floatValue]; [self appearSoundView]; [self updateLongView:sound]; } - (void)updateLayer:(NSNotification *)notify { self.orientationDidChange = YES; [self setNeedsLayout]; [self layoutIfNeeded]; } #pragma mark - Methond - (void)appearSoundView { if (self.alpha == 0.0) { self.orientationDidChange = NO; self.alpha = 1.0; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self disAppearSoundView]; }); } } - (void)disAppearSoundView { if (self.alpha == 1.0) { [UIView animateWithDuration:0.8 animations:^{ self.alpha = 0.0; }]; } } #pragma mark - Update View - (void)updateLongView:(CGFloat)sound { CGFloat stage = 1 / 15.0; NSInteger level = sound / stage; for (int i = 0; i < self.tipArray.count; i++) { UIImageView *img = self.tipArray[i]; if (i <= level) { img.hidden = NO; } else { img.hidden = YES; } } } - (void)layoutSubviews { [super layoutSubviews]; self.backImage.center = CGPointMake(155 * 0.5, 155 * 0.5); self.center = CGPointMake(ScreenWidth * 0.5, ScreenHeight * 0.5); } - (void)dealloc { [[UIScreen mainScreen] removeObserver:self forKeyPath:@"brightness"]; [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)setIsStatusBarHidden:(BOOL)isStatusBarHidden { _isStatusBarHidden = isStatusBarHidden; [[self sl_currentViewController] setNeedsStatusBarAppearanceUpdate]; } - (void)setIsLandscape:(BOOL)isLandscape { _isLandscape = isLandscape; [[self sl_currentViewController] setNeedsStatusBarAppearanceUpdate]; } - (UIViewController*)sl_currentViewController{ UIWindow *window = [[UIApplication sharedApplication].delegate window]; UIViewController *topViewController = [window rootViewController]; while (true) { if (topViewController.presentedViewController) { topViewController = topViewController.presentedViewController; } else if ([topViewController isKindOfClass:[UINavigationController class]] && [(UINavigationController*)topViewController topViewController]) { topViewController = [(UINavigationController *)topViewController topViewController]; } else if ([topViewController isKindOfClass:[UITabBarController class]]) { UITabBarController *tab = (UITabBarController *)topViewController; topViewController = tab.selectedViewController; } else { break; } } return topViewController; } @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/SLMarco.h ================================================ // // SLMarco.h // SLPlayer_test // // Created by lisd on 2017/12/8. // Copyright © 2017年 lisd. All rights reserved. // #ifndef SLMarco_h #define SLMarco_h #define iPhone4s ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 960), [[UIScreen mainScreen] currentMode].size) : NO) // 监听TableView的contentOffset #define kSLPlayerViewContentOffset @"contentOffset" // player的单例 #define SLPlayerShared [SLBrightnessView sharedBrightnessView] // 屏幕的宽 #define ScreenWidth [[UIScreen mainScreen] bounds].size.width // 屏幕的高 #define ScreenHeight [[UIScreen mainScreen] bounds].size.height // 颜色值RGB #define RGBA(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a] // 图片路径 #define SLPlayerSrcName(file) [@"SLPlayer.bundle" stringByAppendingPathComponent:file] #define SLPlayerFrameworkSrcName(file) [@"Frameworks/SLPlayer.framework/SLPlayer.bundle" stringByAppendingPathComponent:file] #define SLPlayerImage(file) [UIImage imageNamed:SLPlayerSrcName(file)] ? :[UIImage imageNamed:SLPlayerFrameworkSrcName(file)] #define SLPlayerOrientationIsLandscape UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation) #define SLPlayerOrientationIsPortrait UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation) #endif /* SLMarco_h */ ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/SLPlayer.h ================================================ // // SLPlayer.h // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import "SLPlayerControlViewDelagate.h" #import "SLPlayerView.h" #import "SLPlayerModel.h" #import "SLPlayerControlView.h" #import "SLBrightnessView.h" #import "SLMarco.h" #import "UIView+ControlView.h" #import "UIViewController+SDPlayerRotation.h" #import ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/SLPlayerControlView.h ================================================ // // SLPlayerControlView.h // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import @interface SLPlayerControlView : UIView @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/SLPlayerControlView.m ================================================ // // SLPlayerControlView.m // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import "SLPlayerControlView.h" #import #import #import "UIView+ControlView.h" #import #import "SLMarco.h" #import "SLBrightnessView.h" #pragma clang diagnostic push #pragma clang diagnostic ignored"-Wdeprecated-declarations" static const CGFloat SLPlayerAnimationTimeInterval = 7.0f; static const CGFloat SLPlayerControlBarAutoFadeOutTimeInterval = 0.35f; @interface SLPlayerControlView () @property (nonatomic, strong) UILabel *titleLabel; @property (nonatomic, strong) UIButton *startBtn; @property (nonatomic, strong) UILabel *currentTimeLabel; @property (nonatomic, strong) UILabel *totalTimeLabel; @property (nonatomic, strong) UIProgressView *progressView; @property (nonatomic, strong) UISlider *videoSlider; @property (nonatomic, strong) UIButton *fullScreenBtn; @property (nonatomic, strong) UIButton *lockBtn; @property (nonatomic,strong) UIActivityIndicatorView *loadingView; @property (nonatomic, strong) UIButton *backBtn; @property (nonatomic, strong) UIButton *closeBtn; @property (nonatomic, strong) UIButton *repeatBtn; @property (nonatomic, strong) UIImageView *bottomImageView; @property (nonatomic, strong) UIImageView *topImageView; @property (nonatomic, strong) UIButton *downLoadBtn; @property (nonatomic, strong) UIButton *resolutionBtn; @property (nonatomic, strong) UIView *resolutionView; @property (nonatomic, strong) UIButton *playeBtn; @property (nonatomic, strong) UIButton *failBtn; @property (nonatomic, strong) UIView *fastView; @property (nonatomic, strong) UIProgressView *fastProgressView; @property (nonatomic, strong) UILabel *fastTimeLabel; @property (nonatomic, strong) UIImageView *fastImageView; @property (nonatomic, weak ) UIButton *resoultionCurrentBtn; @property (nonatomic, strong) UIImageView *placeholderImageView; @property (nonatomic, strong) UIProgressView *bottomProgressView; @property (nonatomic, strong) NSArray *resolutionArray; @property (nonatomic, assign, getter=isShowing) BOOL showing; @property (nonatomic, assign, getter=isShrink ) BOOL shrink; @property (nonatomic, assign, getter=isCellVideo)BOOL cellVideo; @property (nonatomic, assign, getter=isDragged) BOOL dragged; @property (nonatomic, assign, getter=isPlayEnd) BOOL playeEnd; @property (nonatomic, assign,getter=isFullScreen)BOOL fullScreen; @end @implementation SLPlayerControlView - (instancetype)init { self = [super init]; if (self) { [self addSubview:self.placeholderImageView]; [self addSubview:self.topImageView]; [self addSubview:self.bottomImageView]; [self.bottomImageView addSubview:self.startBtn]; [self.bottomImageView addSubview:self.currentTimeLabel]; [self.bottomImageView addSubview:self.progressView]; [self.bottomImageView addSubview:self.videoSlider]; [self.bottomImageView addSubview:self.fullScreenBtn]; [self.bottomImageView addSubview:self.totalTimeLabel]; [self.topImageView addSubview:self.downLoadBtn]; [self addSubview:self.lockBtn]; [self.topImageView addSubview:self.backBtn]; [self addSubview:self.loadingView]; [self addSubview:self.repeatBtn]; [self addSubview:self.playeBtn]; [self addSubview:self.failBtn]; [self addSubview:self.fastView]; [self.fastView addSubview:self.fastImageView]; [self.fastView addSubview:self.fastTimeLabel]; [self.fastView addSubview:self.fastProgressView]; [self.topImageView addSubview:self.resolutionBtn]; [self.topImageView addSubview:self.titleLabel]; [self addSubview:self.closeBtn]; [self addSubview:self.bottomProgressView]; [self makeSubViewsConstraints]; self.downLoadBtn.hidden = YES; self.resolutionBtn.hidden = YES; [self sl_playerResetControlView]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground) name:UIApplicationWillResignActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterPlayground) name:UIApplicationDidBecomeActiveNotification object:nil]; [self listeningRotating]; } return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; } - (void)makeSubViewsConstraints { [self.placeholderImageView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(UIEdgeInsetsZero); }]; [self.closeBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.trailing.equalTo(self.mas_trailing).offset(7); make.top.equalTo(self.mas_top).offset(-7); make.width.height.mas_equalTo(20); }]; [self.topImageView mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.trailing.equalTo(self); make.top.equalTo(self.mas_top).offset(0); make.height.mas_equalTo(50); }]; [self.backBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.equalTo(self.topImageView.mas_leading).offset(10); make.top.equalTo(self.topImageView.mas_top).offset(3); make.width.height.mas_equalTo(40); }]; [self.downLoadBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.width.mas_equalTo(40); make.height.mas_equalTo(49); make.trailing.equalTo(self.topImageView.mas_trailing).offset(-10); make.centerY.equalTo(self.backBtn.mas_centerY); }]; [self.resolutionBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.width.mas_equalTo(40); make.height.mas_equalTo(25); make.trailing.equalTo(self.downLoadBtn.mas_leading).offset(-10); make.centerY.equalTo(self.backBtn.mas_centerY); }]; [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.equalTo(self.backBtn.mas_trailing).offset(5); make.centerY.equalTo(self.backBtn.mas_centerY); make.trailing.equalTo(self.resolutionBtn.mas_leading).offset(-10); }]; [self.bottomImageView mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.trailing.bottom.mas_equalTo(0); make.height.mas_equalTo(50); }]; [self.startBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.equalTo(self.bottomImageView.mas_leading).offset(5); make.bottom.equalTo(self.bottomImageView.mas_bottom).offset(-5); make.width.height.mas_equalTo(30); }]; [self.currentTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.equalTo(self.startBtn.mas_trailing).offset(-3); make.centerY.equalTo(self.startBtn.mas_centerY); make.width.mas_equalTo(43); }]; [self.fullScreenBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.width.height.mas_equalTo(30); make.trailing.equalTo(self.bottomImageView.mas_trailing).offset(-5); make.centerY.equalTo(self.startBtn.mas_centerY); }]; [self.totalTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.trailing.equalTo(self.fullScreenBtn.mas_leading).offset(3); make.centerY.equalTo(self.startBtn.mas_centerY); make.width.mas_equalTo(43); }]; [self.progressView mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.equalTo(self.currentTimeLabel.mas_trailing).offset(4); make.trailing.equalTo(self.totalTimeLabel.mas_leading).offset(-4); make.centerY.equalTo(self.startBtn.mas_centerY); }]; [self.videoSlider mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.equalTo(self.currentTimeLabel.mas_trailing).offset(4); make.trailing.equalTo(self.totalTimeLabel.mas_leading).offset(-4); make.centerY.equalTo(self.currentTimeLabel.mas_centerY).offset(-1); make.height.mas_equalTo(30); }]; [self.lockBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.equalTo(self.mas_leading).offset(15); make.centerY.equalTo(self.mas_centerY); make.width.height.mas_equalTo(32); }]; [self.repeatBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(self); }]; [self.playeBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.width.height.mas_equalTo(50); make.center.equalTo(self); }]; [self.loadingView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(self); make.width.with.height.mas_equalTo(45); }]; [self.failBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(self); make.width.mas_equalTo(130); make.height.mas_equalTo(33); }]; [self.fastView mas_makeConstraints:^(MASConstraintMaker *make) { make.width.mas_equalTo(125); make.height.mas_equalTo(80); make.center.equalTo(self); }]; [self.fastImageView mas_makeConstraints:^(MASConstraintMaker *make) { make.width.mas_offset(32); make.height.mas_offset(32); make.top.mas_equalTo(5); make.centerX.mas_equalTo(self.fastView.mas_centerX); }]; [self.fastTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.with.trailing.mas_equalTo(0); make.top.mas_equalTo(self.fastImageView.mas_bottom).offset(2); }]; [self.fastProgressView mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.mas_equalTo(12); make.trailing.mas_equalTo(-12); make.top.mas_equalTo(self.fastTimeLabel.mas_bottom).offset(10); }]; [self.bottomProgressView mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.trailing.mas_offset(0); make.bottom.mas_offset(0); }]; } - (void)layoutSubviews { [super layoutSubviews]; UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation; if (currentOrientation == UIDeviceOrientationPortrait) { [self setOrientationPortraitConstraint]; } else { [self setOrientationLandscapeConstraint]; } } #pragma mark - Action - (void)changeResolution:(UIButton *)sender { sender.selected = YES; if (sender.isSelected) { sender.backgroundColor = RGBA(86, 143, 232, 1); } else { sender.backgroundColor = [UIColor clearColor]; } self.resoultionCurrentBtn.selected = NO; self.resoultionCurrentBtn.backgroundColor = [UIColor clearColor]; self.resoultionCurrentBtn = sender; self.resolutionView.hidden = YES; self.resolutionBtn.selected = NO; [self.resolutionBtn setTitle:sender.titleLabel.text forState:UIControlStateNormal]; if ([self.delegate respondsToSelector:@selector(sl_controlView:resolutionAction:)]) { [self.delegate sl_controlView:self resolutionAction:sender]; } } /** * UISlider TapAction */ - (void)tapSliderAction:(UITapGestureRecognizer *)tap { if ([tap.view isKindOfClass:[UISlider class]]) { UISlider *slider = (UISlider *)tap.view; CGPoint point = [tap locationInView:slider]; CGFloat length = slider.frame.size.width; CGFloat tapValue = point.x / length; if ([self.delegate respondsToSelector:@selector(sl_controlView:progressSliderTap:)]) { [self.delegate sl_controlView:self progressSliderTap:tapValue]; } } } - (void)panRecognizer:(UIPanGestureRecognizer *)sender {} - (void)backBtnClick:(UIButton *)sender { UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if (self.isCellVideo && orientation == UIInterfaceOrientationPortrait) { if ([self.delegate respondsToSelector:@selector(sl_controlView:closeAction:)]) { [self.delegate sl_controlView:self closeAction:sender]; } } else { if ([self.delegate respondsToSelector:@selector(sl_controlView:backAction:)]) { [self.delegate sl_controlView:self backAction:sender]; } } } - (void)lockScrrenBtnClick:(UIButton *)sender { sender.selected = !sender.selected; self.showing = NO; [self sl_playerShowControlView]; if ([self.delegate respondsToSelector:@selector(sl_controlView:lockScreenAction:)]) { [self.delegate sl_controlView:self lockScreenAction:sender]; } } - (void)playBtnClick:(UIButton *)sender { sender.selected = !sender.selected; if ([self.delegate respondsToSelector:@selector(sl_controlView:playAction:)]) { [self.delegate sl_controlView:self playAction:sender]; } } - (void)closeBtnClick:(UIButton *)sender { if ([self.delegate respondsToSelector:@selector(sl_controlView:closeAction:)]) { [self.delegate sl_controlView:self closeAction:sender]; } } - (void)fullScreenBtnClick:(UIButton *)sender { sender.selected = !sender.selected; if ([self.delegate respondsToSelector:@selector(sl_controlView:fullScreenAction:)]) { [self.delegate sl_controlView:self fullScreenAction:sender]; } } - (void)repeatBtnClick:(UIButton *)sender { [self sl_playerResetControlView]; [self sl_playerShowControlView]; if ([self.delegate respondsToSelector:@selector(sl_controlView:repeatPlayAction:)]) { [self.delegate sl_controlView:self repeatPlayAction:sender]; } } - (void)downloadBtnClick:(UIButton *)sender { if ([self.delegate respondsToSelector:@selector(sl_controlView:downloadVideoAction:)]) { [self.delegate sl_controlView:self downloadVideoAction:sender]; } } - (void)resolutionBtnClick:(UIButton *)sender { sender.selected = !sender.selected; self.resolutionView.hidden = !sender.isSelected; } - (void)centerPlayBtnClick:(UIButton *)sender { if ([self.delegate respondsToSelector:@selector(sl_controlView:cneterPlayAction:)]) { [self.delegate sl_controlView:self cneterPlayAction:sender]; } } - (void)failBtnClick:(UIButton *)sender { self.failBtn.hidden = YES; if ([self.delegate respondsToSelector:@selector(sl_controlView:failAction:)]) { [self.delegate sl_controlView:self failAction:sender]; } } - (void)progressSliderTouchBegan:(UISlider *)sender { [self sl_playerCancelAutoFadeOutControlView]; if ([self.delegate respondsToSelector:@selector(sl_controlView:progressSliderTouchBegan:)]) { [self.delegate sl_controlView:self progressSliderTouchBegan:sender]; } } - (void)progressSliderValueChanged:(UISlider *)sender { if ([self.delegate respondsToSelector:@selector(sl_controlView:progressSliderValueChanged:)]) { [self.delegate sl_controlView:self progressSliderValueChanged:sender]; } } - (void)progressSliderTouchEnded:(UISlider *)sender { self.showing = YES; if ([self.delegate respondsToSelector:@selector(sl_controlView:progressSliderTouchEnded:)]) { [self.delegate sl_controlView:self progressSliderTouchEnded:sender]; } } - (void)appDidEnterBackground { [self sl_playerCancelAutoFadeOutControlView]; } - (void)appDidEnterPlayground { if (!self.isShrink) { [self sl_playerShowControlView]; } } - (void)playerPlayDidEnd { self.backgroundColor = RGBA(0, 0, 0, .6); self.repeatBtn.hidden = NO; self.showing = NO; [self sl_playerShowControlView]; } - (void)onDeviceOrientationChange { if (SLPlayerShared.isLockScreen) { return; } self.lockBtn.hidden = !self.isFullScreen; self.fullScreenBtn.selected = self.isFullScreen; UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; if (orientation == UIDeviceOrientationFaceUp || orientation == UIDeviceOrientationFaceDown || orientation == UIDeviceOrientationUnknown || orientation == UIDeviceOrientationPortraitUpsideDown) { return; } if (!self.isShrink && !self.isPlayEnd && !self.showing) { [self sl_playerShowOrHideControlView]; } } - (void)setOrientationLandscapeConstraint { if (self.isCellVideo) { self.shrink = NO; } self.fullScreen = YES; self.lockBtn.hidden = !self.isFullScreen; self.fullScreenBtn.selected = self.isFullScreen; [self.backBtn setImage:SLPlayerImage(@"SLPlayer_back_full") forState:UIControlStateNormal]; [self.backBtn mas_remakeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.topImageView.mas_top).offset(23); make.leading.equalTo(self.topImageView.mas_leading).offset(10); make.width.height.mas_equalTo(40); }]; } - (void)setOrientationPortraitConstraint { self.fullScreen = NO; self.lockBtn.hidden = !self.isFullScreen; self.fullScreenBtn.selected = self.isFullScreen; [self.backBtn mas_remakeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.topImageView.mas_top).offset(3); make.leading.equalTo(self.topImageView.mas_leading).offset(10); make.width.height.mas_equalTo(40); }]; if (self.isCellVideo) { [self.backBtn setImage:SLPlayerImage(@"SLPlayer_close") forState:UIControlStateNormal]; } } #pragma mark - Private Method - (void)showControlView { self.showing = YES; if (self.lockBtn.isSelected) { self.topImageView.alpha = 0; self.bottomImageView.alpha = 0; } else { self.topImageView.alpha = 1; self.bottomImageView.alpha = 1; } self.backgroundColor = RGBA(0, 0, 0, 0.3); self.lockBtn.alpha = 1; if (self.isCellVideo) { self.shrink = NO; } self.bottomProgressView.alpha = 0; SLPlayerShared.isStatusBarHidden = NO; } - (void)hideControlView { self.showing = NO; self.backgroundColor = RGBA(0, 0, 0, 0); self.topImageView.alpha = self.playeEnd; self.bottomImageView.alpha = 0; self.lockBtn.alpha = 0; self.bottomProgressView.alpha = 1; self.resolutionBtn.selected = YES; [self resolutionBtnClick:self.resolutionBtn]; if (self.isFullScreen && !self.playeEnd && !self.isShrink) { SLPlayerShared.isStatusBarHidden = YES; } } - (void)listeningRotating { [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onDeviceOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil]; } - (void)autoFadeOutControlView { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(sl_playerHideControlView) object:nil]; [self performSelector:@selector(sl_playerHideControlView) withObject:nil afterDelay:SLPlayerAnimationTimeInterval]; } - (CGRect)thumbRect { return [self.videoSlider thumbRectForBounds:self.videoSlider.bounds trackRect:[self.videoSlider trackRectForBounds:self.videoSlider.bounds] value:self.videoSlider.value]; } #pragma mark - setter - (void)setShrink:(BOOL)shrink { _shrink = shrink; self.closeBtn.hidden = !shrink; self.bottomProgressView.hidden = shrink; } - (void)setFullScreen:(BOOL)fullScreen { _fullScreen = fullScreen; SLPlayerShared.isLandscape = fullScreen; } #pragma mark - getter - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [[UILabel alloc] init]; _titleLabel.textColor = [UIColor whiteColor]; _titleLabel.font = [UIFont systemFontOfSize:15.0]; } return _titleLabel; } - (UIButton *)backBtn { if (!_backBtn) { _backBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_backBtn setImage:SLPlayerImage(@"SLPlayer_back_full") forState:UIControlStateNormal]; [_backBtn addTarget:self action:@selector(backBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } return _backBtn; } - (UIImageView *)topImageView { if (!_topImageView) { _topImageView = [[UIImageView alloc] init]; _topImageView.userInteractionEnabled = YES; _topImageView.alpha = 0; _topImageView.image = SLPlayerImage(@"SLPlayer_top_shadow"); } return _topImageView; } - (UIImageView *)bottomImageView { if (!_bottomImageView) { _bottomImageView = [[UIImageView alloc] init]; _bottomImageView.userInteractionEnabled = YES; _bottomImageView.alpha = 0; _bottomImageView.image = SLPlayerImage(@"SLPlayer_bottom_shadow"); } return _bottomImageView; } - (UIButton *)lockBtn { if (!_lockBtn) { _lockBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_lockBtn setImage:SLPlayerImage(@"SLPlayer_unlock-nor") forState:UIControlStateNormal]; [_lockBtn setImage:SLPlayerImage(@"SLPlayer_lock-nor") forState:UIControlStateSelected]; [_lockBtn addTarget:self action:@selector(lockScrrenBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } return _lockBtn; } - (UIButton *)startBtn { if (!_startBtn) { _startBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_startBtn setImage:SLPlayerImage(@"SLPlayer_play") forState:UIControlStateNormal]; [_startBtn setImage:SLPlayerImage(@"SLPlayer_pause") forState:UIControlStateSelected]; [_startBtn addTarget:self action:@selector(playBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } return _startBtn; } - (UIButton *)closeBtn { if (!_closeBtn) { _closeBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_closeBtn setImage:SLPlayerImage(@"SLPlayer_close") forState:UIControlStateNormal]; [_closeBtn addTarget:self action:@selector(closeBtnClick:) forControlEvents:UIControlEventTouchUpInside]; _closeBtn.hidden = YES; } return _closeBtn; } - (UILabel *)currentTimeLabel { if (!_currentTimeLabel) { _currentTimeLabel = [[UILabel alloc] init]; _currentTimeLabel.textColor = [UIColor whiteColor]; _currentTimeLabel.font = [UIFont systemFontOfSize:12.0f]; _currentTimeLabel.textAlignment = NSTextAlignmentCenter; } return _currentTimeLabel; } - (UIProgressView *)progressView { if (!_progressView) { _progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; _progressView.progressTintColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.5]; _progressView.trackTintColor = [UIColor clearColor]; } return _progressView; } -(UISlider *)videoSlider { if (!_videoSlider) { _videoSlider = [[UISlider alloc] init]; _videoSlider.value = 0.0; [_videoSlider setThumbImage:SLPlayerImage(@"SLPlayer_slider") forState:UIControlStateNormal]; _videoSlider.maximumValue = 1; _videoSlider.minimumTrackTintColor = [UIColor whiteColor]; _videoSlider.maximumTrackTintColor = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:0.5]; [_videoSlider addTarget:self action:@selector(progressSliderTouchBegan:) forControlEvents:UIControlEventTouchDown]; [_videoSlider addTarget:self action:@selector(progressSliderValueChanged:) forControlEvents:UIControlEventValueChanged]; [_videoSlider addTarget:self action:@selector(progressSliderTouchEnded:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchCancel | UIControlEventTouchUpOutside]; UITapGestureRecognizer *sliderTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapSliderAction:)]; [_videoSlider addGestureRecognizer:sliderTap]; UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panRecognizer:)]; panRecognizer.delegate = self; [panRecognizer setMaximumNumberOfTouches:1]; [panRecognizer setDelaysTouchesBegan:YES]; [panRecognizer setDelaysTouchesEnded:YES]; [panRecognizer setCancelsTouchesInView:YES]; [_videoSlider addGestureRecognizer:panRecognizer]; } return _videoSlider; } - (UILabel *)totalTimeLabel { if (!_totalTimeLabel) { _totalTimeLabel = [[UILabel alloc] init]; _totalTimeLabel.textColor = [UIColor whiteColor]; _totalTimeLabel.font = [UIFont systemFontOfSize:12.0f]; _totalTimeLabel.textAlignment = NSTextAlignmentCenter; } return _totalTimeLabel; } - (UIButton *)fullScreenBtn { if (!_fullScreenBtn) { _fullScreenBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_fullScreenBtn setImage:SLPlayerImage(@"SLPlayer_fullscreen") forState:UIControlStateNormal]; [_fullScreenBtn setImage:SLPlayerImage(@"SLPlayer_shrinkscreen") forState:UIControlStateSelected]; [_fullScreenBtn addTarget:self action:@selector(fullScreenBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } return _fullScreenBtn; } - (UIActivityIndicatorView *)loadingView { if (!_loadingView) { _loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; } return _loadingView; } - (UIButton *)repeatBtn { if (!_repeatBtn) { _repeatBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_repeatBtn setImage:[UIImage imageNamed:@"SLPlayer_repeat_video"] forState:UIControlStateNormal]; [_repeatBtn addTarget:self action:@selector(repeatBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } return _repeatBtn; } - (UIButton *)downLoadBtn { if (!_downLoadBtn) { _downLoadBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_downLoadBtn setImage:SLPlayerImage(@"Player_download") forState:UIControlStateNormal]; [_downLoadBtn setImage:SLPlayerImage(@"SLPlayer_not_download") forState:UIControlStateDisabled]; [_downLoadBtn addTarget:self action:@selector(downloadBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } return _downLoadBtn; } - (UIButton *)resolutionBtn { if (!_resolutionBtn) { _resolutionBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _resolutionBtn.titleLabel.font = [UIFont systemFontOfSize:12]; _resolutionBtn.backgroundColor = RGBA(0, 0, 0, 0.7); [_resolutionBtn addTarget:self action:@selector(resolutionBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } return _resolutionBtn; } - (UIButton *)playeBtn { if (!_playeBtn) { _playeBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_playeBtn setImage:SLPlayerImage(@"SLPlayer_play_btn") forState:UIControlStateNormal]; [_playeBtn addTarget:self action:@selector(centerPlayBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } return _playeBtn; } - (UIButton *)failBtn { if (!_failBtn) { _failBtn = [UIButton buttonWithType:UIButtonTypeSystem]; [_failBtn setTitle:@"加载失败,点击重试" forState:UIControlStateNormal]; [_failBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; _failBtn.titleLabel.font = [UIFont systemFontOfSize:14.0]; _failBtn.backgroundColor = RGBA(0, 0, 0, 0.7); [_failBtn addTarget:self action:@selector(failBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } return _failBtn; } - (UIView *)fastView { if (!_fastView) { _fastView = [[UIView alloc] init]; _fastView.backgroundColor = RGBA(0, 0, 0, 0.8); _fastView.layer.cornerRadius = 4; _fastView.layer.masksToBounds = YES; } return _fastView; } - (UIImageView *)fastImageView { if (!_fastImageView) { _fastImageView = [[UIImageView alloc] init]; } return _fastImageView; } - (UILabel *)fastTimeLabel { if (!_fastTimeLabel) { _fastTimeLabel = [[UILabel alloc] init]; _fastTimeLabel.textColor = [UIColor whiteColor]; _fastTimeLabel.textAlignment = NSTextAlignmentCenter; _fastTimeLabel.font = [UIFont systemFontOfSize:14.0]; } return _fastTimeLabel; } - (UIProgressView *)fastProgressView { if (!_fastProgressView) { _fastProgressView = [[UIProgressView alloc] init]; _fastProgressView.progressTintColor = [UIColor whiteColor]; _fastProgressView.trackTintColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.4]; } return _fastProgressView; } - (UIImageView *)placeholderImageView { if (!_placeholderImageView) { _placeholderImageView = [[UIImageView alloc] init]; _placeholderImageView.userInteractionEnabled = YES; } return _placeholderImageView; } - (UIProgressView *)bottomProgressView { if (!_bottomProgressView) { _bottomProgressView = [[UIProgressView alloc] init]; _bottomProgressView.progressTintColor = [UIColor whiteColor]; _bottomProgressView.trackTintColor = [UIColor clearColor]; } return _bottomProgressView; } #pragma mark - UIGestureRecognizerDelegate - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { CGRect rect = [self thumbRect]; CGPoint point = [touch locationInView:self.videoSlider]; if ([touch.view isKindOfClass:[UISlider class]]) { if (point.x <= rect.origin.x + rect.size.width && point.x >= rect.origin.x) { return NO; } } return YES; } #pragma mark - Public method - (void)sl_playerResetControlView { [self.loadingView stopAnimating]; self.videoSlider.value = 0; self.bottomProgressView.progress = 0; self.progressView.progress = 0; self.currentTimeLabel.text = @"00:00"; self.totalTimeLabel.text = @"00:00"; self.fastView.hidden = YES; self.repeatBtn.hidden = YES; self.playeBtn.hidden = YES; self.resolutionView.hidden = YES; self.failBtn.hidden = YES; self.backgroundColor = [UIColor clearColor]; self.downLoadBtn.enabled = YES; self.shrink = NO; self.showing = NO; self.playeEnd = NO; self.lockBtn.hidden = !self.isFullScreen; self.failBtn.hidden = YES; self.placeholderImageView.alpha = 1; [self hideControlView]; } - (void)sl_playerResetControlViewForResolution { self.fastView.hidden = YES; self.repeatBtn.hidden = YES; self.resolutionView.hidden = YES; self.playeBtn.hidden = YES; self.downLoadBtn.enabled = YES; self.failBtn.hidden = YES; self.backgroundColor = [UIColor clearColor]; self.shrink = NO; self.showing = NO; self.playeEnd = NO; } - (void)sl_playerCancelAutoFadeOutControlView { [NSObject cancelPreviousPerformRequestsWithTarget:self]; } - (void)sl_playerItemPlaying { [UIView animateWithDuration:1.0 animations:^{ self.placeholderImageView.alpha = 0; }]; } - (void)sl_playerShowOrHideControlView { if (self.isShowing) { [self sl_playerHideControlView]; } else { [self sl_playerShowControlView]; } } - (void)sl_playerShowControlView { if ([self.delegate respondsToSelector:@selector(sl_controlViewWillShow:isFullscreen:)]) { [self.delegate sl_controlViewWillShow:self isFullscreen:self.isFullScreen]; } [self sl_playerCancelAutoFadeOutControlView]; [UIView animateWithDuration:SLPlayerControlBarAutoFadeOutTimeInterval animations:^{ [self showControlView]; } completion:^(BOOL finished) { self.showing = YES; [self autoFadeOutControlView]; }]; } - (void)sl_playerHideControlView { if ([self.delegate respondsToSelector:@selector(sl_controlViewWillHidden:isFullscreen:)]) { [self.delegate sl_controlViewWillHidden:self isFullscreen:self.isFullScreen]; } [self sl_playerCancelAutoFadeOutControlView]; [UIView animateWithDuration:SLPlayerControlBarAutoFadeOutTimeInterval animations:^{ [self hideControlView]; } completion:^(BOOL finished) { self.showing = NO; }]; } - (void)sl_playerBottomShrinkPlay { self.shrink = YES; [self hideControlView]; } - (void)sl_playerCellPlay { self.cellVideo = YES; self.shrink = NO; [self.backBtn setImage:SLPlayerImage(@"SLPlayer_close") forState:UIControlStateNormal]; } - (void)sl_playerCurrentTime:(NSInteger)currentTime totalTime:(NSInteger)totalTime sliderValue:(CGFloat)value { NSInteger proMin = currentTime / 60; NSInteger proSec = currentTime % 60; NSInteger durMin = totalTime / 60; NSInteger durSec = totalTime % 60; if (!self.isDragged) { self.videoSlider.value = value; self.bottomProgressView.progress = value; self.currentTimeLabel.text = [NSString stringWithFormat:@"%02zd:%02zd", proMin, proSec]; } self.totalTimeLabel.text = [NSString stringWithFormat:@"%02zd:%02zd", durMin, durSec]; } - (void)sl_playerDraggedTime:(NSInteger)draggedTime totalTime:(NSInteger)totalTime isForward:(BOOL)forawrd hasPreview:(BOOL)preview { [self.loadingView stopAnimating]; NSInteger proMin = draggedTime / 60; NSInteger proSec = draggedTime % 60; NSInteger durMin = totalTime / 60; NSInteger durSec = totalTime % 60; NSString *currentTimeStr = [NSString stringWithFormat:@"%02zd:%02zd", proMin, proSec]; NSString *totalTimeStr = [NSString stringWithFormat:@"%02zd:%02zd", durMin, durSec]; CGFloat draggedValue = (CGFloat)draggedTime/(CGFloat)totalTime; NSString *timeStr = [NSString stringWithFormat:@"%@ / %@", currentTimeStr, totalTimeStr]; self.videoSlider.value = draggedValue; self.bottomProgressView.progress = draggedValue; self.dragged = YES; if (forawrd) { self.fastImageView.image = SLPlayerImage(@"SLPlayer_fast_forward"); } else { self.fastImageView.image = SLPlayerImage(@"SLPlayer_fast_backward"); } self.fastView.hidden = preview; self.fastTimeLabel.text = timeStr; self.fastProgressView.progress = draggedValue; } - (void)sl_playerDraggedEnd { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.fastView.hidden = YES; }); self.dragged = NO; self.startBtn.selected = YES; [self autoFadeOutControlView]; } - (void)sl_playerDraggedTime:(NSInteger)draggedTime sliderImage:(UIImage *)image; { self.fastView.hidden = YES; } - (void)sl_playerSetProgress:(CGFloat)progress { [self.progressView setProgress:progress animated:NO]; } - (void)sl_playerItemStatusFailed:(NSError *)error { self.failBtn.hidden = NO; } - (void)sl_playerActivity:(BOOL)animated { if (animated) { [self.loadingView startAnimating]; self.fastView.hidden = YES; } else { [self.loadingView stopAnimating]; } } - (void)sl_playerPlayEnd { self.repeatBtn.hidden = NO; self.playeEnd = YES; self.showing = NO; [self hideControlView]; self.backgroundColor = RGBA(0, 0, 0, .3); SLPlayerShared.isStatusBarHidden = NO; self.bottomProgressView.alpha = 0; } - (void)sl_playerHasDownloadFunction:(BOOL)sender { self.downLoadBtn.hidden = !sender; } - (void)sl_playerResolutionArray:(NSArray *)resolutionArray { self.resolutionBtn.hidden = NO; _resolutionArray = resolutionArray; [_resolutionBtn setTitle:resolutionArray.firstObject forState:UIControlStateNormal]; self.resolutionView = [[UIView alloc] init]; self.resolutionView.hidden = YES; self.resolutionView.backgroundColor = RGBA(0, 0, 0, 0.7); [self addSubview:self.resolutionView]; [self.resolutionView mas_makeConstraints:^(MASConstraintMaker *make) { make.width.mas_equalTo(40); make.height.mas_equalTo(25*resolutionArray.count); make.leading.equalTo(self.resolutionBtn.mas_leading).offset(0); make.top.equalTo(self.resolutionBtn.mas_bottom).offset(0); }]; for (NSInteger i = 0 ; i < resolutionArray.count; i++) { UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.layer.borderColor = [UIColor whiteColor].CGColor; btn.layer.borderWidth = 0.5; btn.tag = 200+i; btn.frame = CGRectMake(0, 25*i, 40, 25); btn.titleLabel.font = [UIFont systemFontOfSize:12]; [btn setTitle:resolutionArray[i] forState:UIControlStateNormal]; if (i == 0) { self.resoultionCurrentBtn = btn; btn.selected = YES; btn.backgroundColor = RGBA(86, 143, 232, 1); } [self.resolutionView addSubview:btn]; [btn addTarget:self action:@selector(changeResolution:) forControlEvents:UIControlEventTouchUpInside]; } } - (void)sl_playerPlayBtnState:(BOOL)state { self.startBtn.selected = state; } - (void)sl_playerLockBtnState:(BOOL)state { self.lockBtn.selected = state; } - (void)sl_playerDownloadBtnState:(BOOL)state { self.downLoadBtn.enabled = state; } @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/SLPlayerControlViewDelagate.h ================================================ // // SLPlayerControlViewDelagate.h // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // @protocol SLPlayerControlViewDelagate @optional - (void)sl_controlView:(UIView *)controlView backAction:(UIButton *)sender; - (void)sl_controlView:(UIView *)controlView closeAction:(UIButton *)sender; - (void)sl_controlView:(UIView *)controlView playAction:(UIButton *)sender; - (void)sl_controlView:(UIView *)controlView fullScreenAction:(UIButton *)sender; - (void)sl_controlView:(UIView *)controlView lockScreenAction:(UIButton *)sender; - (void)sl_controlView:(UIView *)controlView repeatPlayAction:(UIButton *)sender; - (void)sl_controlView:(UIView *)controlView cneterPlayAction:(UIButton *)sender; - (void)sl_controlView:(UIView *)controlView failAction:(UIButton *)sender; - (void)sl_controlView:(UIView *)controlView downloadVideoAction:(UIButton *)sender; - (void)sl_controlView:(UIView *)controlView resolutionAction:(UIButton *)sender; - (void)sl_controlView:(UIView *)controlView progressSliderTap:(CGFloat)value; - (void)sl_controlView:(UIView *)controlView progressSliderTouchBegan:(UISlider *)slider; - (void)sl_controlView:(UIView *)controlView progressSliderValueChanged:(UISlider *)slider; - (void)sl_controlView:(UIView *)controlView progressSliderTouchEnded:(UISlider *)slider; - (void)sl_controlViewWillShow:(UIView *)controlView isFullscreen:(BOOL)fullscreen; - (void)sl_controlViewWillHidden:(UIView *)controlView isFullscreen:(BOOL)fullscreen; @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/SLPlayerModel.h ================================================ // // SLPlayerModel.h // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import #import @interface SLPlayerModel : NSObject @property (nonatomic, copy ) NSString *title; @property (nonatomic, strong) NSURL *videoURL; @property (nonatomic, strong) UIImage *placeholderImage; @property (nonatomic, weak ) UIView *fatherView; @property (nonatomic, copy ) NSString *placeholderImageURLString; @property (nonatomic, strong) NSDictionary *resolutionDic; @property (nonatomic, assign) NSInteger seekTime; @property (nonatomic, strong) UIScrollView *scrollView; @property (nonatomic, strong) NSIndexPath *indexPath; @property (nonatomic, assign) NSInteger fatherViewTag; @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/SLPlayerModel.m ================================================ // // SLPlayerModel.m // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import "SLPlayerModel.h" @implementation SLPlayerModel @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/SLPlayerView.h ================================================ // // SLPlayerView.h // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import #import "SLPlayerModel.h" #import "SLPlayerControlViewDelagate.h" @protocol SLPlayerDelegate @optional - (void)sl_playerBackAction; - (void)sl_playerDownload:(NSString *)url; - (void)sl_playerControlViewWillShow:(UIView *)controlView isFullscreen:(BOOL)fullscreen; - (void)sl_playerControlViewWillHidden:(UIView *)controlView isFullscreen:(BOOL)fullscreen; @end typedef NS_ENUM(NSInteger, SLPlayerLayerGravity) { SLPlayerLayerGravityResize, SLPlayerLayerGravityResizeAspect, SLPlayerLayerGravityResizeAspectFill }; typedef NS_ENUM(NSInteger, SLPlayerState) { SLPlayerStateFailed, SLPlayerStateBuffering, SLPlayerStatePlaying, SLPlayerStateStopped, SLPlayerStatePause }; @interface SLPlayerView : UIView @property (nonatomic, assign) SLPlayerLayerGravity playerLayerGravity; @property (nonatomic, assign) BOOL hasDownload; @property (nonatomic, assign) BOOL hasPreviewView; @property (nonatomic, weak) id delegate; @property (nonatomic, assign, readonly) BOOL isPauseByUser; @property (nonatomic, assign, readonly) SLPlayerState state; @property (nonatomic, assign) BOOL mute; @property (nonatomic, assign) BOOL stopPlayWhileCellNotVisable; @property (nonatomic, assign) BOOL cellPlayerOnCenter; @property (nonatomic, assign) BOOL playerPushedOrPresented; @property (nonatomic, strong) NSURL *videoURL; @property (nonatomic, strong) UIScrollView *scrollView; @property (nonatomic, strong) NSIndexPath *indexPath; @property (nonatomic, assign) NSInteger fatherViewTag; @property (nonatomic, strong) UIView *controlView; @property (nonatomic, weak) UIView *fatherView; + (instancetype)sharedPlayerView; - (void)playerControlView:(UIView *)controlView playerModel:(SLPlayerModel *)playerModel; - (void)playWithControllView; - (void)playWithVideoURL:(NSURL*)videoURl scrollView:(UIScrollView*)scrollView indexPath:(NSIndexPath*)indexPath fatherViewTag:(NSInteger)fatherViewTag; - (void)playerModel:(SLPlayerModel *)playerModel; - (void)autoPlayTheVideo; - (void)resetPlayer; - (void)resetToPlayNewVideo:(SLPlayerModel *)playerModel; - (void)play; - (void)pause; @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/SLPlayerView.m ================================================ // // SLPlayerView.m // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import "SLPlayerView.h" #import #import #import "UIView+ControlView.h" #define CellPlayerFatherViewTag 200 #pragma clang diagnostic push #pragma clang diagnostic ignored"-Wdeprecated-declarations" typedef NS_ENUM(NSInteger, PanDirection){ PanDirectionHorizontalMoved, PanDirectionVerticalMoved }; @interface SLPlayerView () @property (nonatomic, strong) AVPlayer *player; @property (nonatomic, strong) AVPlayerItem *playerItem; @property (nonatomic, strong) AVURLAsset *urlAsset; @property (nonatomic, strong) AVAssetImageGenerator *imageGenerator; @property (nonatomic, strong) AVPlayerLayer *playerLayer; @property (nonatomic, strong) id timeObserve; @property (nonatomic, strong) UISlider *volumeViewSlider; @property (nonatomic, assign) CGFloat sumTime; @property (nonatomic, assign) PanDirection panDirection; @property (nonatomic, assign) SLPlayerState state; @property (nonatomic, assign) BOOL isFullScreen; @property (nonatomic, assign) BOOL isLocked; @property (nonatomic, assign) BOOL isVolume; @property (nonatomic, assign) BOOL isPauseByUser; @property (nonatomic, assign) BOOL isLocalVideo; @property (nonatomic, assign) CGFloat sliderLastValue; @property (nonatomic, assign) BOOL repeatToPlay; @property (nonatomic, assign) BOOL playDidEnd; @property (nonatomic, assign) BOOL didEnterBackground; @property (nonatomic, assign) BOOL isAutoPlay; @property (nonatomic, strong) UITapGestureRecognizer *singleTap; @property (nonatomic, strong) UITapGestureRecognizer *doubleTap; @property (nonatomic, strong) NSArray *videoURLArray; @property (nonatomic, strong) UIImage *thumbImg; @property (nonatomic, strong) SLBrightnessView *brightnessView; @property (nonatomic, copy) NSString *videoGravity; #pragma mark - UITableViewCell PlayerView @property (nonatomic, assign) BOOL viewDisappear; @property (nonatomic, assign) BOOL isCellVideo; @property (nonatomic, assign) BOOL isBottomVideo; @property (nonatomic, assign) BOOL isChangeResolution; @property (nonatomic, assign) BOOL isDragged; @property (nonatomic, assign) CGPoint shrinkRightBottomPoint; @property (nonatomic, strong) UIPanGestureRecognizer *shrinkPanGesture; @property (nonatomic, strong) SLPlayerModel *playerModel; @property (nonatomic, assign) NSInteger seekTime; @property (nonatomic, strong) NSDictionary *resolutionDic; @end @implementation SLPlayerView #pragma mark - life Cycle - (instancetype)init { self = [super init]; if (self) { [self initializeThePlayer]; } return self; } - (void)awakeFromNib { [super awakeFromNib]; [self initializeThePlayer]; } - (void)initializeThePlayer { self.cellPlayerOnCenter = YES; } - (void)dealloc { self.playerItem = nil; self.scrollView = nil; SLPlayerShared.isLockScreen = NO; [self.controlView sl_playerCancelAutoFadeOutControlView]; [[NSNotificationCenter defaultCenter] removeObserver:self]; [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; if (self.timeObserve) { [self.player removeTimeObserver:self.timeObserve]; self.timeObserve = nil; } } - (void)resetToPlayNewURL { self.repeatToPlay = YES; [self resetPlayer]; } #pragma mark - 观察者、通知 - (void)addNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground) name:UIApplicationWillResignActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterPlayground) name:UIApplicationDidBecomeActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) name:AVAudioSessionRouteChangeNotification object:nil]; [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onDeviceOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onStatusBarOrientationChange) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; } #pragma mark - layoutSubviews - (void)layoutSubviews { [super layoutSubviews]; self.playerLayer.frame = self.bounds; } #pragma mark - Public Method + (instancetype)sharedPlayerView { static SLPlayerView *playerView = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ playerView = [[SLPlayerView alloc] init]; }); return playerView; } - (void)playerControlView:(UIView *)controlView playerModel:(SLPlayerModel *)playerModel { if (!controlView) { SLPlayerControlView *defaultControlView = [[SLPlayerControlView alloc] init]; self.controlView = defaultControlView; } else { self.controlView = controlView; } self.playerModel = playerModel; } - (void)playWithVideoURL:(NSURL*)videoURl scrollView:(UIScrollView*)scrollView indexPath:(NSIndexPath*)indexPath fatherViewTag:(NSInteger)fatherViewTag{ self.seekTime = 0; self.videoURL = videoURl; if (scrollView && indexPath && videoURl) { NSCAssert(fatherViewTag, @"请指定playerViews所在的faterViewTag"); [self cellVideoWithScrollView:scrollView AtIndexPath:indexPath]; if ([scrollView isKindOfClass:[UITableView class]]) { UITableView *tableView = (UITableView *)scrollView; UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; UIView *fatherView = [cell.contentView viewWithTag:fatherViewTag]; [self addPlayerToFatherView:fatherView]; } else if ([scrollView isKindOfClass:[UICollectionView class]]) { UICollectionView *collectionView = (UICollectionView *)scrollView; UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; UIView *fatherView = [cell.contentView viewWithTag:fatherViewTag]; [self addPlayerToFatherView:fatherView]; } } } - (void)playWithControllView{ if (self.scrollView && self.indexPath && self.videoURL) { NSCAssert(self.fatherViewTag, @"请指定playerViews所在的faterViewTag"); [self cellVideoWithScrollView:self.scrollView AtIndexPath:self.indexPath]; if ([self.scrollView isKindOfClass:[UITableView class]]) { UITableView *tableView = (UITableView *)self.scrollView; UITableViewCell *cell = [tableView cellForRowAtIndexPath:self.indexPath]; UIView *fatherView = [cell.contentView viewWithTag:self.fatherViewTag]; [self addPlayerToFatherView:fatherView]; } else if ([self.scrollView isKindOfClass:[UICollectionView class]]) { UICollectionView *collectionView = (UICollectionView *)self.scrollView; UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:self.indexPath]; UIView *fatherView = [cell.contentView viewWithTag:self.fatherViewTag]; [self addPlayerToFatherView:fatherView]; } } } - (void)setPlayerModel:(SLPlayerModel *)playerModel { _playerModel = playerModel; self.seekTime = 0; self.videoURL = playerModel.videoURL; if (playerModel.scrollView && playerModel.indexPath && playerModel.videoURL) { NSCAssert(playerModel.fatherViewTag, @"请指定playerViews所在的faterViewTag"); [self cellVideoWithScrollView:playerModel.scrollView AtIndexPath:playerModel.indexPath]; if ([self.scrollView isKindOfClass:[UITableView class]]) { UITableView *tableView = (UITableView *)playerModel.scrollView; UITableViewCell *cell = [tableView cellForRowAtIndexPath:playerModel.indexPath]; UIView *fatherView = [cell.contentView viewWithTag:playerModel.fatherViewTag]; [self addPlayerToFatherView:fatherView]; } else if ([self.scrollView isKindOfClass:[UICollectionView class]]) { UICollectionView *collectionView = (UICollectionView *)playerModel.scrollView; UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:playerModel.indexPath]; UIView *fatherView = [cell.contentView viewWithTag:playerModel.fatherViewTag]; [self addPlayerToFatherView:fatherView]; } } else { NSCAssert(playerModel.fatherView, @"请指定playerView的faterView"); [self addPlayerToFatherView:playerModel.fatherView]; } } - (void)playerModel:(SLPlayerModel *)playerModel { [self playerControlView:nil playerModel:playerModel]; } - (void)autoPlayTheVideo { [self configSLPlayer]; } - (void)addPlayerToFatherView:(UIView *)view { if (view) { [self removeFromSuperview]; [view addSubview:self]; [self mas_remakeConstraints:^(MASConstraintMaker *make) { make.edges.mas_offset(UIEdgeInsetsZero); }]; } } - (void)resetPlayer { self.playDidEnd = NO; self.playerItem = nil; self.didEnterBackground = NO; self.seekTime = 0; self.isAutoPlay = NO; if (self.timeObserve) { [self.player removeTimeObserver:self.timeObserve]; self.timeObserve = nil; } [[NSNotificationCenter defaultCenter] removeObserver:self]; [self pause]; [self.playerLayer removeFromSuperlayer]; self.imageGenerator = nil; self.player = nil; if (self.isChangeResolution) { [self.controlView sl_playerResetControlViewForResolution]; self.isChangeResolution = NO; }else { [self.controlView sl_playerResetControlView]; } self.controlView = nil; self.isBottomVideo = NO; if (self.isCellVideo && !self.repeatToPlay) { self.viewDisappear = YES; self.isCellVideo = NO; self.scrollView = nil; self.indexPath = nil; } } - (void)resetToPlayNewVideo:(SLPlayerModel *)playerModel { self.repeatToPlay = YES; [self resetPlayer]; self.playerModel = playerModel; [self configSLPlayer]; } - (void)play{ [self.controlView sl_playerPlayBtnState:YES]; if (self.state ==SLPlayerStatePause) { self.state = SLPlayerStatePlaying; } self.isPauseByUser = NO; [_player play]; } - (void)pause { [self.controlView sl_playerPlayBtnState:NO]; if (self.state == SLPlayerStatePlaying) { self.state = SLPlayerStatePause;} self.isPauseByUser = YES; [_player pause]; } #pragma mark - Private Method - (void)cellVideoWithScrollView:(UIScrollView *)scrollView AtIndexPath:(NSIndexPath *)indexPath { if (!self.viewDisappear && self.playerItem) { [self resetPlayer]; } self.isCellVideo = YES; self.viewDisappear = NO; self.scrollView = scrollView; self.indexPath = indexPath; [self.controlView sl_playerCellPlay]; self.shrinkPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(shrikPanAction:)]; self.shrinkPanGesture.delegate = self; [self addGestureRecognizer:self.shrinkPanGesture]; } - (void)configSLPlayer { self.urlAsset = [AVURLAsset assetWithURL:self.videoURL]; self.playerItem = [AVPlayerItem playerItemWithAsset:self.urlAsset]; self.player = [AVPlayer playerWithPlayerItem:self.playerItem]; self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; self.backgroundColor = [UIColor blackColor]; self.playerLayer.videoGravity = self.videoGravity; self.isAutoPlay = YES; [self createTimer]; [self configureVolume]; if ([self.videoURL.scheme isEqualToString:@"file"]) { self.state = SLPlayerStatePlaying; self.isLocalVideo = YES; [self.controlView sl_playerDownloadBtnState:NO]; } else { self.state = SLPlayerStateBuffering; self.isLocalVideo = NO; [self.controlView sl_playerDownloadBtnState:YES]; } [self play]; self.isPauseByUser = NO; } - (void)createGesture { self.singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(singleTapAction:)]; self.singleTap.delegate = self; self.singleTap.numberOfTouchesRequired = 1; self.singleTap.numberOfTapsRequired = 1; [self addGestureRecognizer:self.singleTap]; self.doubleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(doubleTapAction:)]; self.doubleTap.delegate = self; self.doubleTap.numberOfTouchesRequired = 1; self.doubleTap.numberOfTapsRequired = 2; [self addGestureRecognizer:self.doubleTap]; [self.singleTap setDelaysTouchesBegan:YES]; [self.doubleTap setDelaysTouchesBegan:YES]; [self.singleTap requireGestureRecognizerToFail:self.doubleTap]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { if (self.isAutoPlay) { UITouch *touch = [touches anyObject]; if(touch.tapCount == 1) { [self performSelector:@selector(singleTapAction:) withObject:@(NO) ]; } else if (touch.tapCount == 2) { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(singleTapAction:) object:nil]; [self doubleTapAction:touch.gestureRecognizers.lastObject]; } } } - (void)createTimer { __weak typeof(self) weakSelf = self; self.timeObserve = [self.player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, 1) queue:nil usingBlock:^(CMTime time){ AVPlayerItem *currentItem = weakSelf.playerItem; NSArray *loadedRanges = currentItem.seekableTimeRanges; if (loadedRanges.count > 0 && currentItem.duration.timescale != 0) { NSInteger currentTime = (NSInteger)CMTimeGetSeconds([currentItem currentTime]); CGFloat totalTime = (CGFloat)currentItem.duration.value / currentItem.duration.timescale; CGFloat value = CMTimeGetSeconds([currentItem currentTime]) / totalTime; [weakSelf.controlView sl_playerCurrentTime:currentTime totalTime:totalTime sliderValue:value]; } }]; } - (void)configureVolume { MPVolumeView *volumeView = [[MPVolumeView alloc] init]; _volumeViewSlider = nil; for (UIView *view in [volumeView subviews]){ if ([view.class.description isEqualToString:@"MPVolumeSlider"]){ _volumeViewSlider = (UISlider *)view; break; } } NSError *setCategoryError = nil; BOOL success = [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError]; if (!success) { /* handle the error in setCategoryError */ } } - (void)audioRouteChangeListenerCallback:(NSNotification*)notification { NSDictionary *interuptionDict = notification.userInfo; NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue]; switch (routeChangeReason) { case AVAudioSessionRouteChangeReasonNewDeviceAvailable: break; case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: { [self play]; } break; case AVAudioSessionRouteChangeReasonCategoryChange: NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange"); break; } } #pragma mark - KVO - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (object == self.player.currentItem) { if ([keyPath isEqualToString:@"status"]) { if (self.player.currentItem.status == AVPlayerItemStatusReadyToPlay) { [self setNeedsLayout]; [self layoutIfNeeded]; [self.layer insertSublayer:self.playerLayer atIndex:0]; self.state = SLPlayerStatePlaying; UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panDirection:)]; panRecognizer.delegate = self; [panRecognizer setMaximumNumberOfTouches:1]; [panRecognizer setDelaysTouchesBegan:YES]; [panRecognizer setDelaysTouchesEnded:YES]; [panRecognizer setCancelsTouchesInView:YES]; [self addGestureRecognizer:panRecognizer]; if (self.seekTime) { [self seekToTime:self.seekTime completionHandler:nil]; } self.player.muted = self.mute; } else if (self.player.currentItem.status == AVPlayerItemStatusFailed) { self.state = SLPlayerStateFailed; } } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) { NSTimeInterval timeInterval = [self availableDuration]; CMTime duration = self.playerItem.duration; CGFloat totalDuration = CMTimeGetSeconds(duration); [self.controlView sl_playerSetProgress:timeInterval / totalDuration]; } else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) { if (self.playerItem.playbackBufferEmpty) { self.state = SLPlayerStateBuffering; [self bufferingSomeSecond]; } } else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) { if (self.playerItem.playbackLikelyToKeepUp && self.state == SLPlayerStateBuffering){ self.state = SLPlayerStatePlaying; } } } else if (object == self.scrollView) { if ([keyPath isEqualToString:kSLPlayerViewContentOffset]) { if (self.isFullScreen) { return; } [self handleScrollOffsetWithDict:change]; } } } #pragma mark - tableViewContentOffset - (void)handleScrollOffsetWithDict:(NSDictionary*)dict { if ([self.scrollView isKindOfClass:[UITableView class]]) { UITableView *tableView = (UITableView *)self.scrollView; UITableViewCell *cell = [tableView cellForRowAtIndexPath:self.indexPath]; NSArray *visableCells = tableView.visibleCells; if ([visableCells containsObject:cell]) { [self updatePlayerViewToCell]; } else { if (self.stopPlayWhileCellNotVisable) { [self resetPlayer]; } else { [self updatePlayerViewToBottom]; } } } else if ([self.scrollView isKindOfClass:[UICollectionView class]]) { UICollectionView *collectionView = (UICollectionView *)self.scrollView; UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:self.indexPath]; if ( [collectionView.visibleCells containsObject:cell]) { [self updatePlayerViewToCell]; } else { if (self.stopPlayWhileCellNotVisable) { [self resetPlayer]; } else { [self updatePlayerViewToBottom]; } } } } - (void)updatePlayerViewToBottom { if (self.isBottomVideo) { return; } self.isBottomVideo = YES; if (self.playDidEnd) { self.repeatToPlay = NO; self.playDidEnd = NO; [self resetPlayer]; return; } [[UIApplication sharedApplication].keyWindow addSubview:self]; if (CGPointEqualToPoint(self.shrinkRightBottomPoint, CGPointZero)) { self.shrinkRightBottomPoint = CGPointMake(10, self.scrollView.contentInset.bottom+10); } else { [self setShrinkRightBottomPoint:self.shrinkRightBottomPoint]; } [self.controlView sl_playerBottomShrinkPlay]; } - (void)updatePlayerViewToCell { if (!self.isBottomVideo) { return; } self.isBottomVideo = NO; [self setOrientationPortraitConstraint]; [self.controlView sl_playerCellPlay]; } - (void)setOrientationLandscapeConstraint:(UIInterfaceOrientation)orientation { [self toOrientation:orientation]; self.isFullScreen = YES; } - (void)setOrientationPortraitConstraint { if (self.isCellVideo) { if ([self.scrollView isKindOfClass:[UITableView class]]) { UITableView *tableView = (UITableView *)self.scrollView; UITableViewCell *cell = [tableView cellForRowAtIndexPath:self.indexPath]; self.isBottomVideo = NO; if (![tableView.visibleCells containsObject:cell]) { [self updatePlayerViewToBottom]; } else { UIView *fatherView = [cell.contentView viewWithTag:self.playerModel.fatherViewTag]; [self addPlayerToFatherView:fatherView]; } } else if ([self.scrollView isKindOfClass:[UICollectionView class]]) { UICollectionView *collectionView = (UICollectionView *)self.scrollView; UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:self.indexPath]; self.isBottomVideo = NO; if (![collectionView.visibleCells containsObject:cell]) { [self updatePlayerViewToBottom]; } else { UIView *fatherView = [cell viewWithTag:self.playerModel.fatherViewTag]; [self addPlayerToFatherView:fatherView]; } } } else { [self addPlayerToFatherView:self.playerModel.fatherView]; } [self toOrientation:UIInterfaceOrientationPortrait]; self.isFullScreen = NO; } - (void)toOrientation:(UIInterfaceOrientation)orientation { UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation; if (currentOrientation == orientation) { return; } if (orientation != UIInterfaceOrientationPortrait) {// if (currentOrientation == UIInterfaceOrientationPortrait) { [self removeFromSuperview]; SLBrightnessView *brightnessView = [SLBrightnessView sharedBrightnessView]; [[UIApplication sharedApplication].keyWindow insertSubview:self belowSubview:brightnessView]; [self mas_remakeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(@(ScreenHeight)); make.height.equalTo(@(ScreenWidth)); make.center.equalTo([UIApplication sharedApplication].keyWindow); }]; } } [[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:NO]; [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:0.3]; self.transform = CGAffineTransformIdentity; self.transform = [self getTransformRotationAngle]; [UIView commitAnimations]; } - (CGAffineTransform)getTransformRotationAngle { UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if (orientation == UIInterfaceOrientationPortrait) { return CGAffineTransformIdentity; } else if (orientation == UIInterfaceOrientationLandscapeLeft){ return CGAffineTransformMakeRotation(-M_PI_2); } else if(orientation == UIInterfaceOrientationLandscapeRight){ return CGAffineTransformMakeRotation(M_PI_2); } return CGAffineTransformIdentity; } #pragma mark 屏幕转屏相关 - (void)interfaceOrientation:(UIInterfaceOrientation)orientation { if (orientation == UIInterfaceOrientationLandscapeRight || orientation == UIInterfaceOrientationLandscapeLeft) { [self setOrientationLandscapeConstraint:orientation]; } else if (orientation == UIInterfaceOrientationPortrait) { [self setOrientationPortraitConstraint]; } } - (void)onDeviceOrientationChange { if (!self.player) { return; } if (SLPlayerShared.isLockScreen) { return; } if (self.didEnterBackground) { return; }; if (self.playerPushedOrPresented) { return; } UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; UIInterfaceOrientation interfaceOrientation = (UIInterfaceOrientation)orientation; if (orientation == UIDeviceOrientationFaceUp || orientation == UIDeviceOrientationFaceDown || orientation == UIDeviceOrientationUnknown ) { return; } switch (interfaceOrientation) { case UIInterfaceOrientationPortraitUpsideDown:{ } break; case UIInterfaceOrientationPortrait:{ if (self.isFullScreen) { [self toOrientation:UIInterfaceOrientationPortrait]; } } break; case UIInterfaceOrientationLandscapeLeft:{ if (self.isFullScreen == NO) { [self toOrientation:UIInterfaceOrientationLandscapeLeft]; self.isFullScreen = YES; } else { [self toOrientation:UIInterfaceOrientationLandscapeLeft]; } } break; case UIInterfaceOrientationLandscapeRight:{ if (self.isFullScreen == NO) { [self toOrientation:UIInterfaceOrientationLandscapeRight]; self.isFullScreen = YES; } else { [self toOrientation:UIInterfaceOrientationLandscapeRight]; } } break; default: break; } } - (void)onStatusBarOrientationChange { if (!self.didEnterBackground) { UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation; if (currentOrientation == UIInterfaceOrientationPortrait) { [self setOrientationPortraitConstraint]; if (self.cellPlayerOnCenter) { if ([self.scrollView isKindOfClass:[UITableView class]]) { UITableView *tableView = (UITableView *)self.scrollView; [tableView scrollToRowAtIndexPath:self.indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO]; } else if ([self.scrollView isKindOfClass:[UICollectionView class]]) { UICollectionView *collectionView = (UICollectionView *)self.scrollView; [collectionView scrollToItemAtIndexPath:self.indexPath atScrollPosition:UICollectionViewScrollPositionTop animated:NO]; } } [self.brightnessView removeFromSuperview]; [[UIApplication sharedApplication].keyWindow addSubview:self.brightnessView]; [self.brightnessView mas_remakeConstraints:^(MASConstraintMaker *make) { make.width.height.mas_equalTo(155); make.leading.mas_equalTo((ScreenWidth-155)/2); make.top.mas_equalTo((ScreenHeight-155)/2); }]; } else { if (currentOrientation == UIInterfaceOrientationLandscapeRight) { [self toOrientation:UIInterfaceOrientationLandscapeRight]; } else if (currentOrientation == UIDeviceOrientationLandscapeLeft){ [self toOrientation:UIInterfaceOrientationLandscapeLeft]; } [self.brightnessView removeFromSuperview]; [self addSubview:self.brightnessView]; [self.brightnessView mas_remakeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self); make.width.height.mas_equalTo(155); }]; } } } - (void)lockScreenAction:(UIButton *)sender { sender.selected = !sender.selected; self.isLocked = sender.selected; SLPlayerShared.isLockScreen = sender.selected; } - (void)unLockTheScreen { SLPlayerShared.isLockScreen = NO; [self.controlView sl_playerLockBtnState:NO]; self.isLocked = NO; [self interfaceOrientation:UIInterfaceOrientationPortrait]; } #pragma mark - 缓冲较差时候 - (void)bufferingSomeSecond { self.state = SLPlayerStateBuffering; __block BOOL isBuffering = NO; if (isBuffering) return; isBuffering = YES; [self.player pause]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ if (self.isPauseByUser) { isBuffering = NO; return; } [self play]; isBuffering = NO; if (!self.playerItem.isPlaybackLikelyToKeepUp) { [self bufferingSomeSecond]; } }); } #pragma mark - 计算缓冲进度 - (NSTimeInterval)availableDuration { NSArray *loadedTimeRanges = [[_player currentItem] loadedTimeRanges]; CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue]; float startSeconds = CMTimeGetSeconds(timeRange.start); float durationSeconds = CMTimeGetSeconds(timeRange.duration); NSTimeInterval result = startSeconds + durationSeconds; return result; } #pragma mark - Action - (void)singleTapAction:(UIGestureRecognizer *)gesture { if ([gesture isKindOfClass:[NSNumber class]] && ![(id)gesture boolValue]) { [self _fullScreenAction]; return; } if (gesture.state == UIGestureRecognizerStateRecognized) { if (self.isBottomVideo && !self.isFullScreen) { [self _fullScreenAction]; } else { if (self.playDidEnd) { return; } else { [self.controlView sl_playerShowOrHideControlView]; } } } } - (void)doubleTapAction:(UIGestureRecognizer *)gesture { if (self.playDidEnd) {return;} [self.controlView sl_playerShowControlView]; if (self.isPauseByUser) { [self play]; } else { [self pause]; } if (!self.isAutoPlay) { self.isAutoPlay = YES; [self configSLPlayer]; } } - (void)shrikPanAction:(UIPanGestureRecognizer *)gesture { CGPoint point = [gesture locationInView:[UIApplication sharedApplication].keyWindow]; SLPlayerView *view = (SLPlayerView *)gesture.view; const CGFloat width = view.frame.size.width; const CGFloat height = view.frame.size.height; const CGFloat distance = 10; if (gesture.state == UIGestureRecognizerStateEnded) { if (point.x < width/2) { point.x = width/2 + distance; } else if (point.x > ScreenWidth - width/2) { point.x = ScreenWidth - width/2 - distance; } if (point.y < height/2) { point.y = height/2 + distance; } else if (point.y > ScreenHeight - height/2) { point.y = ScreenHeight - height/2 - distance; } [UIView animateWithDuration:0.5 animations:^{ view.center = point; self.shrinkRightBottomPoint = CGPointMake(ScreenWidth - view.frame.origin.x - width, ScreenHeight - view.frame.origin.y - height); }]; } else { view.center = point; self.shrinkRightBottomPoint = CGPointMake(ScreenWidth - view.frame.origin.x- view.frame.size.width, ScreenHeight - view.frame.origin.y-view.frame.size.height); } } - (void)_fullScreenAction { if (SLPlayerShared.isLockScreen) { [self unLockTheScreen]; return; } if (self.isFullScreen) { [self interfaceOrientation:UIInterfaceOrientationPortrait]; self.isFullScreen = NO; return; } else { UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; if (orientation == UIDeviceOrientationLandscapeRight) { [self interfaceOrientation:UIInterfaceOrientationLandscapeLeft]; } else { [self interfaceOrientation:UIInterfaceOrientationLandscapeRight]; } self.isFullScreen = YES; } } #pragma mark - NSNotification Action - (void)moviePlayDidEnd:(NSNotification *)notification { self.state = SLPlayerStateStopped; if (self.isBottomVideo && !self.isFullScreen) { self.repeatToPlay = NO; self.playDidEnd = NO; [self resetPlayer]; } else { if (!self.isDragged) { self.playDidEnd = YES; [self.controlView sl_playerPlayEnd]; } } } - (void)appDidEnterBackground { self.didEnterBackground = YES; SLPlayerShared.isLockScreen = YES; [_player pause]; self.state = SLPlayerStatePause; } - (void)appDidEnterPlayground { self.didEnterBackground = NO; SLPlayerShared.isLockScreen = self.isLocked; if (!self.isPauseByUser) { self.state = SLPlayerStatePlaying; self.isPauseByUser = NO; [self play]; } } - (void)seekToTime:(NSInteger)dragedSeconds completionHandler:(void (^)(BOOL finished))completionHandler { if (self.player.currentItem.status == AVPlayerItemStatusReadyToPlay) { [self.controlView sl_playerActivity:YES]; [self.player pause]; CMTime dragedCMTime = CMTimeMake(dragedSeconds, 1); __weak typeof(self) weakSelf = self; [self.player seekToTime:dragedCMTime toleranceBefore:CMTimeMake(1,1) toleranceAfter:CMTimeMake(1,1) completionHandler:^(BOOL finished) { [weakSelf.controlView sl_playerActivity:NO]; if (completionHandler) { completionHandler(finished); } [weakSelf.player play]; weakSelf.seekTime = 0; weakSelf.isDragged = NO; [weakSelf.controlView sl_playerDraggedEnd]; if (!weakSelf.playerItem.isPlaybackLikelyToKeepUp && !weakSelf.isLocalVideo) { weakSelf.state = SLPlayerStateBuffering; } }]; } } #pragma mark - UIPanGestureRecognizer手势方法 - (void)panDirection:(UIPanGestureRecognizer *)pan { CGPoint locationPoint = [pan locationInView:self]; CGPoint veloctyPoint = [pan velocityInView:self]; switch (pan.state) { case UIGestureRecognizerStateBegan:{ CGFloat x = fabs(veloctyPoint.x); CGFloat y = fabs(veloctyPoint.y); if (x > y) { self.panDirection = PanDirectionHorizontalMoved; CMTime time = self.player.currentTime; self.sumTime = time.value/time.timescale; } else if (x < y){ self.panDirection = PanDirectionVerticalMoved; if (locationPoint.x > self.bounds.size.width / 2) { self.isVolume = YES; }else { self.isVolume = NO; } } break; } case UIGestureRecognizerStateChanged:{ switch (self.panDirection) { case PanDirectionHorizontalMoved:{ [self horizontalMoved:veloctyPoint.x]; break; } case PanDirectionVerticalMoved:{ [self verticalMoved:veloctyPoint.y]; break; } default: break; } break; } case UIGestureRecognizerStateEnded:{ switch (self.panDirection) { case PanDirectionHorizontalMoved:{ self.isPauseByUser = NO; [self seekToTime:self.sumTime completionHandler:nil]; self.sumTime = 0; break; } case PanDirectionVerticalMoved:{ self.isVolume = NO; break; } default: break; } break; } default: break; } } - (void)verticalMoved:(CGFloat)value { self.isVolume ? (self.volumeViewSlider.value -= value / 10000) : ([UIScreen mainScreen].brightness -= value / 10000); } - (void)horizontalMoved:(CGFloat)value { self.sumTime += value / 200; CMTime totalTime = self.playerItem.duration; CGFloat totalMovieDuration = (CGFloat)totalTime.value/totalTime.timescale; if (self.sumTime > totalMovieDuration) { self.sumTime = totalMovieDuration;} if (self.sumTime < 0) { self.sumTime = 0; } BOOL style = false; if (value > 0) { style = YES; } if (value < 0) { style = NO; } if (value == 0) { return; } self.isDragged = YES; [self.controlView sl_playerDraggedTime:self.sumTime totalTime:totalMovieDuration isForward:style hasPreview:NO]; } - (NSString *)durationStringWithTime:(int)time { NSString *min = [NSString stringWithFormat:@"%02d",time / 60]; NSString *sec = [NSString stringWithFormat:@"%02d",time % 60]; return [NSString stringWithFormat:@"%@:%@", min, sec]; } #pragma mark - UIGestureRecognizerDelegate - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if (gestureRecognizer == self.shrinkPanGesture && self.isCellVideo) { if (!self.isBottomVideo || self.isFullScreen) { return NO; } } if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && gestureRecognizer != self.shrinkPanGesture) { if ((self.isCellVideo && !self.isFullScreen) || self.playDidEnd || self.isLocked){ return NO; } } if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) { if (self.isBottomVideo && !self.isFullScreen) { return NO; } } if ([touch.view isKindOfClass:[UISlider class]]) { return NO; } return YES; } #pragma mark - Setter - (void)setVideoURL:(NSURL *)videoURL { _videoURL = videoURL; self.repeatToPlay = NO; self.playDidEnd = NO; [self addNotifications]; self.isPauseByUser = YES; [self createGesture]; } - (void)setState:(SLPlayerState)state { _state = state; [self.controlView sl_playerActivity:state == SLPlayerStateBuffering]; if (state == SLPlayerStatePlaying || state == SLPlayerStateBuffering) { [self.controlView sl_playerItemPlaying]; } else if (state == SLPlayerStateFailed) { NSError *error = [self.playerItem error]; [self.controlView sl_playerItemStatusFailed:error]; } } - (void)setPlayerItem:(AVPlayerItem *)playerItem { if (_playerItem == playerItem) {return;} if (_playerItem) { [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:_playerItem]; [_playerItem removeObserver:self forKeyPath:@"status"]; [_playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"]; [_playerItem removeObserver:self forKeyPath:@"playbackBufferEmpty"]; [_playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"]; } _playerItem = playerItem; if (playerItem) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem]; [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil]; [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil]; [playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil]; [playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil]; } } - (void)setScrollView:(UIScrollView *)scrollView { if (_scrollView == scrollView) { return; } if (_scrollView) { [_scrollView removeObserver:self forKeyPath:kSLPlayerViewContentOffset]; } _scrollView = scrollView; if (scrollView) { [scrollView addObserver:self forKeyPath:kSLPlayerViewContentOffset options:NSKeyValueObservingOptionNew context:nil]; } } - (void)setPlayerLayerGravity:(SLPlayerLayerGravity)playerLayerGravity { _playerLayerGravity = playerLayerGravity; switch (playerLayerGravity) { case SLPlayerLayerGravityResize: self.playerLayer.videoGravity = AVLayerVideoGravityResize; self.videoGravity = AVLayerVideoGravityResize; break; case SLPlayerLayerGravityResizeAspect: self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect; self.videoGravity = AVLayerVideoGravityResizeAspect; break; case SLPlayerLayerGravityResizeAspectFill: self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; self.videoGravity = AVLayerVideoGravityResizeAspectFill; break; default: break; } } - (void)setHasDownload:(BOOL)hasDownload { _hasDownload = hasDownload; [self.controlView sl_playerHasDownloadFunction:hasDownload]; } - (void)setResolutionDic:(NSDictionary *)resolutionDic { _resolutionDic = resolutionDic; self.videoURLArray = [resolutionDic allValues]; } - (void)setControlView:(UIView *)controlView { if (_controlView) { return; } _controlView = controlView; controlView.delegate = self; [self addSubview:controlView]; [controlView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(UIEdgeInsetsZero); }]; } - (void)setShrinkRightBottomPoint:(CGPoint)shrinkRightBottomPoint { _shrinkRightBottomPoint = shrinkRightBottomPoint; CGFloat width = ScreenWidth*0.5-20; CGFloat height = (self.bounds.size.height / self.bounds.size.width); [self mas_remakeConstraints:^(MASConstraintMaker *make) { make.width.mas_equalTo(width); make.height.equalTo(self.mas_width).multipliedBy(height); make.trailing.mas_equalTo(-shrinkRightBottomPoint.x); make.bottom.mas_equalTo(-shrinkRightBottomPoint.y); }]; } - (void)setPlayerPushedOrPresented:(BOOL)playerPushedOrPresented { _playerPushedOrPresented = playerPushedOrPresented; if (playerPushedOrPresented) { [self pause]; } else { [self play]; } } #pragma mark - Getter - (AVAssetImageGenerator *)imageGenerator { if (!_imageGenerator) { _imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:self.urlAsset]; } return _imageGenerator; } - (SLBrightnessView *)brightnessView { if (!_brightnessView) { _brightnessView = [SLBrightnessView sharedBrightnessView]; } return _brightnessView; } - (NSString *)videoGravity { if (!_videoGravity) { _videoGravity = AVLayerVideoGravityResizeAspect; } return _videoGravity; } #pragma mark - SLPlayerControlViewDelegate - (void)sl_controlView:(UIView *)controlView playAction:(UIButton *)sender { self.isPauseByUser = !self.isPauseByUser; if (self.isPauseByUser) { [self pause]; if (self.state == SLPlayerStatePlaying) { self.state = SLPlayerStatePause;} } else { [self play]; if (self.state == SLPlayerStatePause) { self.state = SLPlayerStatePlaying; } } if (!self.isAutoPlay) { self.isAutoPlay = YES; [self configSLPlayer]; } } - (void)sl_controlView:(UIView *)controlView backAction:(UIButton *)sender { if (SLPlayerShared.isLockScreen) { [self unLockTheScreen]; } else { if (!self.isFullScreen) { [self pause]; if ([self.delegate respondsToSelector:@selector(sl_playerBackAction)]) { [self.delegate sl_playerBackAction]; } } else { [self interfaceOrientation:UIInterfaceOrientationPortrait]; } } } - (void)sl_controlView:(UIView *)controlView closeAction:(UIButton *)sender { [self resetPlayer]; [self removeFromSuperview]; } - (void)sl_controlView:(UIView *)controlView fullScreenAction:(UIButton *)sender { [self _fullScreenAction]; } - (void)sl_controlView:(UIView *)controlView lockScreenAction:(UIButton *)sender { self.isLocked = sender.selected; SLPlayerShared.isLockScreen = sender.selected; } - (void)sl_controlView:(UIView *)controlView cneterPlayAction:(UIButton *)sender { [self configSLPlayer]; } - (void)sl_controlView:(UIView *)controlView repeatPlayAction:(UIButton *)sender { self.playDidEnd = NO; self.repeatToPlay = NO; [self seekToTime:0 completionHandler:nil]; if ([self.videoURL.scheme isEqualToString:@"file"]) { self.state = SLPlayerStatePlaying; } else { self.state = SLPlayerStateBuffering; } } - (void)sl_controlView:(UIView *)controlView failAction:(UIButton *)sender { [self configSLPlayer]; } - (void)sl_controlView:(UIView *)controlView resolutionAction:(UIButton *)sender { NSInteger currentTime = (NSInteger)CMTimeGetSeconds([self.player currentTime]); NSString *videoStr = self.videoURLArray[sender.tag - 200]; NSURL *videoURL = [NSURL URLWithString:videoStr]; if ([videoURL isEqual:self.videoURL]) { return; } self.isChangeResolution = YES; [self resetToPlayNewURL]; self.videoURL = videoURL; self.seekTime = currentTime; [self autoPlayTheVideo]; } - (void)sl_controlView:(UIView *)controlView downloadVideoAction:(UIButton *)sender { NSString *urlStr = self.videoURL.absoluteString; if ([self.delegate respondsToSelector:@selector(sl_playerDownload:)]) { [self.delegate sl_playerDownload:urlStr]; } } - (void)sl_controlView:(UIView *)controlView progressSliderTap:(CGFloat)value { CGFloat total = (CGFloat)self.playerItem.duration.value / self.playerItem.duration.timescale; NSInteger dragedSeconds = floorf(total * value); [self.controlView sl_playerPlayBtnState:YES]; [self seekToTime:dragedSeconds completionHandler:^(BOOL finished) {}]; } - (void)sl_controlView:(UIView *)controlView progressSliderValueChanged:(UISlider *)slider { if (self.player.currentItem.status == AVPlayerItemStatusReadyToPlay) { self.isDragged = YES; BOOL style = false; CGFloat value = slider.value - self.sliderLastValue; if (value > 0) { style = YES; } if (value < 0) { style = NO; } if (value == 0) { return; } self.sliderLastValue = slider.value; CGFloat totalTime = (CGFloat)_playerItem.duration.value / _playerItem.duration.timescale; CGFloat dragedSeconds = floorf(totalTime * slider.value); CMTime dragedCMTime = CMTimeMake(dragedSeconds, 1); [controlView sl_playerDraggedTime:dragedSeconds totalTime:totalTime isForward:style hasPreview:self.isFullScreen ? self.hasPreviewView : NO]; if (totalTime > 0) { if (self.isFullScreen && self.hasPreviewView) { [self.imageGenerator cancelAllCGImageGeneration]; self.imageGenerator.appliesPreferredTrackTransform = YES; self.imageGenerator.maximumSize = CGSizeMake(100, 56); AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){ NSLog(@"%zd",result); if (result != AVAssetImageGeneratorSucceeded) { dispatch_async(dispatch_get_main_queue(), ^{ [controlView sl_playerDraggedTime:dragedSeconds sliderImage:self.thumbImg ? : SLPlayerImage(@"SLPlayer_loading_bgView")]; }); } else { self.thumbImg = [UIImage imageWithCGImage:im]; dispatch_async(dispatch_get_main_queue(), ^{ [controlView sl_playerDraggedTime:dragedSeconds sliderImage:self.thumbImg ? : SLPlayerImage(@"SLPlayer_loading_bgView")]; }); } }; [self.imageGenerator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:dragedCMTime]] completionHandler:handler]; } } else { slider.value = 0; } }else { slider.value = 0; } } - (void)sl_controlView:(UIView *)controlView progressSliderTouchEnded:(UISlider *)slider { if (self.player.currentItem.status == AVPlayerItemStatusReadyToPlay) { self.isPauseByUser = NO; self.isDragged = NO; CGFloat total = (CGFloat)_playerItem.duration.value / _playerItem.duration.timescale; NSInteger dragedSeconds = floorf(total * slider.value); [self seekToTime:dragedSeconds completionHandler:nil]; } } - (void)sl_controlViewWillShow:(UIView *)controlView isFullscreen:(BOOL)fullscreen { if ([self.delegate respondsToSelector:@selector(sl_playerControlViewWillShow:isFullscreen:)]) { [self.delegate sl_playerControlViewWillShow:controlView isFullscreen:fullscreen]; } } - (void)sl_controlViewWillHidden:(UIView *)controlView isFullscreen:(BOOL)fullscreen { if ([self.delegate respondsToSelector:@selector(sl_playerControlViewWillHidden:isFullscreen:)]) { [self.delegate sl_playerControlViewWillHidden:controlView isFullscreen:fullscreen]; } } #pragma clang diagnostic pop @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/UIView+ControlView.h ================================================ // // UIView+CustomControlView1.h // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import #import "SLPlayer.h" @interface UIView (ControlView) @property (nonatomic, weak) id delegate; - (void)sl_playerModel:(SLPlayerModel *)playerModel; - (void)sl_playerShowOrHideControlView; - (void)sl_playerShowControlView; - (void)sl_playerHideControlView; - (void)sl_playerResetControlView; - (void)sl_playerResetControlViewForResolution; - (void)sl_playerCancelAutoFadeOutControlView; - (void)sl_playerItemPlaying; - (void)sl_playerPlayEnd; - (void)sl_playerHasDownloadFunction:(BOOL)sender; - (void)sl_playerResolutionArray:(NSArray *)resolutionArray; - (void)sl_playerPlayBtnState:(BOOL)state; - (void)sl_playerLockBtnState:(BOOL)state; - (void)sl_playerDownloadBtnState:(BOOL)state; - (void)sl_playerActivity:(BOOL)animated; - (void)sl_playerDraggedTime:(NSInteger)draggedTime sliderImage:(UIImage *)image; - (void)sl_playerDraggedTime:(NSInteger)draggedTime totalTime:(NSInteger)totalTime isForward:(BOOL)forawrd hasPreview:(BOOL)preview; - (void)sl_playerDraggedEnd; - (void)sl_playerCurrentTime:(NSInteger)currentTime totalTime:(NSInteger)totalTime sliderValue:(CGFloat)value; - (void)sl_playerSetProgress:(CGFloat)progress; - (void)sl_playerItemStatusFailed:(NSError *)error; - (void)sl_playerBottomShrinkPlay; - (void)sl_playerCellPlay; @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/UIView+ControlView.m ================================================ // // UIView+CustomControlView1.m // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import "UIView+ControlView.h" #import @implementation UIView (ControlView) - (void)setDelegate:(id)delegate { objc_setAssociatedObject(self, @selector(delegate), delegate, OBJC_ASSOCIATION_ASSIGN); } - (id)delegate { return objc_getAssociatedObject(self, _cmd); } - (void)sl_playerModel:(SLPlayerModel *)playerModel {} - (void)sl_playerShowOrHideControlView {} - (void)sl_playerShowControlView {} - (void)sl_playerHideControlView {} - (void)sl_playerResetControlView {} - (void)sl_playerResetControlViewForResolution {} - (void)sl_playerCancelAutoFadeOutControlView {} - (void)sl_playerItemPlaying {} - (void)sl_playerPlayEnd {} - (void)sl_playerHasDownloadFunction:(BOOL)sender {} - (void)sl_playerDownloadBtnState:(BOOL)state {} - (void)sl_playerResolutionArray:(NSArray *)resolutionArray {} - (void)sl_playerPlayBtnState:(BOOL)state {} - (void)sl_playerLockBtnState:(BOOL)state {} - (void)sl_playerActivity:(BOOL)animated {} - (void)sl_playerDraggedTime:(NSInteger)draggedTime sliderImage:(UIImage *)image {} - (void)sl_playerDraggedTime:(NSInteger)draggedTime totalTime:(NSInteger)totalTime isForward:(BOOL)forawrd hasPreview:(BOOL)preview {} - (void)sl_playerDraggedEnd {} - (void)sl_playerCurrentTime:(NSInteger)currentTime totalTime:(NSInteger)totalTime sliderValue:(CGFloat)value {} - (void)sl_playerSetProgress:(CGFloat)progress {} - (void)sl_playerItemStatusFailed:(NSError *)error {} - (void)sl_playerBottomShrinkPlay {} - (void)sl_playerCellPlay {} @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/UIViewController+SDPlayerRotation.h ================================================ // // UIViewController+SDPlayerRotation.h // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import @interface UIViewController (SDPlayerRotation) @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SLPlayer/UIViewController+SDPlayerRotation.m ================================================ // // UIViewController+SDPlayerRotation.m // SLPlayer // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import "UIViewController+SDPlayerRotation.h" @implementation UIViewController (SDPlayerRotation) - (BOOL)shouldAutorotate { return NO; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationPortrait; } - (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleDefault; } - (BOOL)prefersStatusBarHidden { return NO; } @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SimpleAlignCell.h ================================================ // // SimpleAlignCell.h // XYMaintenance // // Created by DamocsYang on 15/8/12. // Copyright (c) 2015年 Kingnet. All rights reserved. // #import @interface SimpleAlignCell : UITableViewCell @property (weak, nonatomic) IBOutlet UILabel *xyTextLabel; @property (weak, nonatomic) IBOutlet UILabel *xyDetailLabel; @property (weak, nonatomic) IBOutlet UIImageView *xyIndicator; + (NSString*)defaultReuseId; @property (nonatomic, copy) void(^playBlock)(UIButton *); @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SimpleAlignCell.m ================================================ // // SimpleAlignCell.m // XYMaintenance // // Created by lisd on 15/8/12. // Copyright (c) 2015年 Kingnet. All rights reserved. // #import "SimpleAlignCell.h" @interface SimpleAlignCell() @end @implementation SimpleAlignCell - (void)awakeFromNib { [super awakeFromNib]; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; } + (NSString*)defaultReuseId{ return @"SimpleAlignCell"; } - (void)setData:(NSString*)data { self.xyDetailLabel.text = data; } - (IBAction)clickButton:(id)sender { !_playBlock ?: _playBlock(sender); } @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/SimpleAlignCell.xib ================================================ ================================================ FILE: SLPlayerDemo/SLPlayerDemo/Test1ViewController.h ================================================ // // Test1ViewController.h // SLPlayer_test // // Created by lisd on 2017/12/4. // Copyright © 2017年 lisd. All rights reserved. // #import @interface Test1ViewController : UIViewController @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/Test1ViewController.m ================================================ // // Test1ViewController.m // SLPlayer_test // // Created by lisd on 2017/12/4. // Copyright © 2017年 lisd. All rights reserved. // #import "Test1ViewController.h" #import "SimpleAlignCell.h" #import "SLPlayer.h" @interface Test1ViewController () @property (weak, nonatomic) IBOutlet UITableView *tableView; @property (nonatomic, strong) SLPlayerView *playerView; @end @implementation Test1ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor redColor]; self.tableView.delegate = self; self.tableView.dataSource = self; [self xy_registerTableView:self.tableView identifier:[SimpleAlignCell defaultReuseId]]; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 10; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { SimpleAlignCell* cell = [self.tableView dequeueReusableCellWithIdentifier:[SimpleAlignCell defaultReuseId]]; __weak __typeof(self)weakSelf = self; __block NSIndexPath *weakIndexPath = indexPath; [cell setPlayBlock:^(UIButton *btn) { NSURL *videoURL = [NSURL URLWithString:@"https://image.52doushi.com/hiweixiu/1_20170401.mp4"]; weakSelf.playerView = [[SLPlayerView alloc] init]; [weakSelf.view addSubview:weakSelf.playerView]; [weakSelf.playerView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(weakSelf.view).offset(20); make.left.right.equalTo(weakSelf.view); make.height.equalTo(weakSelf.playerView.mas_width).multipliedBy(9.0f/16.0f); }]; SLPlayerControlView *controlView = [[SLPlayerControlView alloc] init]; SLPlayerModel *playerModel = [[SLPlayerModel alloc] init]; playerModel.videoURL = videoURL; playerModel.scrollView = weakSelf.tableView; playerModel.indexPath = weakIndexPath; playerModel.fatherViewTag = 100; [weakSelf.playerView playerControlView:controlView playerModel:playerModel]; [weakSelf.playerView autoPlayTheVideo]; }]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 200; } -(void)xy_registerTableView:(UITableView*)tableView identifier:(NSString*)identifier{ NSString *className = NSStringFromClass([SimpleAlignCell class]); UINib *nib = [UINib nibWithNibName:className bundle:nil]; [tableView registerNib:nib forCellReuseIdentifier:identifier]; } - (SLPlayerView *)playerView { if (!_playerView) { _playerView = [SLPlayerView sharedPlayerView]; _playerView.playerLayerGravity = SLPlayerLayerGravityResize; _playerView.delegate = self; _playerView.cellPlayerOnCenter = NO; } return _playerView; } @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/ViewController.h ================================================ // // ViewController.h // SLPlayerDemo // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import @interface ViewController : UIViewController @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/ViewController.m ================================================ // // ViewController.m // SLPlayerDemo // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end ================================================ FILE: SLPlayerDemo/SLPlayerDemo/main.m ================================================ // // main.m // SLPlayerDemo // // Created by lisd on 2017/12/12. // Copyright © 2017年 lisd. All rights reserved. // #import #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: SLPlayerDemo/SLPlayerDemo.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 48; objects = { /* Begin PBXBuildFile section */ 307F1247DA776FF3D06EDDD0 /* libPods-SLPlayerDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BFF7F03F14D66C49E64A630E /* libPods-SLPlayerDemo.a */; }; C3903B891FDFCA4A007BB51C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C3903B881FDFCA4A007BB51C /* AppDelegate.m */; }; C3903B8C1FDFCA4A007BB51C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C3903B8B1FDFCA4A007BB51C /* ViewController.m */; }; C3903B8F1FDFCA4A007BB51C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C3903B8D1FDFCA4A007BB51C /* Main.storyboard */; }; C3903B911FDFCA4A007BB51C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C3903B901FDFCA4A007BB51C /* Assets.xcassets */; }; C3903B941FDFCA4A007BB51C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C3903B921FDFCA4A007BB51C /* LaunchScreen.storyboard */; }; C3903B971FDFCA4A007BB51C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C3903B961FDFCA4A007BB51C /* main.m */; }; C3903B9F1FDFCF70007BB51C /* Test1ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C3903B9D1FDFCF70007BB51C /* Test1ViewController.m */; }; C3903BA31FDFCFB6007BB51C /* SimpleAlignCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C3903BA01FDFCFB6007BB51C /* SimpleAlignCell.m */; }; C3903BA41FDFCFB6007BB51C /* SimpleAlignCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C3903BA11FDFCFB6007BB51C /* SimpleAlignCell.xib */; }; C3903BB51FDFCFF9007BB51C /* SLPlayerView.m in Sources */ = {isa = PBXBuildFile; fileRef = C3903BA61FDFCFF9007BB51C /* SLPlayerView.m */; }; C3903BB61FDFCFF9007BB51C /* SLBrightnessView.m in Sources */ = {isa = PBXBuildFile; fileRef = C3903BA71FDFCFF9007BB51C /* SLBrightnessView.m */; }; C3903BB71FDFCFF9007BB51C /* SLPlayerModel.m in Sources */ = {isa = PBXBuildFile; fileRef = C3903BA91FDFCFF9007BB51C /* SLPlayerModel.m */; }; C3903BB81FDFCFF9007BB51C /* SLPlayerControlView.m in Sources */ = {isa = PBXBuildFile; fileRef = C3903BAB1FDFCFF9007BB51C /* SLPlayerControlView.m */; }; C3903BB91FDFCFF9007BB51C /* UIView+ControlView.m in Sources */ = {isa = PBXBuildFile; fileRef = C3903BB01FDFCFF9007BB51C /* UIView+ControlView.m */; }; C3903BBA1FDFCFF9007BB51C /* UIViewController+SDPlayerRotation.m in Sources */ = {isa = PBXBuildFile; fileRef = C3903BB21FDFCFF9007BB51C /* UIViewController+SDPlayerRotation.m */; }; C3903BC01FDFD6D9007BB51C /* SLPlayer.bundle in Resources */ = {isa = PBXBuildFile; fileRef = C3903BBF1FDFD6D9007BB51C /* SLPlayer.bundle */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 648A639471591230332222AE /* Pods-SLPlayerDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SLPlayerDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SLPlayerDemo/Pods-SLPlayerDemo.debug.xcconfig"; sourceTree = ""; }; B44CDC4847E219622DFC7822 /* Pods-SLPlayerDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SLPlayerDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-SLPlayerDemo/Pods-SLPlayerDemo.release.xcconfig"; sourceTree = ""; }; BFF7F03F14D66C49E64A630E /* libPods-SLPlayerDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SLPlayerDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; C3903B841FDFCA4A007BB51C /* SLPlayerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SLPlayerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; C3903B871FDFCA4A007BB51C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; C3903B881FDFCA4A007BB51C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; C3903B8A1FDFCA4A007BB51C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; C3903B8B1FDFCA4A007BB51C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; C3903B8E1FDFCA4A007BB51C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; C3903B901FDFCA4A007BB51C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; C3903B931FDFCA4A007BB51C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; C3903B951FDFCA4A007BB51C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C3903B961FDFCA4A007BB51C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; C3903B9D1FDFCF70007BB51C /* Test1ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Test1ViewController.m; sourceTree = ""; }; C3903B9E1FDFCF70007BB51C /* Test1ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Test1ViewController.h; sourceTree = ""; }; C3903BA01FDFCFB6007BB51C /* SimpleAlignCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimpleAlignCell.m; sourceTree = ""; }; C3903BA11FDFCFB6007BB51C /* SimpleAlignCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SimpleAlignCell.xib; sourceTree = ""; }; C3903BA21FDFCFB6007BB51C /* SimpleAlignCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleAlignCell.h; sourceTree = ""; }; C3903BA61FDFCFF9007BB51C /* SLPlayerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SLPlayerView.m; sourceTree = ""; }; C3903BA71FDFCFF9007BB51C /* SLBrightnessView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SLBrightnessView.m; sourceTree = ""; }; C3903BA81FDFCFF9007BB51C /* UIViewController+SDPlayerRotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+SDPlayerRotation.h"; sourceTree = ""; }; C3903BA91FDFCFF9007BB51C /* SLPlayerModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SLPlayerModel.m; sourceTree = ""; }; C3903BAA1FDFCFF9007BB51C /* UIView+ControlView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+ControlView.h"; sourceTree = ""; }; C3903BAB1FDFCFF9007BB51C /* SLPlayerControlView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SLPlayerControlView.m; sourceTree = ""; }; C3903BAC1FDFCFF9007BB51C /* SLBrightnessView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLBrightnessView.h; sourceTree = ""; }; C3903BAD1FDFCFF9007BB51C /* SLPlayerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLPlayerView.h; sourceTree = ""; }; C3903BAE1FDFCFF9007BB51C /* SLPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLPlayer.h; sourceTree = ""; }; C3903BAF1FDFCFF9007BB51C /* SLPlayerControlViewDelagate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLPlayerControlViewDelagate.h; sourceTree = ""; }; C3903BB01FDFCFF9007BB51C /* UIView+ControlView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+ControlView.m"; sourceTree = ""; }; C3903BB11FDFCFF9007BB51C /* SLPlayerModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLPlayerModel.h; sourceTree = ""; }; C3903BB21FDFCFF9007BB51C /* UIViewController+SDPlayerRotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+SDPlayerRotation.m"; sourceTree = ""; }; C3903BB31FDFCFF9007BB51C /* SLMarco.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLMarco.h; sourceTree = ""; }; C3903BB41FDFCFF9007BB51C /* SLPlayerControlView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLPlayerControlView.h; sourceTree = ""; }; C3903BBF1FDFD6D9007BB51C /* SLPlayer.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SLPlayer.bundle; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ C3903B811FDFCA4A007BB51C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 307F1247DA776FF3D06EDDD0 /* libPods-SLPlayerDemo.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 5AB47592F5A0E88CE240B388 /* Frameworks */ = { isa = PBXGroup; children = ( BFF7F03F14D66C49E64A630E /* libPods-SLPlayerDemo.a */, ); name = Frameworks; sourceTree = ""; }; 7CF6B57B0B04B0E5ADB88677 /* Pods */ = { isa = PBXGroup; children = ( 648A639471591230332222AE /* Pods-SLPlayerDemo.debug.xcconfig */, B44CDC4847E219622DFC7822 /* Pods-SLPlayerDemo.release.xcconfig */, ); name = Pods; sourceTree = ""; }; C3903B7B1FDFCA4A007BB51C = { isa = PBXGroup; children = ( C3903B861FDFCA4A007BB51C /* SLPlayerDemo */, C3903B851FDFCA4A007BB51C /* Products */, 7CF6B57B0B04B0E5ADB88677 /* Pods */, 5AB47592F5A0E88CE240B388 /* Frameworks */, ); sourceTree = ""; }; C3903B851FDFCA4A007BB51C /* Products */ = { isa = PBXGroup; children = ( C3903B841FDFCA4A007BB51C /* SLPlayerDemo.app */, ); name = Products; sourceTree = ""; }; C3903B861FDFCA4A007BB51C /* SLPlayerDemo */ = { isa = PBXGroup; children = ( C3903BA51FDFCFF9007BB51C /* SLPlayer */, C3903B871FDFCA4A007BB51C /* AppDelegate.h */, C3903B881FDFCA4A007BB51C /* AppDelegate.m */, C3903B8A1FDFCA4A007BB51C /* ViewController.h */, C3903B8B1FDFCA4A007BB51C /* ViewController.m */, C3903B9E1FDFCF70007BB51C /* Test1ViewController.h */, C3903B9D1FDFCF70007BB51C /* Test1ViewController.m */, C3903BA21FDFCFB6007BB51C /* SimpleAlignCell.h */, C3903BA01FDFCFB6007BB51C /* SimpleAlignCell.m */, C3903BA11FDFCFB6007BB51C /* SimpleAlignCell.xib */, C3903B8D1FDFCA4A007BB51C /* Main.storyboard */, C3903B901FDFCA4A007BB51C /* Assets.xcassets */, C3903B921FDFCA4A007BB51C /* LaunchScreen.storyboard */, C3903B951FDFCA4A007BB51C /* Info.plist */, C3903B961FDFCA4A007BB51C /* main.m */, ); path = SLPlayerDemo; sourceTree = ""; }; C3903BA51FDFCFF9007BB51C /* SLPlayer */ = { isa = PBXGroup; children = ( C3903BBF1FDFD6D9007BB51C /* SLPlayer.bundle */, C3903BAE1FDFCFF9007BB51C /* SLPlayer.h */, C3903BAF1FDFCFF9007BB51C /* SLPlayerControlViewDelagate.h */, C3903BAD1FDFCFF9007BB51C /* SLPlayerView.h */, C3903BA61FDFCFF9007BB51C /* SLPlayerView.m */, C3903BB11FDFCFF9007BB51C /* SLPlayerModel.h */, C3903BA91FDFCFF9007BB51C /* SLPlayerModel.m */, C3903BAC1FDFCFF9007BB51C /* SLBrightnessView.h */, C3903BA71FDFCFF9007BB51C /* SLBrightnessView.m */, C3903BA81FDFCFF9007BB51C /* UIViewController+SDPlayerRotation.h */, C3903BB21FDFCFF9007BB51C /* UIViewController+SDPlayerRotation.m */, C3903BAA1FDFCFF9007BB51C /* UIView+ControlView.h */, C3903BB01FDFCFF9007BB51C /* UIView+ControlView.m */, C3903BB41FDFCFF9007BB51C /* SLPlayerControlView.h */, C3903BAB1FDFCFF9007BB51C /* SLPlayerControlView.m */, C3903BB31FDFCFF9007BB51C /* SLMarco.h */, ); path = SLPlayer; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ C3903B831FDFCA4A007BB51C /* SLPlayerDemo */ = { isa = PBXNativeTarget; buildConfigurationList = C3903B9A1FDFCA4A007BB51C /* Build configuration list for PBXNativeTarget "SLPlayerDemo" */; buildPhases = ( 3E66BC0C75E000AC61D72A04 /* [CP] Check Pods Manifest.lock */, C3903B801FDFCA4A007BB51C /* Sources */, C3903B811FDFCA4A007BB51C /* Frameworks */, C3903B821FDFCA4A007BB51C /* Resources */, 6A0092EC460170C892FD7422 /* [CP] Embed Pods Frameworks */, 948605D3F0C8507CB0887CFF /* [CP] Copy Pods Resources */, ); buildRules = ( ); dependencies = ( ); name = SLPlayerDemo; productName = SLPlayerDemo; productReference = C3903B841FDFCA4A007BB51C /* SLPlayerDemo.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ C3903B7C1FDFCA4A007BB51C /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0910; ORGANIZATIONNAME = lisd; TargetAttributes = { C3903B831FDFCA4A007BB51C = { CreatedOnToolsVersion = 9.1; ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = C3903B7F1FDFCA4A007BB51C /* Build configuration list for PBXProject "SLPlayerDemo" */; compatibilityVersion = "Xcode 8.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = C3903B7B1FDFCA4A007BB51C; productRefGroup = C3903B851FDFCA4A007BB51C /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( C3903B831FDFCA4A007BB51C /* SLPlayerDemo */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ C3903B821FDFCA4A007BB51C /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( C3903B941FDFCA4A007BB51C /* LaunchScreen.storyboard in Resources */, C3903BA41FDFCFB6007BB51C /* SimpleAlignCell.xib in Resources */, C3903B911FDFCA4A007BB51C /* Assets.xcassets in Resources */, C3903B8F1FDFCA4A007BB51C /* Main.storyboard in Resources */, C3903BC01FDFD6D9007BB51C /* SLPlayer.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 3E66BC0C75E000AC61D72A04 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; 6A0092EC460170C892FD7422 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SLPlayerDemo/Pods-SLPlayerDemo-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 948605D3F0C8507CB0887CFF /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SLPlayerDemo/Pods-SLPlayerDemo-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ C3903B801FDFCA4A007BB51C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( C3903B9F1FDFCF70007BB51C /* Test1ViewController.m in Sources */, C3903BB61FDFCFF9007BB51C /* SLBrightnessView.m in Sources */, C3903BA31FDFCFB6007BB51C /* SimpleAlignCell.m in Sources */, C3903BB51FDFCFF9007BB51C /* SLPlayerView.m in Sources */, C3903B8C1FDFCA4A007BB51C /* ViewController.m in Sources */, C3903BB81FDFCFF9007BB51C /* SLPlayerControlView.m in Sources */, C3903B971FDFCA4A007BB51C /* main.m in Sources */, C3903BBA1FDFCFF9007BB51C /* UIViewController+SDPlayerRotation.m in Sources */, C3903B891FDFCA4A007BB51C /* AppDelegate.m in Sources */, C3903BB71FDFCFF9007BB51C /* SLPlayerModel.m in Sources */, C3903BB91FDFCFF9007BB51C /* UIView+ControlView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ C3903B8D1FDFCA4A007BB51C /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( C3903B8E1FDFCA4A007BB51C /* Base */, ); name = Main.storyboard; sourceTree = ""; }; C3903B921FDFCA4A007BB51C /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( C3903B931FDFCA4A007BB51C /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ C3903B981FDFCA4A007BB51C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 11.1; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; }; C3903B991FDFCA4A007BB51C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 11.1; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; name = Release; }; C3903B9B1FDFCA4A007BB51C /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 648A639471591230332222AE /* Pods-SLPlayerDemo.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 266655SB8D; INFOPLIST_FILE = SLPlayerDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.lisd.SLPlayerDemo; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; C3903B9C1FDFCA4A007BB51C /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = B44CDC4847E219622DFC7822 /* Pods-SLPlayerDemo.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 266655SB8D; INFOPLIST_FILE = SLPlayerDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.lisd.SLPlayerDemo; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ C3903B7F1FDFCA4A007BB51C /* Build configuration list for PBXProject "SLPlayerDemo" */ = { isa = XCConfigurationList; buildConfigurations = ( C3903B981FDFCA4A007BB51C /* Debug */, C3903B991FDFCA4A007BB51C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; C3903B9A1FDFCA4A007BB51C /* Build configuration list for PBXNativeTarget "SLPlayerDemo" */ = { isa = XCConfigurationList; buildConfigurations = ( C3903B9B1FDFCA4A007BB51C /* Debug */, C3903B9C1FDFCA4A007BB51C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = C3903B7C1FDFCA4A007BB51C /* Project object */; } ================================================ FILE: SLPlayerDemo/SLPlayerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: SLPlayerDemo/SLPlayerDemo.xcworkspace/contents.xcworkspacedata ================================================