2019独角兽企业重金招聘Python工程师标准>>>

前言

  • 公司APP使用七牛的播放器,各种崩溃,各种卡顿问题,一怒之下抽时间,看看有没苹果自带框架比较好解决播放问题,又不想引入其他库增加APP大小。发现AVPlayer,确实效率不错,基本满足业务需求,和同事确认了APP某部分功能播放文件只使用了mp4,m3u8,flv (按使用量先后排序)。AVPlayer不支持flv,所以mp4,m3u8使用AVPlayer,其他使用七牛播放器SDK.

注意

  • 由于项目使用较多约束,但是AVPlayer默认渲染不能根据约束大小变化,所以需要重载UIView的一个方法,强制改变layerClass,作为AVPlayer的渲染层,以便动态适配约束。
.h 文件#import <UIKit/UIKit.h>
@interface TTVAVPlayerView : UIView
@end.m 文件#import "TTVAVPlayerView.h"
#import <AVFoundation/AVFoundation.h>@implementation TTVAVPlayerView+ (Class)layerClass {return [AVPlayerLayer class];
}@end

AVPlayer

使用库

#import <AVFoundation/AVFoundation.h>
#import<MediaPlayer/MediaPlayer.h>
#import<CoreMedia/CoreMedia.h>

初始化

- (NSDictionary*)setupPlayer:(NSString*)url{//防盗链headersNSMutableDictionary * headers = [NSMutableDictionary dictionary];[headers setObject:@"http://*.itouchtv.cn" forKey:@"Referer"];NSURL*liveURL = [NSURL URLWithString:url];AVAsset*liveAsset = [AVURLAsset URLAssetWithURL:liveURL options:@{@"AVURLAssetHTTPHeaderFieldsKey" : headers} ];AVPlayerItem* playerItem = [AVPlayerItem playerItemWithAsset:liveAsset];if (iOS9_OR_LATER) {playerItem.canUseNetworkResourcesForLiveStreamingWhilePaused = true;}if (iOS10_OR_LATER) {playerItem.preferredForwardBufferDuration = kPreferredForwardBufferDuration;}//播放器AVPlayer*player = [AVPlayer playerWithPlayerItem:playerItem];//渲染对象TTVAVPlayerView* avPlayerView = [[TTVAVPlayerView alloc ]init];AVPlayerLayer* playerLayer = (AVPlayerLayer *)avPlayerView.layer;[playerLayer setPlayer:player];return @{@"AVAsset":player,@"TTVAVPlayerView":avPlayerView};
}

状态监听

  • 方法一 KVO监听
static NSString* const kStatusKeyName = @"status";
static NSString* const kLoadedTimeRangesKeyName = @"loadedTimeRanges";
static NSString* const kPlaybackBufferEmptyKeyName = @"playbackBufferEmpty";
static NSString* const kPlaybackLikelyToKeepUpKeyName = @"playbackLikelyToKeepUp";- (void)addKVO:(AVPlayerItem*)playerItem{if (playerItem == nil) return;[playerItem addObserver:self forKeyPath:kStatusKeyName options:NSKeyValueObservingOptionNew context:nil];[playerItem addObserver:self forKeyPath:kLoadedTimeRangesKeyName options:NSKeyValueObservingOptionNew context:nil];[playerItem addObserver:self forKeyPath:kPlaybackBufferEmptyKeyName options:NSKeyValueObservingOptionNew context:nil];[playerItem addObserver:self forKeyPath:kPlaybackLikelyToKeepUpKeyName options:NSKeyValueObservingOptionNew context:nil];
}- (void)delKVO:(AVPlayerItem*)playerItem{@try {[playerItem removeObserver:self forKeyPath:kStatusKeyName context:nil];[playerItem removeObserver:self forKeyPath:kLoadedTimeRangesKeyName context:nil];[playerItem removeObserver:self forKeyPath:kPlaybackBufferEmptyKeyName context:nil];[playerItem removeObserver:self forKeyPath:kPlaybackLikelyToKeepUpKeyName context:nil];}@catch (NSException *exception) {DLog(@"多次删除了");}
}//监听获得消息
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{{AVPlayerItem *playerItem = (AVPlayerItem *)object;if ([keyPath isEqualToString:@"status"]) {if ([playerItem status] == AVPlayerStatusReadyToPlay) {self.playerStatus = TTVPlayerStatusReady;//status 点进去看 有三种状态CGFloat duration = playerItem.duration.value / playerItem.duration.timescale; //视频总时间DLog(@"准备好播放了,总时间:%.2f", duration);//还可以获得播放的进度,这里可以给播放进度条赋值了} else if ([playerItem status] == AVPlayerStatusFailed || [playerItem status] == AVPlayerStatusUnknown) {[_player pause];}} else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {  //监听播放器的下载进度NSArray *loadedTimeRanges = [playerItem loadedTimeRanges];CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域float startSeconds = CMTimeGetSeconds(timeRange.start);float durationSeconds = CMTimeGetSeconds(timeRange.duration);NSTimeInterval timeInterval = startSeconds + durationSeconds;// 计算缓冲总进度CMTime duration = playerItem.duration;CGFloat totalDuration = CMTimeGetSeconds(duration);CGFloat bufferdDuration = round(timeInterval);DLog(@"下载进度:%.2f 当前下载时长:%.2f 总时长:%.2f", timeInterval / totalDuration,self.bufferedTime,totalDuration);} else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) { //监听播放器在缓冲数据的状态DLog(@"缓冲不足暂停了");} else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {DLog(@"缓冲达到可播放程度了");//由于 AVPlayer 缓存不足就会自动暂停,所以缓存充足了需要手动播放,才能继续播放[_player play];}}
}
  • 方法二 通知监听
- (void)addNotification{[[NSNotificationCenter defaultCenter] removeObserver:self];[[NSNotificationCenter defaultCenter] removeObserver:self.player];@weakify(self)[[NSNotificationCenter defaultCenter]addObserverForName:AVPlayerItemDidPlayToEndTimeNotificationobject:nil queue:[NSOperationQueue mainQueue]usingBlock:^(NSNotification * _Nonnull note) {@strongify(self)DLog(@"播放完成");}];[[NSNotificationCenter defaultCenter]addObserverForName:AVPlayerItemFailedToPlayToEndTimeNotificationobject:nil queue:[NSOperationQueue mainQueue]usingBlock:^(NSNotification * _Nonnull note) {@strongify(self)DLog(@"播放出错");}];
}
  • 一些状态的判断
@property (nonatomic, strong) AVPlayer *player;- (BOOL)playing {if (self.playerItem.isPlaybackLikelyToKeepUp &&  self.player.rate == 1) {return true;}return false;
}- (NSUInteger)currentPlayingTime {CMTime time = self.player.currentTime;return CMTimeGetSeconds(time);
}- (NSUInteger)totalPlayingTime {CMTime time = self.player.currentItem.duration;Float64 seconds = CMTimeGetSeconds(time);return seconds;
}- (void)seekTo:(NSUInteger)sec{CMTime time = CMTimeMakeWithSeconds(sec, 1);[self.player seekToTime:time];
}- (void)play{[self.player play];
}- (void)resume{[self seekTo:self.currentPlayingTime];[self.player play];
}- (void)pause{[self.player pause];
}- (void)stop{[self.player pause];self.player.muted = true;self.player.rate = 0.0;
}

原文:http://raychow.linkfun.top/2017/12/28/archives/1_ios/AVPlayer/index/

转载于:https://my.oschina.net/u/3729367/blog/1596358

AVPlayer简单使用相关推荐

  1. iOS音视频播放-AVPlayer简单使用

    按公司需求需要对音频文件进行后台播放,借此机会对音频播放做了个总结.主要针对 AVPlayer 进行详细说明. iOS 各播放器比较 名称 使用环境 优点 确点 System Sound Servic ...

  2. iOS AVPlayer 简单应用

    //1 AVPlayerViewController *avvc = [[AVPlayerViewController alloc] init]; //2 avvc.player = [[AVPlay ...

  3. OC 使用AVPlayer 简单的实现一个视频播放器

    1.使用类PlayView来实现,代码如下: #import <UIKit/UIKit.h> @interface PlayView : UIView /**播放的URL*/ - (voi ...

  4. AVPlayer简单地视频播放器

    #import <AVFoundation/AVFoundation.h> #import <AVKit/AVKit.h> @property (nonatomic, reta ...

  5. AVPlayer就可以播放在线音频

    大家知道AVAudioPlayer只能播放本地的,而第三方的AudioStreamer只能播放在线的.audioqueue,audiostream这些非到万不得已我是不看的....-  - AVPla ...

  6. AVPlayer 实现简单的视频播放功能

    // 声明两个对象 @property (nonatomic,strong)AVPlayer *player;//播放器对象 @property (nonatomic,strong)AVPlayerI ...

  7. 简单视频播放AVPlayer和AVPlayerViewController

    NSURL *url = [NSURL URLWithString:@"http://flv3.bn.netease.com/videolib3/1712/13/ouwHf3421/SD/o ...

  8. [iOS]调和 pop 手势导致 AVPlayer 播放卡顿

    作者 NewPan 关注 2017.07.15 14:24* 字数 3110 阅读 749评论 8喜欢 17 声明:我为这个框架写了四篇文章: 第一篇:[iOS]UINavigationControl ...

  9. iOS: ios视频播放(MPMediaPlayerController,AVPlayer,AVPlayerViewcontroller、ffmpeg-AVPlayer)...

    介绍: 和音频播放一样,ios也提供个很多的API.如mediaPlayer.framework下的MPMediaPlayerController.AVFounditon.framework下的AVP ...

最新文章

  1. 如何优雅地使用pdpipe与Pandas构建管道?
  2. 小技巧 —— linux中怎么简单的复制5000个数字
  3. 推送通知(二)远程通知
  4. 《C++ Primer 第五版》(第1~6章总结)
  5. react数据从本地读取_如何将从Google表格读取的React应用程序部署到Netlify
  6. linux 添加重定向域名,Linux系统中Nginx的安装并进行域名认证和重定向
  7. java的vector_Java中 Vector的使用详解
  8. Keras-3 Keras With Otto Group
  9. 【LeetCode】【HOT】105. 从前序与中序遍历序列构造二叉树(哈希表+递归)
  10. 电子城西区北扩规划一路道路工程_雁塔区电子城街道重点项目进度
  11. LINUX使用U盘要小心,特别是不要用剪切
  12. 这才是真相,“轻点,疼”被禁却另有玄机
  13. 企业网站管理系统php源码,云优CMS企业网站管理系统
  14. 一致性算法 - Distro协议在Nacos的实践
  15. 大前研一,柳井正《放胆去闯》读书笔记
  16. cdrx8如何批量导出jpg_cdr超级伴侣批量导图v8.0 免费版
  17. Ipad开发课程系列目录--很好的教程,推荐给大家
  18. 解决mysql保存数据SQLException: Incorrect string value: ‘\xF0\x9F\x91\x87\xE5\x91...‘ for column ‘错误
  19. 从云服务器硬盘更换认识备份、快照、镜像
  20. [力扣c语言实现]207. 课程表(拓扑排序)

热门文章

  1. Eureka 的 Application Service 客户端的注册以及运行示例
  2. STM32BootLoader引导SecureCRT串口固件升级(YModem协议)
  3. android 8.1 Launcher3 去掉抽屉式,显示所有 app
  4. LTE CSFB测试分析
  5. Verilog中 高位与低位
  6. MT6771芯片开发资料,MT6771原理图、参考设计、移植指南
  7. 啊,整理整理收藏的PS3游戏
  8. SRS和杜比认证音效
  9. 谁导演了这场玫瑰花的葬礼
  10. pytorch repeat使用