播放视频旋转 曾经终败给现在 2022-06-01 14:11 198阅读 0赞 播放器Demo(全屏)已实现功能点: push到播放器页面,横屏显示。 单机隐藏or显示上方标题栏与下方操作栏。 呼出右侧设置栏。 视频播放操作与进度条设置。 在屏幕上左右拖动,进行视频快进与快退。 在屏幕左侧上下拖动,进行亮度调整。 在屏幕右侧上下拖动,进行音量调整。 想到但是暂未实现的功能点:(大多为优化或与业务相关) 屏幕或进度条拖动快进操作时,添加提示框进行快进时间的实时提示。 用户无操作两三秒之后自动隐藏上下View。 视频清晰度调整按钮。(更换视频源) 操作加锁按钮。(加锁后未进行解锁操作之前不可进行操作) 弹幕相关。 用户允许横屏状态下,横屏竖屏自动进行页面切换与动画效果等。 网络视频的缓存、下载等。 软硬解码模式切换等。 笔者Demo选择使用了AVPlayer进行视频播放器的构建。由于UI的代码实现,加上略蛋疼的逻辑代码,播放器页面的代码量达到400多行,之后有时间的话会再进行优化。这里只贴出部分代码,想要查看或借鉴完整Demo,可以到本人github去下载。 使用AVPlayer构建播放器 1.导入头文件 #import <AVFoundation/AVFoundation.h> 2.其实没什么可说的,很简单,先初始化AVPlayer,然后添加到AVPlayerLayer,最后将其添加到视图的layer层。 #pragma mark - Demo中此视图的属性 #define TopViewHeight 55 #define BottomViewHeight 72 #define mainWidth [UIScreen mainScreen].bounds.size.width #define mainHeight [UIScreen mainScreen].bounds.size.height //上层建筑 @property (nonatomic,strong)UIView *topView; @property (nonatomic,strong)UIButton *backBtn; @property (nonatomic,strong)UILabel *titleLabel; @property (nonatomic,strong)UIButton *settingsBtn; //经济基础 @property (nonatomic,strong)UIView *bottomView; @property (nonatomic,strong)UIButton *playBtn; @property (nonatomic,strong)UILabel *textLabel; @property (nonatomic,assign)BOOL isPlay; @property (nonatomic,strong)UISlider *movieProgressSlider;//进度条 @property (nonatomic,assign)CGFloat ProgressBeginToMove; @property (nonatomic,assign)CGFloat totalMovieDuration;//视频总时间 //核心躯干 @property (nonatomic,strong)AVPlayer *player; //神之右手 @property (nonatomic,strong)UIView *settingsView; @property (nonatomic,strong)UIView *rightView; @property (nonatomic,strong)UIButton *setTestBtn; //touch evens @property (nonatomic,assign)BOOL isShowView; @property (nonatomic,assign)BOOL isSettingsViewShow; @property (nonatomic,assign)BOOL isSlideOrClick; @property (nonatomic,strong)UISlider *volumeViewSlider; @property (nonatomic,assign)float systemVolume;//系统音量值 @property (nonatomic,assign)float systemBrightness;//系统亮度 @property (nonatomic,assign)CGPoint startPoint;//起始位置坐标 @property (nonatomic,assign)BOOL isTouchBeganLeft;//起始位置方向 @property (nonatomic,copy)NSString *isSlideDirection;//滑动方向 @property (nonatomic,assign)float startProgress;//起始进度条 #pragma mark - 播放器躯干 - (void)createAvPlayer{ //设置静音状态也可播放声音 AVAudioSession *audioSession = [AVAudioSession sharedInstance]; [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; CGRect playerFrame = CGRectMake(0, 0, self.view.layer.bounds.size.height, self.view.layer.bounds.size.width); AVURLAsset *asset = [AVURLAsset assetWithURL: _url]; Float64 duration = CMTimeGetSeconds(asset.duration); //获取视频总时长 _totalMovieDuration = duration; AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset: asset]; _player = [[AVPlayer alloc]initWithPlayerItem:playerItem]; AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player]; playerLayer.frame = playerFrame; playerLayer.videoGravity = AVLayerVideoGravityResizeAspect; [self.view.layer addSublayer:playerLayer]; //需要设置自动播放的直接play即可 //[_player play]; } 屏幕单击手势与视频快进 屏幕单击 1.符合条件的情况下(手指按下后离开屏幕,并且没有拖动)通过BOOL值判断,隐藏或显示上下View - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ CGPoint point = [[touches anyObject] locationInView:self.view]; if (_isShowView) { //上下View为显示状态,此时点击上下View直接return if ((point.y>CGRectGetMinY(self.topView.frame)&&point.y< CGRectGetMaxY(self.topView.frame))||(point.y<CGRectGetMaxY(self.bottomView.frame)&&point.y>CGRectGetMinY(self.bottomView.frame))) { return } _isShowView = NO; [UIView animateWithDuration:0.5 animations:^{ _topView.alpha = 0; _bottomView.alpha = 0; }]; }else{ _isShowView = YES; [UIView animateWithDuration:0.5 animations:^{ _topView.alpha = 1; _bottomView.alpha = 1; }]; } } 2.右侧View显示的状态下,点击屏幕左半空白区域,隐藏右侧View if (_isSettingsViewShow) { if (point.x>CGRectGetMinX(_rightView.frame)&&point.x< CGRectGetMaxX(_rightView.frame)) { return; } _settingsView.alpha = 0; _isSettingsViewShow = NO; } 拖动快进 1.计算后得出拖动方向为横向拖动。 CGPoint location = [[touches anyObject] locationInView:self.view]; CGFloat changeY = location.y - _startPoint.y; CGFloat changeX = location.x - _startPoint.x; if(fabs(changeX) > fabs(changeY)){ _isSlideDirection = @"横向";//设置为横向 }else if(fabs(changeY)>fabs(changeX)){ _isSlideDirection = @"纵向";//设置为纵向 }else{ _isSlideOrClick = NO; NSLog(@"不在五行中。"); } 2.根据手指按下与离开屏幕后,横向位移的坐标值,对视频播放进度进行刷新。 if (_isSlideOrClick) { _isSlideDirection = @""; _isSlideOrClick = NO; CGFloat changeY = point.y - _startPoint.y; CGFloat changeX = point.x - _startPoint.x; //如果位置改变 刷新进度条 if(fabs(changeX) > fabs(changeY)){ [self scrubberIsScrolling]; } return; } //拖动进度条 -(void)scrubberIsScrolling{ //计算出拖动的当前秒数(总长*当前百分比) NSInteger dragedSeconds = floorf(_totalMovieDuration * _movieProgressSlider.value); CMTime newCMTime = CMTimeMake(dragedSeconds, 1); [_player seekToTime:newCMTime completionHandler:^(BOOL finished) { [_player play]; [_playBtn setTitle:@"暂停" forState:UIControlStateNormal]; }]; } MPMediaPlayerController与AVPlayerViewController的使用介绍 MPMediaPlayerController与AVPlayerViewController,两者都是基于AVPlayer的简单UI封装,如果只是需要简单的视频播放功能,可以使用这两个类快速的构建视频播放器。 MPMediaPlayerController 1.导入头文件 #import <MediaPlayer/MediaPlayer.h> 2.初始化mp,几行代码既可以实现。 @property (nonatomic,strong)MPMoviePlayerController *mp; NSURL *url1 = [[NSBundle mainBundle]URLForResource:@"chenyifaer" withExtension:@"mp4"]; _mp = [[MPMoviePlayerController alloc] initWithContentURL:url1]; _mp.controlStyle = MPMovieControlStyleNone; _mp.view.frame = CGRectMake(0, 0, self.view.layer.bounds.size.height, self.view.layer.bounds.size.width); [self.view addSubview:_mp.view]; [_mp play]; controlStyle属性有三个值: MPMovieControlStyleNone, //无控制 MPMovieControlStyleEmbedded, //有全屏按钮与控制 MPMovieControlStyleFullscreen, // 默认全屏,有退出和控制 当然还有一些其他属性,有需要可以自行进行设置。 AVPlayerViewController 1.导入框架与头文件 #import <AVKit/AVKit.h> 2.初始化AVPlayerViewController,创建一个AVPlayer添加上。然后将其添加到视图上,再将View添加到self.View上,然后play即可 NSURL *url1 = [[NSBundle mainBundle]URLForResource:@"chenyifaer" withExtension:@"mp4"]; AVPlayer * player = [AVPlayer playerWithURL:url1]; AVPlayerViewController *playerController = [[AVPlayerViewController alloc]init]; playerController.player = player; [self addChildViewController:playerController]; [self.view addSubview:playerController.view]; playerController.view.frame = CGRectMake(0, 0, self.view.layer.bounds.size.height, self.view.layer.bounds.size.width); [player play]; 同样几行代码,即可实现。 音量调整 1.导入头文件 #import <MediaPlayer/MediaPlayer.h> 2.借助MPVolumeView类来获取到其音量进度条,进而进行音量获取与控制 @property (nonatomic,strong)UISlider *movieProgressSlider;//进度条 MPVolumeView *volumeView = [[MPVolumeView alloc] init]; _volumeViewSlider = nil; for (UIView *view in [volumeView subviews]){ if ([view.class.description isEqualToString:@"MPVolumeSlider"]){ _volumeViewSlider = (UISlider *)view; break; } 3.触摸屏幕时,记录手指按下的位置、获取按下时系统的音量(实现touchesBegan方法) - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ _startProgress = _movieProgressSlider.value; } 4.手指在规定行为下(手指按下位置为视图右半区,且纵向滑动)持续滑动时,动态改变系统音量(实现touchesMoved方法) //手指持续滑动,此方法会持续调用 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ CGPoint location = [[touches anyObject] locationInView:self.view]; int index = location.y - _startPoint.y; if(index>0){ [_volumeViewSlider setValue:_systemVolume - (abs(index)/10 * 0.05) animated:YES]; [_volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside]; }else{ [_volumeViewSlider setValue:_systemVolume + (abs(index)/10 * 0.05) animated:YES]; [_volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside]; } } 亮度调整 1.触摸屏幕时,记录手指按下的位置、按下时屏幕的亮度(实现touchesBegan方法) 2.手指在规定行为下(手指按下位置为视图左半区,且纵向滑动)持续滑动时,不断动态处理(实现touchesMoved方法) 3.改变屏幕亮度:[UIScreen mainScreen].brightness = X (0~1); //手指持续滑动,此方法会持续调用 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ CGPoint location = [[touches anyObject] locationInView:self.view]; int index = location.y - _startPoint.y; if(index>0){ [UIScreen mainScreen].brightness = _systemBrightness - abs(index)/10 * 0.01; }else{ _movieProgressSlider.value = _startProgress - abs(index)/10 * 0.008; } } 屏幕旋转 1.设置应用支持横屏(默认支持)。 2.在根视图中设置默认竖屏(Nav、TabBar、VC基类) - (BOOL)shouldAutorotate{ return NO; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; } 3.在需要横屏的VC中重写下列方法即可 //允许横屏旋转 - (BOOL)shouldAutorotate{ return YES; } //支持左右旋转 - (UIInterfaceOrientationMask)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskLandscapeRight|UIInterfaceOrientationMaskLandscapeLeft; } //默认为右旋转 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{ return UIInterfaceOrientationLandscapeRight; } 作者:CCN菜先生 链接:https://www.jianshu.com/p/813a74cc7e41 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
还没有评论,来说两句吧...