// // ALMoviePlayerController.m // ALMoviePlayerController // // Created by Anthony Lobianco on 10/8/13. // Copyright (c) 2013 Anthony Lobianco. All rights reserved. // #import "ALMoviePlayerController.h" #import #import #import "TPLightView.h" #import #import @implementation UIDevice (ALSystemVersion) + (float)iOSVersion { static float version = 0.f; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ version = [[[UIDevice currentDevice] systemVersion] floatValue]; }); return version; } @end @implementation UIApplication (ALAppDimensions) + (CGSize)sizeInOrientation:(UIInterfaceOrientation)orientation { CGSize size = [UIScreen mainScreen].bounds.size; UIApplication *application = [UIApplication sharedApplication]; if (UIInterfaceOrientationIsLandscape(orientation)) { if (size.widthsize.height) { size = CGSizeMake(size.height, size.width); } } if (!application.statusBarHidden && [UIDevice iOSVersion] < 7.0) { size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height); } return size; } @end static const CGFloat movieBackgroundPadding = 0.f; //if we don't pad the movie's background view, the edges will appear jagged when rotating static const NSTimeInterval fullscreenAnimationDuration = 0.15; @interface ALMoviePlayerController () { CGPoint beginPoint; CGPoint movePoint; CGPoint tempPoint; UISlider* volumeViewSlider; CGFloat sysV; CGFloat value; NSString *directionString; CTCallCenter *callCenter; } @property (nonatomic, strong) UIView *playBackView; @property (nonatomic, strong) UILabel *totalLabel; @property (nonatomic, strong) UILabel *currLabel; @property (nonatomic, strong) UIImageView *playImage; @property (nonatomic, strong) UIProgressView *timeSlider; @property (nonatomic, strong) TPLightView *lightView; @end @implementation ALMoviePlayerController # pragma mark - Construct/Destruct - (id)init { return [self initWithFrame:CGRectZero]; } - (id)initWithFrame:(CGRect)frame { if ( (self = [super init]) ) { self.view.frame = frame; MPVolumeView *volumeView = [[MPVolumeView alloc] init]; volumeView.showsVolumeSlider = YES; for (UIView *view in [volumeView subviews]){ if ([view.class.description isEqualToString:@"MPVolumeSlider"]){ volumeViewSlider = (UISlider*)view; break; } } self.currentPlaybackRate = 1.f; sysV = volumeViewSlider.value; [UIScreen mainScreen].wantsSoftwareDimming = YES; [volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside]; self.view.backgroundColor = [UIColor blackColor]; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; _movieFullscreen = NO; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; if (!_movieBackgroundView) { _movieBackgroundView = [[UIView alloc] init]; _movieBackgroundView.alpha = 0.f; [_movieBackgroundView setBackgroundColor:[UIColor blackColor]]; } [self.view addSubview:self.playBackView]; [self.view addSubview:self.lightView]; [self.lightView makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.view); make.centerY.equalTo(self.view); make.size.mas_equalTo(CGSizeMake(155, 155)); }]; [self.playBackView makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.view); make.centerY.equalTo(self.view); make.size.mas_equalTo(CGSizeMake(140, 60)); }]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarOrientationWillChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; callCenter = [[CTCallCenter alloc] init]; __block typeof(self) weakSelf = self; callCenter.callEventHandler = ^(CTCall* call) { if ([call.callState isEqualToString:CTCallStateDisconnected]) { dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf play]; }); NSLog(@"Call has been disconnected"); } else if ([call.callState isEqualToString:CTCallStateConnected]) { NSLog(@"Call has just been connected"); } else if([call.callState isEqualToString:CTCallStateIncoming]) { NSLog(@"Call is incoming"); } else if ([call.callState isEqualToString:CTCallStateDialing]) { NSLog(@"call is dialing"); } else { NSLog(@"Nothing is done"); } }; } return self; } - (TPLightView *)lightView { if (nil == _lightView) { _lightView = [[TPLightView alloc] initWithValue:(int)([UIScreen mainScreen].brightness*16)]; _lightView.alpha = 0; } return _lightView; } - (UIView *)playBackView { if (_playBackView == nil) { _playBackView = [[UIView alloc] initWithFrame:CGRectZero]; _playBackView.backgroundColor = [UIColor clearColor]; _playBackView.alpha = 0; UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectZero]; imageView.image = Image(@"video/backImage.png"); [_playBackView addSubview:imageView]; [imageView makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(_playBackView); }]; [_playBackView addSubview:self.playImage]; [self.playImage makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(_playBackView).offset(5); make.centerX.equalTo(_playBackView); make.size.mas_equalTo(CGSizeMake(55/2, 20)); }]; [_playBackView addSubview:self.totalLabel]; [_playBackView addSubview:self.timeSlider]; [self.timeSlider makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(_playBackView).offset(6); make.right.equalTo(_playBackView).offset(-6); make.bottom.equalTo(_playBackView).offset(-7); make.height.mas_equalTo(1); }]; [_playBackView addSubview:self.currLabel]; } return _playBackView; } - (UIProgressView *)timeSlider { if (_timeSlider == nil) { _timeSlider = [[UIProgressView alloc] initWithFrame:CGRectZero]; _timeSlider.progressTintColor = [UIColor colorWithHexString:@"0x5ca3e9"]; _timeSlider.trackTintColor = [UIColor clearColor]; // _timeSlider.maximumValue = floor(self.duration); _timeSlider.userInteractionEnabled = NO; } return _timeSlider; } - (UIImageView *)playImage { if (_playImage == nil) { _playImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 55/2, 20)]; } return _playImage; } - (UILabel *)totalLabel { if (_totalLabel == nil) { _totalLabel = [[UILabel alloc] initWithFrame:CGRectMake(65, 35, 75, 10)]; double totalTime = floor(self.duration); _totalLabel.text = [NSString stringWithFormat:@"/%02.f:%02.f",floor(totalTime / 60.0),fmod(totalTime, 60.0)]; _totalLabel.font = appFont(9, NO); _totalLabel.textColor = [UIColor whiteColor]; } return _totalLabel; } - (UILabel *)currLabel { if (_currLabel == nil) { _currLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 35, 65, 10)]; double currentTime = floor(self.currentPlaybackTime); _currLabel.text = [NSString stringWithFormat:@"%02.f:%02.f",floor(currentTime / 60.0),fmod(currentTime, 60.0)]; _currLabel.textAlignment = NSTextAlignmentRight; _currLabel.font = appFont(9, NO); _currLabel.textColor = [UIColor colorWithHexString:@"0x5ca3e9"]; } return _currLabel; } - (void)cutPhotoBtnClick:(UIButton *)btn { UIView *view = [[UIView alloc] initWithFrame:KEY_WINDOW.bounds]; view.backgroundColor = [UIColor whiteColor]; view.alpha = 0; [KEY_WINDOW addSubview:view]; [UIView animateWithDuration:0.1 animations:^{ view.alpha = 1; } completion:^(BOOL finished) { [UIView animateWithDuration:0.1 animations:^{ view.alpha = 0; } completion:^(BOOL finished) { [view removeFromSuperview]; }]; }]; NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; AVURLAsset *myAsset = [[AVURLAsset alloc] initWithURL:self.contentURL options:opts]; float second = 0.0f; // value为 总帧数,timescale为 fps second = myAsset.duration.value / myAsset.duration.timescale; // 获取视频总时长,单位秒 AVAssetImageGenerator *myImageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:myAsset]; myImageGenerator.appliesPreferredTrackTransform = YES; //解决 时间不准确问题 myImageGenerator.requestedTimeToleranceBefore = kCMTimeZero; myImageGenerator.requestedTimeToleranceAfter = kCMTimeZero; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [myImageGenerator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:CMTimeMakeWithSeconds(self.currentPlaybackTime, NSEC_PER_SEC)]] completionHandler: ^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) { UIImage *img = [UIImage imageWithCGImage:image]; UIImageWriteToSavedPhotosAlbum(img, self, NULL, NULL); }]; }); // UIView *view = [[UIView alloc] initWithFrame:KEY_WINDOW.bounds]; // view.backgroundColor = [UIColor whiteColor]; // view.alpha = 0; // [KEY_WINDOW addSubview:view]; // NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] // forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; // AVURLAsset *myAsset = [[AVURLAsset alloc] initWithURL:self.contentURL options:opts]; // float second = 0.0f; // // value为 总帧数,timescale为 fps // second = myAsset.duration.value / myAsset.duration.timescale; // 获取视频总时长,单位秒 // AVAssetImageGenerator *myImageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:myAsset]; // myImageGenerator.appliesPreferredTrackTransform = YES; // //解决 时间不准确问题 // myImageGenerator.requestedTimeToleranceBefore = kCMTimeZero; // myImageGenerator.requestedTimeToleranceAfter = kCMTimeZero; // NSLog(@"begin %f %@",self.currentPlaybackTime,self.contentURL); //// CMTime time = CMTimeMake(self.currentPlaybackTime*myAsset.duration.timescale, myAsset.duration.timescale); //// NSError *error; // // if ([self.contentURL.absoluteString isMatchedByRegex:@"m3u8"]) { // if ([self.delegate respondsToSelector:@selector(captureVideoPhoto)]) { // [self.delegate captureVideoPhoto]; // } //// AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:myAsset]; //// //// //// NSDictionary *pixBuffAttributes = @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)}; //// AVPlayerItemVideoOutput *outPut = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:pixBuffAttributes]; //// dispatch_queue_t que = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //// [outPut setDelegate:self queue:que]; //// [playerItem addOutput:outPut]; //// [outPut requestNotificationOfMediaDataChangeWithAdvanceInterval:0.1]; //// //// CVPixelBufferRef videoRef = [outPut copyPixelBufferForItemTime:playerItem.currentTime itemTimeForDisplay:nil]; //// //// CIImage *ciImage = [CIImage imageWithCVPixelBuffer:videoRef]; //// //// CIContext *temporaryContext = [CIContext contextWithOptions:nil]; //// CGImageRef videoImage = [temporaryContext //// createCGImage:ciImage //// fromRect:CGRectMake(0, 0, //// CVPixelBufferGetWidth(videoRef), //// CVPixelBufferGetHeight(videoRef))]; //// //// UIImage *image = [UIImage imageWithCGImage:videoImage]; //// UIImageWriteToSavedPhotosAlbum(image, self, nil, nil); //// CGImageRelease(videoImage); //// outPut = nil; //// myAsset = nil; // }else { // dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // [myImageGenerator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:CMTimeMakeWithSeconds(self.currentPlaybackTime, NSEC_PER_SEC)]] completionHandler: // ^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) // { // UIImageWriteToSavedPhotosAlbum([UIImage imageWithCGImage:image], self, nil, nil); // NSLog(@"end"); // }]; // }); // CGImageRef refImg = [myImageGenerator copyCGImageAtTime:time actualTime:NULL error:&error]; // UIImageWriteToSavedPhotosAlbum([UIImage imageWithCGImage:refImg], self, nil, nil); // CGImageRelease(refImg); // NSLog(@"end:%@",error.description); // } // [UIView animateWithDuration:0.1 animations:^{ // view.alpha = 1; // } completion:^(BOOL finished) { // [UIView animateWithDuration:0.1 animations:^{ // view.alpha = 0; // } completion:^(BOOL finished) { // [view removeFromSuperview]; // }]; // }]; } // //- (void)outputMediaDataWillChange:(AVPlayerItemOutput *)sender //{ // // // Restart display link. // [displayLink setPaused:NO]; // //} - (void)panHandler:(UIPanGestureRecognizer *)pan { switch (pan.state) { case UIGestureRecognizerStateBegan: beginPoint = [pan locationInView:self.view]; tempPoint = beginPoint; value = [UIScreen mainScreen].brightness; sysV = volumeViewSlider.value; directionString = nil; double totalTime = floor(self.duration); _totalLabel.text = [NSString stringWithFormat:@"/%02.f:%02.f",floor(totalTime / 60.0),fmod(totalTime, 60.0)]; break; case UIGestureRecognizerStateChanged: movePoint = [pan locationInView:self.view]; if (directionString == nil) { if (fabs(movePoint.y - beginPoint.y) > fabs(movePoint.x - beginPoint.x) && fabs(movePoint.y - beginPoint.y) > 20) { directionString = @"1";//竖直 }else if (fabs(movePoint.x - beginPoint.x) > fabs(movePoint.y - beginPoint.y) && fabs(movePoint.x - beginPoint.x) > 20) { directionString = @"0";//水平 } }else { if ([directionString isEqualToString:@"1"]) { if ([pan locationInView:self.view].x <= rect_screen.size.width/2) {//亮度 _lightView.alpha = 1; CGFloat tmp = value +0.05*((beginPoint.y - movePoint.y)/10); if (tmp > 1.0) { tmp = 1.0; }else if (tmp < 0) { tmp = 0; } [UIScreen mainScreen].brightness = tmp; [_lightView setValue:(int)(tmp*16)]; }else { CGFloat tmp = sysV+0.05*((beginPoint.y - movePoint.y)/10); if (tmp > 1.0) { tmp = 1.0; }else if (tmp < 0) { tmp = 0; } [volumeViewSlider setValue:tmp animated:YES]; } }else { //快进快退 self.playBackView.alpha = 1; double totalTime = floor(self.duration); double currentTime = floor(self.currentPlaybackTime); double temp = (currentTime + ((movePoint.x - beginPoint.x)/6*(totalTime/120.0))); if (temp < 0) { temp = 0; }else if (temp > totalTime) { temp = totalTime; } self.currLabel.text = [NSString stringWithFormat:@"%02.f:%02.f",floor(temp/60.0),fmod(temp, 60.0)]; if (movePoint.x < tempPoint.x) { self.playImage.image = Image(@"video/playBack.png"); }else if (tempPoint.x < movePoint.x){ self.playImage.image = Image(@"video/playForword.png"); } [self.timeSlider setProgress:(temp/totalTime) animated:YES]; tempPoint = movePoint; } } break; case UIGestureRecognizerStateEnded: { if ([directionString isEqualToString:@"0"]) { double currentTime = floor(self.currentPlaybackTime); double totalTime = floor(self.duration); double temp = (currentTime + ((movePoint.x - beginPoint.x)/6*(totalTime/120.0))); if (temp < 0) { temp = 0; }else if (temp > totalTime) { temp = totalTime; } self.currentPlaybackTime = temp; [self.controls.durationTimer invalidate]; [self play]; [UIView animateWithDuration:1 animations:^{ self.playBackView.alpha = 0; } completion:^(BOOL finished) { }]; }else if ([directionString isEqualToString:@"1"]) { if ([pan locationInView:self.view].x <= rect_screen.size.width/2) { [UIView animateWithDuration:1.5 animations:^{ self.lightView.alpha = 0; } completion:^(BOOL finished) { }]; } } } break; default: break; } [pan setTranslation:CGPointMake(0, 0) inView:self.view]; } - (void)dealloc { _delegate = nil; [_movieBackgroundView removeFromSuperview]; [[NSNotificationCenter defaultCenter] removeObserver:self]; TPLOG(@"*************video stop**************"); } # pragma mark - Getters - (BOOL)isFullscreen { return _movieFullscreen; } - (CGFloat)statusBarHeightInOrientation:(UIInterfaceOrientation)orientation { if ([UIDevice iOSVersion] >= 7.0) return 0.f; else if ([UIApplication sharedApplication].statusBarHidden) return 0.f; return 20.f; } # pragma mark - Setters - (void)setContentURL:(NSURL *)contentURL { if (!_controls) { [[NSException exceptionWithName:@"ALMoviePlayerController Exception" reason:@"Set contentURL after setting controls." userInfo:nil] raise]; } [self setControlStyle:MPMovieControlStyleNone]; [super setContentURL:contentURL]; [[NSNotificationCenter defaultCenter] postNotificationName:ALMoviePlayerContentURLDidChangeNotification object:nil]; [self play]; } - (BOOL)videoIsLiving { NSString *url = [self.contentURL absoluteString]; if ([url isMatchedByRegex:@"m3u8"]) { _controls.durationSlider.enabled = NO; return YES; }else { return NO; } } - (void)setControls:(ALMoviePlayerControls *)controls { if (_controls != controls) { _controls = controls; UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panHandler:)]; pan.maximumNumberOfTouches = 1; [pan delaysTouchesBegan]; [self.view addGestureRecognizer:pan]; _controls.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); [self.view addSubview:_controls]; [_controls.cutPhotoBtn addTarget:self action:@selector(cutPhotoBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } } - (void)setFrame:(CGRect)frame { [self.view setFrame:frame]; [self.controls setFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; } - (void)setFullscreen:(BOOL)fullscreen { [self setFullscreen:fullscreen animated:NO]; } - (void)setFullscreen:(BOOL)fullscreen animated:(BOOL)animated { _movieFullscreen = fullscreen; if (fullscreen) { [[NSNotificationCenter defaultCenter] postNotificationName:MPMoviePlayerWillEnterFullscreenNotification object:nil]; UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow]; if (!keyWindow) { keyWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:0]; } if (CGRectEqualToRect(self.movieBackgroundView.frame, CGRectZero)) { [self.movieBackgroundView setFrame:keyWindow.bounds]; } [keyWindow addSubview:self.movieBackgroundView]; [UIView animateWithDuration:animated ? fullscreenAnimationDuration : 0.0 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{ self.movieBackgroundView.alpha = 1.f; } completion:^(BOOL finished) { self.view.alpha = 0.f; [self.movieBackgroundView addSubview:self.view]; UIInterfaceOrientation currentOrientation = [[UIApplication sharedApplication] statusBarOrientation]; // if (isIOS8) { // if (currentOrientation == UIInterfaceOrientationPortrait || currentOrientation == UIInterfaceOrientationPortraitUpsideDown) { // currentOrientation = UIInterfaceOrientationPortrait; // }else currentOrientation = UIInterfaceOrientationLandscapeLeft; // } [self rotateMoviePlayerForOrientation:currentOrientation animated:NO completion:^{ [UIView animateWithDuration:animated ? fullscreenAnimationDuration : 0.0 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{ self.view.alpha = 1.f; } completion:^(BOOL finished) { [[NSNotificationCenter defaultCenter] postNotificationName:MPMoviePlayerDidEnterFullscreenNotification object:nil]; }]; }]; if ([self.delegate conformsToProtocol:@protocol(ALMoviePlayerControllerDelegate)] && [self.delegate respondsToSelector:@selector(enterFullScreen:)]) { [self.delegate enterFullScreen:YES]; } }]; } else { [[NSNotificationCenter defaultCenter] postNotificationName:MPMoviePlayerWillExitFullscreenNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillChangeStatusBarOrientationNotification object:nil]; [UIView animateWithDuration:animated ? fullscreenAnimationDuration : 0.0 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ self.view.alpha = 0.f; } completion:^(BOOL finished) { if ([self.delegate respondsToSelector:@selector(moviePlayerWillMoveFromWindow)]) { [self.delegate moviePlayerWillMoveFromWindow]; } self.view.alpha = 1.f; [UIView animateWithDuration:animated ? fullscreenAnimationDuration : 0.0 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ self.movieBackgroundView.alpha = 0.f; } completion:^(BOOL finished) { [self.movieBackgroundView removeFromSuperview]; [[NSNotificationCenter defaultCenter] postNotificationName:MPMoviePlayerDidExitFullscreenNotification object:nil]; }]; if ([self.delegate conformsToProtocol:@protocol(ALMoviePlayerControllerDelegate)] && [self.delegate respondsToSelector:@selector(enterFullScreen:)]) { [self.delegate enterFullScreen:NO]; } }]; } } //- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { // return YES; //} #pragma mark - Notifications - (void)videoLoadStateChanged:(NSNotification *)note { switch (self.loadState) { case MPMovieLoadStatePlayable: [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(movieTimedOut) object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:nil]; default: break; } } - (void)statusBarOrientationWillChange:(NSNotification *)note { } - (void)rotateMoviePlayerForOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated completion:(void (^)(void))completion { CGFloat angle; CGSize windowSize = [UIApplication sizeInOrientation:orientation]; NSLog(@"%ld",(long)orientation); CGRect backgroundFrame; CGRect movieFrame; switch (orientation) { case UIInterfaceOrientationPortraitUpsideDown: angle = 0.f; backgroundFrame = CGRectMake(-movieBackgroundPadding, -movieBackgroundPadding, windowSize.width + movieBackgroundPadding*2, windowSize.height + movieBackgroundPadding*2); movieFrame = CGRectMake(movieBackgroundPadding, movieBackgroundPadding, backgroundFrame.size.width - movieBackgroundPadding*2, backgroundFrame.size.height - movieBackgroundPadding*2); self.controls.cutPhotoBtn.hidden = NO; break; case UIInterfaceOrientationLandscapeLeft: angle = 0.f; backgroundFrame = KEY_WINDOW.bounds; movieFrame = KEY_WINDOW.bounds; self.controls.cutPhotoBtn.hidden = NO; self.controls.fullscreenButton.selected = YES; break; case UIInterfaceOrientationLandscapeRight: angle = 0.f; backgroundFrame = KEY_WINDOW.bounds; movieFrame = KEY_WINDOW.bounds; self.controls.cutPhotoBtn.hidden = NO; self.controls.fullscreenButton.selected = YES; break; case UIInterfaceOrientationPortrait: default: if (self.fullscreen) { angle = 0.f; if ([self.delegate respondsToSelector:@selector(turnToright)]) { [self.delegate turnToright]; } // backgroundFrame = KEY_WINDOW.bounds; // movieFrame = CGRectMake(movieBackgroundPadding, movieBackgroundPadding, backgroundFrame.size.height - movieBackgroundPadding*2, backgroundFrame.size.width - movieBackgroundPadding*2); self.controls.fullscreenButton.selected = YES; }else { self.controls.fullscreenButton.selected = NO; angle = 0.f; backgroundFrame = CGRectMake(-movieBackgroundPadding, [self statusBarHeightInOrientation:orientation] - movieBackgroundPadding, windowSize.width + movieBackgroundPadding*2, windowSize.height + movieBackgroundPadding*2); movieFrame = CGRectMake(movieBackgroundPadding, movieBackgroundPadding, backgroundFrame.size.width - movieBackgroundPadding*2, backgroundFrame.size.height - movieBackgroundPadding*2); } break; } if (animated) { [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ self.movieBackgroundView.transform = CGAffineTransformMakeRotation(angle); self.movieBackgroundView.frame = backgroundFrame; [self setFrame:movieFrame]; [self.controls setFrame:CGRectMake(0, 0, KEY_WINDOW.bounds.size.width, KEY_WINDOW.bounds.size.height)]; } completion:^(BOOL finished) { if (completion) completion(); }]; } else { self.movieBackgroundView.transform = CGAffineTransformMakeRotation(angle); self.movieBackgroundView.frame = backgroundFrame; [self setFrame:movieFrame]; [self.controls setFrame:CGRectMake(0, 0, KEY_WINDOW.bounds.size.width, KEY_WINDOW.bounds.size.height)]; if (completion) completion(); } } # pragma mark - Internal Methods - (void)play { [super play]; //remote file if (![self.contentURL.scheme isEqualToString:@"file"] && self.loadState == MPMovieLoadStateUnknown) { [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:nil]; [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(movieTimedOut) object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoLoadStateChanged:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil]; [self performSelector:@selector(movieTimedOut) withObject:nil afterDelay:20.f]; } } - (void)stop { if ([self videoIsLiving]) { if ([[self.contentURL absoluteString] isMatchedByRegex:@"m3u8"]) { [self setContentURL:[NSURL URLWithString:@""]]; [self setFullscreen:NO]; [self shouldAutoplay]; } } [super stop]; } -(void)movieTimedOut { if (!(self.loadState & MPMovieLoadStatePlayable) || !(self.loadState & MPMovieLoadStatePlaythroughOK)) { if ([self.delegate respondsToSelector:@selector(movieTimedOut)]) { [self.delegate performSelector:@selector(movieTimedOut)]; } } } @end