我的avplayer播放器,能横屏,竖屏,适应屏幕,上代码

1.我把我的那个最主要的类的.m的主要的代码附上

@implementation LDZMoviePlayerController- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor blackColor];self.topProgressSlider.value = 0.0;[self addGestureRecognizer];//  添加观察者[self addNotificationCenters];[self addAVPlayer];
}- (void)addAVPlayer{playItem = [AVPlayerItem playerItemWithURL: self.movieURL];self.playerHelper = [[LDZAVPlayerHelper alloc] init];[_playerHelper initAVPlayerWithAVPlayerItem:playItem];//  创建显示层self.playerLayer = [AVPlayerLayer playerLayerWithPlayer: _playerHelper.getAVPlayer];_playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;//  竖屏的时候frame[self setVerticalFrame];//  这是视频的填充模式, 默认为AVLayerVideoGravityResizeAspect_playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;//  插入到view层上面, 没有用addSubLayer[self.view.layer insertSublayer:_playerLayer atIndex:0];//  添加进度观察[self addProgressObserver];[self addObserverToPlayerItem: playItem];
}
//  播放页面添加轻拍手势
- (void)addGestureRecognizer {UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissAllSubViews:)];tap.delegate = self;[self.view addGestureRecognizer:tap];
}
#pragma mark - 观察者 观察播放完毕 观察屏幕旋转
- (void)addNotificationCenters {//  注册观察者用来观察,是否播放完毕[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];//  注册观察者来观察屏幕的旋转[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarOrientationChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}
#pragma mark - 横屏 竖屏的时候frame的设置
- (void)statusBarOrientationChange:(NSNotification *)notification {UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];if (orientation == UIInterfaceOrientationLandscapeRight) {[self setPlayerLayerFrame];self.isFirstRotatorTap = YES;[self setTopRightBottomFrame];}if (orientation == UIInterfaceOrientationLandscapeLeft) {[self setPlayerLayerFrame];self.isFirstRotatorTap = YES;[self setTopRightBottomFrame];}if (orientation == UIInterfaceOrientationPortrait) {//  竖屏的时候[self setVerticalFrame];self.isFirstRotatorTap = YES;[self setTopRightBottomFrame];}
}
//  横屏的时候frame
- (void)setPlayerLayerFrame {CGRect frame = self.view.bounds;frame.origin.x = 20;frame.origin.y = (SCREEN_HEIGHT - SCREEN_HEIGHT * (SCREEN_WIDTH - 40) / SCREEN_WIDTH) / 2;frame.size.width = SCREEN_WIDTH - 40;frame.size.height = SCREEN_HEIGHT * (SCREEN_WIDTH - 40) / SCREEN_WIDTH;_playerLayer.frame = frame;
}
//  竖屏的时候frame
- (void)setVerticalFrame {CGRect frame = self.view.bounds;frame.origin.x = ZERO;frame.origin.y = (SCREEN_HEIGHT - SCREEN_WIDTH * (SCREEN_WIDTH / SCREEN_HEIGHT)) / 2;frame.size.width = SCREEN_WIDTH;frame.size.height = SCREEN_WIDTH * (SCREEN_WIDTH / SCREEN_HEIGHT);_playerLayer.frame = frame;
}//  动画(出现或隐藏top - right - bottom)
- (void)dismissAllSubViews:(UITapGestureRecognizer *)tap {[self setTopRightBottomFrame];
}
//  设置TopRightBottomFrame
- (void)setTopRightBottomFrame {__weak typeof (self) myself = self;if (!self.isFirstRotatorTap) {[UIView animateWithDuration:.2f animations:^{myself.topView.frame = CGRectMake(myself.topView.frame.origin.x, -TOPVIEW_HEIGHT, myself.topView.frame.size.width, myself.topView.frame.size.height);myself.rightView.frame = CGRectMake(SCREEN_WIDTH, myself.rightView.frame.origin.y, myself.rightView.frame.size.width, myself.rightView.frame.size.height);myself.verticalBottomView.frame = CGRectMake(myself.verticalBottomView.frame.origin.x, SCREEN_HEIGHT, myself.verticalBottomView.frame.size.width, myself.verticalBottomView.frame.size.height);myself.ratotarBottomView.frame = CGRectMake(myself.ratotarBottomView.frame.origin.x, SCREEN_HEIGHT, myself.ratotarBottomView.frame.size.width, myself.ratotarBottomView.frame.size.height);}];self.isFirstRotatorTap = YES;} else {[UIView animateWithDuration:.2f animations:^{myself.topView.frame = CGRectMake(myself.topView.frame.origin.x, ZERO, myself.topView.frame.size.width, myself.topView.frame.size.height);myself.rightView.frame = CGRectMake(SCREEN_WIDTH - RIGHT_WIDTH, myself.rightView.frame.origin.y, myself.rightView.frame.size.width, myself.rightView.frame.size.height);myself.verticalBottomView.frame = CGRectMake(myself.verticalBottomView.frame.origin.x, SCREEN_HEIGHT - VERTICAL_BOTTOM_HEIGHT, myself.verticalBottomView.frame.size.width, myself.verticalBottomView.frame.size.height);myself.ratotarBottomView.frame = CGRectMake(myself.ratotarBottomView.frame.origin.x, SCREEN_HEIGHT - ROTATOR_BOTTOM_HEIGHT, myself.ratotarBottomView.frame.size.width, myself.ratotarBottomView.frame.size.height);}];self.isFirstRotatorTap = NO;}
}
//  显示top,right,bottom的View
- (void)setTopRightBottomViewHiddenToShow {_topView.hidden = NO;_rightView.hidden = NO;_ratotarBottomView.hidden = NO;_verticalBottomView.hidden = NO;_isFirstRotatorTap = NO;
}
//  隐藏top,right,bottom的View
- (void)setTopRightBottomViewShowToHidden {_topView.hidden = YES;_rightView.hidden = YES;_ratotarBottomView.hidden = YES;_verticalBottomView.hidden = YES;_isFirstRotatorTap = YES;
}
#pragma mark - 暂停
- (void)setMovieParse {[_playerHelper.getAVPlayer pause];isPlay = NO;//  因为用的是xib,不设置的话图片会重合_verticalPlayButton.imageView.image = nil;_rotatorPlayButton.imageView.image = nil;[_verticalPlayButton setImage:[UIImage imageNamed:@"播放器_播放"] forState: UIControlStateNormal];[_rotatorPlayButton setImage:[UIImage imageNamed:@"播放器_播放"] forState:UIControlStateNormal];
}
#pragma mark - 播放
- (void)setMoviePlay {[_playerHelper.getAVPlayer play];isPlay = YES;//  因为用的是xib,不设置的话图片会重合_verticalPlayButton.imageView.image = nil;_rotatorPlayButton.imageView.image = nil;[_verticalPlayButton setImage:[UIImage imageNamed:@"播放器_暂停"] forState: UIControlStateNormal];[_rotatorPlayButton setImage:[UIImage imageNamed:@"播放器_暂停"] forState:UIControlStateNormal];
}#pragma mark -  添加进度观察 - addProgressObserver
- (void)addProgressObserver {//  设置每秒执行一次[_playerHelper.getAVPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue: NULL usingBlock:^(CMTime time) {
NSLog(@"进度观察 + %f", _topProgressSlider.value);//  获取当前时间CMTime currentTime = _playerHelper.getAVPlayer.currentItem.currentTime;//  转化成秒数CGFloat currentPlayTime = (CGFloat)currentTime.value / currentTime.timescale;//  总时间CMTime totalTime = playItem.duration;//  转化成秒_totalMovieDuration = (CGFloat)totalTime.value / totalTime.timescale;//  相减后_topProgressSlider.value = CMTimeGetSeconds(currentTime) / _totalMovieDuration;progressSlider = CMTimeGetSeconds(currentTime) / _totalMovieDuration;
NSLog(@"%f", _topProgressSlider.value);NSDate *pastDate = [NSDate dateWithTimeIntervalSince1970: currentPlayTime];_topPastTimeLabel.text = [self getTimeByDate:pastDate byProgress: currentPlayTime];CGFloat remainderTime = _totalMovieDuration - currentPlayTime;NSDate *remainderDate = [NSDate dateWithTimeIntervalSince1970: remainderTime];_topRemainderLabel.text = [self getTimeByDate:remainderDate byProgress: remainderTime];if (_isFirstRotatorTap) {[self setTopRightBottomViewShowToHidden];} else {[self setTopRightBottomViewHiddenToShow];}}];//  设置topProgressSlider图片UIImage *thumbImage = [UIImage imageNamed:@"slider-metal-handle.png"];[self.topProgressSlider setThumbImage:thumbImage forState:UIControlStateHighlighted];[self.topProgressSlider setThumbImage:thumbImage forState:UIControlStateNormal];
}- (NSString *)getTimeByDate:(NSDate *)date byProgress:(float)current {NSDateFormatter *formatter = [[NSDateFormatter alloc] init];if (current / 3600 >= 1) {[formatter setDateFormat:@"HH:mm:ss"];} else {[formatter setDateFormat:@"mm:ss"];}return [formatter stringFromDate:date];
}- (void)addObserverToPlayerItem:(AVPlayerItem *)playerItem {[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];[playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem {[playerItem removeObserver:self forKeyPath:@"status"];[playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
}//  观察者的方法, 会在加载好后触发, 可以在这个方法中, 保存总文件的大小, 用于后面的进度的实现
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{AVPlayerItem *playerItem = (AVPlayerItem *)object;if ([keyPath isEqualToString:@"status"]) {AVPlayerStatus status = [[change objectForKey:@"new"] intValue];if (status == AVPlayerStatusReadyToPlay) {NSLog(@"正在播放...,视频总长度: %.2f",CMTimeGetSeconds(playerItem.duration));CMTime totalTime = playerItem.duration;self.totalMovieDuration = (CGFloat)totalTime.value / totalTime.timescale;}}if ([keyPath isEqualToString:@"loadedTimeRanges"]) {NSArray *array = playerItem.loadedTimeRanges;//  本次缓冲时间范围CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];float startSeconds = CMTimeGetSeconds(timeRange.start);float durationSeconds = CMTimeGetSeconds(timeRange.duration);//  缓冲总长度NSTimeInterval totalBuffer = startSeconds + durationSeconds;
//        NSLog(@"共缓冲%.2f", totalBuffer);NSLog(@"进度 + %f", progressSlider);self.topProgressSlider.value = progressSlider;}
}#pragma mark - UIGestureRecognizerDelegate Method 方法
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {//  不让子视图响应点击事件if( CGRectContainsPoint(self.topView.frame, [gestureRecognizer locationInView:self.view]) || CGRectContainsPoint(self.rightView.frame, [gestureRecognizer locationInView:self.view]) || CGRectContainsPoint(self.ratotarBottomView.frame, [gestureRecognizer locationInView:self.view]) || CGRectContainsPoint(self.verticalBottomView.frame, [gestureRecognizer locationInView:self.view])) {return NO;} else{return YES;};
}#pragma mark - 播放进度
- (IBAction)topSliderValueChangedAction:(id)sender {UISlider *test = (UISlider *)sender;NSLog(@"进度条进度 + %f", test.value);UISlider *senderSlider = sender;double currentTime = floor(_totalMovieDuration * senderSlider.value);//转换成CMTime才能给player来控制播放进度CMTime dragedCMTime = CMTimeMake(currentTime, 1);[_playerHelper.getAVPlayer seekToTime:dragedCMTime completionHandler:^(BOOL finished) {if (_isPlayOrParse) {[_playerHelper.getAVPlayer play];}}];
}- (IBAction)topSliderTouchDownAction:(id)sender {
}- (IBAction)topSliderTouchUpInsideAction:(id)sender {
}#pragma mark - 播放上一个
- (IBAction)rotatorUpAction:(id)sender {NSLog(@"上一个~~~");
}#pragma mark - 播放...
- (IBAction)rotatorPlayAction:(UIButton *)sender {if (isPlay) {[self setMovieParse];} else {[self setMoviePlay];}
}#pragma mark - 播放下一个...
- (IBAction)rotatorNextAction:(UIButton *)sender {NSLog(@"下一个~~~");
}#pragma mark - 返回按钮...
- (IBAction)finishAction:(UIButton *)sender {NSLog(@"完成~~~");
}#pragma mark 播放结束后的代理回调
- (void)moviePlayDidEnd:(NSNotification *)notify
{//  LettopRightBottomViewShow[self setTopRightBottomViewHiddenToShow];[self setMovieParse];//  让这个视频循环播放...
}#pragma mark - 音量slider
- (IBAction)bottomSoundSliderAction:(UISlider *)sender {//  0 - 1[_playerHelper setAVPlayerVolume:sender.value];self.rotatorBottomSlider.value = sender.value;self.verticalBottomSlider.value = sender.value;if (sender.value == 0) {self.rotatorSoundImageView.image = [UIImage imageNamed:@"播放器_静音"];self.verticalSoundImageView.image = [UIImage imageNamed:@"播放器_静音"];} else {self.rotatorSoundImageView.image = [UIImage imageNamed:@"播放器_音量"];self.verticalSoundImageView.image = [UIImage imageNamed:@"播放器_音量"];}
}#pragma mark -  分享 - 收藏 - 缓存
- (IBAction)rightShareButton:(UIButton *)sender {NSLog(@"分享~~~");
}- (IBAction)rightCollectButton:(UIButton *)sender {NSLog(@"收藏~~~");
}- (IBAction)rightCacheButton:(UIButton *)sender {NSLog(@"缓存~~~");
}- (void)dealloc {//  移除观察者,使用观察者模式的时候,记得在不使用的时候,进行移除[self removeObserverFromPlayerItem: _playerHelper.getAVPlayer.currentItem];[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:nil];[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];//  返回前一个页面的时候释放内存[self.playerHelper.getAVPlayer replaceCurrentItemWithPlayerItem:nil];
}

2.到此说完啦,为了写这个玩意,我写了一周啊.

3.实现了横屏,竖屏,快进,快退,暂停等功能

源码地址:http://download.csdn.net/detail/fengchenlangzi_/9354939

AVPlayer自定义视频播放器相关推荐

  1. 自定义视频播放器与慢放滚轮

    受同学之邀,帮忙自定义一控件.需求是:开发慢放滚轮,用手指拨动实现帧级的慢速播放,滚轮可双向拨动,其滚动具有惯性,滚动速度决定视频播放的速度.需求很明朗,可我却是一头雾水.说实话,在此之前我还没有自定 ...

  2. Android进阶:自定义视频播放器开发(下)

    上一篇文章我们主要讲了视频播放器开发之前需要准备的一个知识,TextureView,用于对图像流的处理.这篇文章开始构建一个基础的视频播放器. 一.准备工作 在之前的文章已经说过了,播放器也是一个vi ...

  3. Android开发笔记(一百二十五)自定义视频播放器

    视频播放方式 在Android中播放视频的方式有两种: 1.使用MediaPlayer结合SurfaceView进行播放.其中通过SurfaceView显示视频的画面,通过MediaPlayer来设置 ...

  4. 一步步自定义视频播放器——TextureView+MediaPlayer自定义视频播放器

    本篇参考封装一个视频播放器,原文已经写的非常棒了,本篇加入了个人对其内容的理解.秉承不重复造轮子的良好理念,接下来开始拆解轮子.内容非常多,我都差点放弃写,有耐心的请往下看 github上非常棒的视频 ...

  5. Android自定义视频播放器(三)

    参看:Android自定义视频播放器(一):https://blog.csdn.net/zxd1435513775/article/details/81507909 参看:Android自定义视频播放 ...

  6. HTML5 自定义视频播放器

    HTML5 自定义视频播放器 第一步:获取播放器 第二步:实现播放与暂停 第三步:实现全屏操作 第四步:实现播放的逻辑 第五步:实现播放过程的逻辑 第六步:实现视频的跳播 第七步:播放完毕后重置播放器 ...

  7. Android 自定义视频播放器

    由于录像之后,原先选用的腾讯VOD点播播放器显示出来竖屏都变横屏了,虽然选中了现在的腾讯VOD点播,还是把Android视频播放器了解了一番. Android自定义视频播放器有以下三种: 一.Medi ...

  8. HTML5视频(自定义视频播放器源码)

    video对象 兼容情况: safari浏览器不支持webm格式 Chrome浏览器支持webm格式 ie8以及以下不支持video标签 , ie9支持video标签 ,但是支持mp4格式的 Fire ...

  9. Android进阶:自定义视频播放器开发(上)

    随着快手,抖音,西瓜视频等视频APP的崛起,视频播放已经成为主流,此时作为Android研发的你,想要提高自己的能力还不知道怎么开发视频播放器怎么行?所以今天就带着大家一起开发一个简易播放器:Smal ...

最新文章

  1. C++中局部类的使用
  2. 【PAT乙级】1041 考试座位号 (15 分)
  3. 怎么自定义linux登录界面?
  4. Spring Security OAuth2源码解析(一)
  5. mysql 快速插入(insert)多条记录
  6. Qt报错:C:\Program Files (x86)\SogouInput\Components\
  7. 计算机专业教育经历怎么写,个人简历教育经历怎么写?
  8. 如何在CentOS 7上安装Elasticsearch,Logstash和Kibana(ELK堆栈)
  9. SUSE11挂载目录seems to be mounted read-only错误 2022_11_08
  10. oracle数据删了怎么恢复吗,oracle误删数据恢复方法总结
  11. Cocos Creator
  12. [云原生专题-22]:K8S - 集群编排工具K8S与SWARM比较与技术选择
  13. 银河系创投徐芳:专注B2B这片热土,燃起产业新势能 | To B 50+
  14. 韩国电力供应商利用区块链构建生态友好型微电网
  15. 微信小程序把view居中_初识微信小程序
  16. 封闭式基金周折价率排行表20061013(ZT)
  17. 21天学通java第7版pdf_21天学通Java.第7版.pdf
  18. 网络管理员需了解的主要职责!
  19. linux服务器实训心得体会,linux实训心得体会 linux实训总结与体会
  20. Large-Scale Long-Tailed Recognition in an Open World

热门文章

  1. 交换机的接口有哪些?一文带你记住其名称及作用
  2. 查看端口:如何查看端口(3306)被哪个程序占用?
  3. java使用jacob实现word转pdf
  4. 360面试——产品实习面试
  5. “水果”公司的复兴:Apple
  6. 【Win11添加软件到开机启动项方法】
  7. solidworks 2018 因动态绘制边线显示视图延迟的解决方案
  8. 浅谈:什么是ABI接口
  9. 游戏背景音乐的作用—增强文化活力
  10. 【C++】vector 排序