哈喽,我是二西,今天主要来记录AVPlayer播放视频,Emmm包括一些坑,Emmm顺便放上最近喜欢的一首歌哈哈哈
错位时空 music.163.com/song?id=180…
简单初始化
AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:url]];
_player = [[AVPlayer alloc] initWithPlayerItem:item];
//放置播放器的视图
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
_playerLayer.frame = _videoView.bounds;
[_videoView.layer addSublayer:_playerLayer];
//自定义view转屏自动布局
//[((AVPlayerLayer *)_playerView.layer) setPlayer:_player];
_player.automaticallyWaitsToMinimizeStalling = NO;//坑坑坑,要加不然会卡主第一帧很久才播放
坑1:记得加automaticallyWaitsToMinimizeStalling=NO; 不然某些视频会卡在第一帧很久才会自动播放。
坑2:如需转屏的时候自动布局,需自定义一个view,让view的layer类返回AVPlayerLayer类,不然有时候转屏frame不会改变或者错误,布局会乱
@interface DQPlayerLayerView : UIView
@end
#import <AVKit/AVKit.h>
@implementation DQPlayerLayerView
+ (Class)layerClass {
return [AVPlayerLayer class];
}
KVO检测一些状态属性
由于我引用了FBKVOController,所以一些监听回调和系统不一样,自行修改,如未引用记得释放监听
状态status
[self.KVOController observe:item keyPath:@"status" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSString *,id> * _Nonnull change) {
__strong typeof(weakSelf) strongSelf = weakSelf;
AVPlayerItem *item = (AVPlayerItem *)object;
if (item.status == AVPlayerItemStatusReadyToPlay) {
strongSelf.isFail = NO;
//开始播放
[strongSelf.loadView stopAnimating];
[strongSelf.player play];
//进度条时间
CMTime duration = item.duration;
[strongSelf setEndTime:CMTimeGetSeconds(duration)];
}else if(item.status == AVPlayerItemStatusFailed){
strongSelf.isFail = YES;
//视频加载失败
[strongSelf.loadView stopAnimating];
}
}];
缓冲loadedTimeRanges
[self.KVOController observe:item keyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSString *,id> * _Nonnull change) {
__strong typeof(weakSelf) strongSelf = weakSelf;
NSArray *loadedTimeRanges = [[strongSelf.player currentItem] loadedTimeRanges];
CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域
float startSeconds = CMTimeGetSeconds(timeRange.start);
float durationSeconds = CMTimeGetSeconds(timeRange.duration);
NSTimeInterval result = startSeconds + durationSeconds;// 计算缓冲总进度
NSTimeInterval current = strongSelf.player.currentTime.value/strongSelf.player.currentTime.timescale;//当前播放进度
if (strongSelf.isPlay && (result>current+2 || result==CMTimeGetSeconds(strongSelf.player.currentItem.duration))) {
if (strongSelf.isBuffer) {
strongSelf.isBuffer = NO;
[strongSelf.loadView stopAnimating];
[strongSelf.player play];
}
}
}];
//缓冲
[self.KVOController observe:item keyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSString *,id> * _Nonnull change) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf.isPlay && !strongSelf.isBuffer) {
strongSelf.isBuffer = YES;
[strongSelf.loadView startAnimating];
[strongSelf.player pause];
}
}];
加载进度
// 每秒回调一次,更新进度条
_playTimeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
__strong typeof(weakSelf) strongSelf = weakSelf;
NSTimeInterval totalTime = CMTimeGetSeconds(strongSelf.player.currentItem.duration);//总时长
NSTimeInterval currentTime = time.value / time.timescale;//当前时间进度
strongSelf.slider.value = currentTime / totalTime;
[strongSelf setStartTime:currentTime];
}];
- (void)dealloc {
[_player removeTimeObserver:_playTimeObserver];
}
播放结束通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playFinishNotification:) name:AVPlayerItemDidPlayToEndTimeNotification object:item];
- (void)playFinishNotification:(NSNotification *)noti {
[self stop];
}
操作
#pragma mark - 停止
- (void)stop {
_isPlay = NO;
if (_player) {
[_player.currentItem cancelPendingSeeks];
[_player.currentItem.asset cancelLoading];
[_player pause];
[_player.currentItem seekToTime:kCMTimeZero];
[_loadView stopAnimating];
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpbf"] forState:UIControlStateNormal];
}
}
#pragma mark - 继续
- (void)continuePlay {
if (!_isPlay) {
[_player play];
_isPlay = YES;
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpzt"] forState:UIControlStateNormal];
}
}
#pragma mark - 暂停
- (void)pausePlay {
if (_isPlay) {
[_player pause];
_isPlay = NO;
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpbf"] forState:UIControlStateNormal];
}
}
#
静音
#pragma mark - 静音
- (void)onMute {
_player.muted = YES;
}
- (void)offMute {
_player.muted = NO;
}
进度条拖拽播放
#pragma mark - 拖拽播放
_slider = [[UISlider alloc] init];
//进度条图片
[_slider setMinimumTrackImage:[UIImage imageNamed:@"app_img_jdt_2"] forState:UIControlStateNormal];
[_slider setMaximumTrackImage:[UIImage imageNamed:@"app_img_jdt_1"] forState:UIControlStateNormal];
//进度条小圆点
[_slider setThumbImage:[UIImage imageNamed:@"app_img_hk"] forState:UIControlStateNormal];
[_slider setThumbImage:[UIImage imageNamed:@"app_img_hk"] forState:UIControlStateHighlighted];
//拖拽事件
[_slider addTarget:self action:@selector(sliderTouchBeginAction) forControlEvents:UIControlEventTouchDown];
[_slider addTarget:self action:@selector(sliderChangeAction) forControlEvents:UIControlEventValueChanged];
[_slider addTarget:self action:@selector(sliderTouchEndAction) forControlEvents:UIControlEventTouchUpInside];
- (void)sliderTouchBeginAction {
[_player pause];
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpbf"] forState:UIControlStateNormal];
}
- (void)sliderChangeAction {
NSTimeInterval currentTime = _slider.value * CMTimeGetSeconds(_player.currentItem.duration);
[self setStartTime:currentTime];
}
- (void)sliderTouchEndAction {
NSTimeInterval changedTime = _slider.value * CMTimeGetSeconds(_player.currentItem.duration);
if (changedTime == CMTimeGetSeconds(_player.currentItem.duration)) {
changedTime -= 0.5;
}
[_player.currentItem seekToTime:CMTimeMakeWithSeconds(changedTime,NSEC_PER_SEC)];
[_player play];
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpzt"] forState:UIControlStateNormal];
}
最后
最后贴个全代码,看看就好,根据需求来~
@interface DQPlayerView : UIView
@property (nonatomic, strong) NSString *playImageUrl;//封面
@property (nonatomic, strong) NSString *playTitle;//标题
@property (nonatomic, assign) BOOL isPlay;
@property (nonatomic, copy) dispatch_block_t closeBlock;
@property (nonatomic, copy) dispatch_block_t endBlock;
- (void)playWithUrl:(NSString *)url;
- (void)continuePlay;
- (void)pausePlay;
- (void)operaAction;
- (void)showToolView;
- (void)hideToolView;
- (void)onMute;
- (void)offMute;
#import "DQPlayerView.h"
#import <AVKit/AVKit.h>
#import "NSObject+FBKVOController.h"
#import "PublicAction.h"
#import "Masonry.h"
#import "DQPlayerLayerView.h"
@interface DQPlayerView()
@property (nonatomic, strong) UIImageView *playImageV;
@property (nonatomic, strong) DQPlayerLayerView *playerView;
@property (nonatomic, strong) UIActivityIndicatorView *loadView;
@property (nonatomic, strong) UIButton *playBtn;
@property (nonatomic, strong) UIView *topView;
@property (nonatomic, strong) UILabel *titleL;
@property (nonatomic, strong) UIView *toolView;
@property (nonatomic, strong) UIButton *operaBtn;
@property (nonatomic, strong) UILabel *startL;
@property (nonatomic, strong) UISlider *slider;
@property (nonatomic, strong) UILabel *endL;
@property (nonatomic, strong) NSString *url;
@property (nonatomic, strong) AVPlayer *player;
@property (nonatomic, strong) AVPlayerItem *playItem;
@property (nonatomic, strong) id playTimeObserver;
@property (nonatomic, assign) BOOL isFail;
@property (nonatomic, assign) BOOL isBuffer;
@end
@implementation DQPlayerView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupView];
}
return self;
}
- (void)layoutSubviews {
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) {
if (inch_X) {
[_topView mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(20);
}];
}
}else{
if (inch_X) {
[_topView mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(NavigationBarHeight-44);
}];
}
}
}
- (void)dealloc {
[_player removeTimeObserver:_playTimeObserver];
}
- (void)setupView {
self.backgroundColor = rgb(0, 0, 0);
UIView *tapView = [[UIView alloc] init];
[PublicAction addTapGesture:tapView number:1 Target:self Sel:@selector(tapAction)];
//顶部栏
_topView = [[UIView alloc] init];
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[backBtn setImage:[UIImage imageNamed:@"app_icon_fh_bs"] forState:UIControlStateNormal];
[backBtn addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
[backBtn setLargeEdge:20];
_titleL = [[UILabel alloc] init];
_titleL.font = [UIFont boldSystemFontOfSize:17];
_titleL.textColor = kWhiteColor;
//播放页
_playerView = [[DQPlayerLayerView alloc] init];
//封面图
_playImageV = [[UIImageView alloc] init];
//加载
_loadView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
//播放按钮
_playBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_playBtn setImage:[UIImage imageNamed:@"app_icon_bf"] forState:UIControlStateNormal];
[_playBtn addTarget:self action:@selector(operaAction) forControlEvents:UIControlEventTouchUpInside];
_playBtn.hidden = YES;
//工具栏
_toolView = [[UIView alloc] init];
_operaBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpbf"] forState:UIControlStateNormal];
[_operaBtn addTarget:self action:@selector(operaAction) forControlEvents:UIControlEventTouchUpInside];
[_operaBtn setLargeEdge:20];
_startL = [[UILabel alloc] init];
_startL.font = [UIFont fontWithName:numFontBoldName size:15];
_startL.textColor = kWhiteColor;
_startL.textAlignment = NSTextAlignmentCenter;
_startL.text = @"00:00";
_slider = [[UISlider alloc] init];
[_slider setMinimumTrackImage:[UIImage imageNamed:@"app_img_jdt_2"] forState:UIControlStateNormal];
[_slider setMaximumTrackImage:[UIImage imageNamed:@"app_img_jdt_1"] forState:UIControlStateNormal];
[_slider setThumbImage:[UIImage imageNamed:@"app_img_hk"] forState:UIControlStateNormal];
[_slider setThumbImage:[UIImage imageNamed:@"app_img_hk"] forState:UIControlStateHighlighted];
[_slider addTarget:self action:@selector(sliderTouchBeginAction) forControlEvents:UIControlEventTouchDown];
[_slider addTarget:self action:@selector(sliderChangeAction) forControlEvents:UIControlEventValueChanged];
[_slider addTarget:self action:@selector(sliderTouchEndAction) forControlEvents:UIControlEventTouchUpInside];
_endL = [[UILabel alloc] init];
_endL.font = [UIFont fontWithName:numFontBoldName size:15];
_endL.textColor = kWhiteColor;
_endL.textAlignment = NSTextAlignmentCenter;
_endL.text = @"00:00";
UIButton *rotateBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[rotateBtn setImage:[UIImage imageNamed:@"app_icon_hspqh"] forState:UIControlStateNormal];
[rotateBtn addTarget:self action:@selector(rotateAction) forControlEvents:UIControlEventTouchUpInside];
[rotateBtn setLargeEdge:20];
[self addSubview:_playerView];
[_playerView addSubview:_playImageV];
[_playerView addSubview:_loadView];
[self addSubview:tapView];
[tapView addSubview:_playBtn];
[self addSubview:_topView];
[_topView addSubview:backBtn];
[_topView addSubview:_titleL];
[self addSubview:_toolView];
[_toolView addSubview:_operaBtn];
[_toolView addSubview:_startL];
[_toolView addSubview:_slider];
[_toolView addSubview:_endL];
[_toolView addSubview:rotateBtn];
[_playerView mas_makeConstraints:^(MASConstraintMaker *make) {
if(@available(iOS 11.0, *)) {
//横屏状态
make.left.mas_equalTo(self.mas_safeAreaLayoutGuideLeft);
make.right.mas_equalTo(self.mas_safeAreaLayoutGuideRight);
}else{
make.left.right.mas_equalTo(0);
}
make.center.mas_equalTo(0);
make.height.mas_equalTo(_playerView.mas_width).multipliedBy(9/16.0);
}];
[_playImageV mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(0);
}];
[_loadView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(_playerView);
}];
[_playBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(_playerView);
}];
[tapView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(0);
}];
[_topView mas_makeConstraints:^(MASConstraintMaker *make) {
if(@available(iOS 11.0, *)) {
//横屏状态
make.left.mas_equalTo(self.mas_safeAreaLayoutGuideLeft).mas_offset(12);
make.right.mas_equalTo(self.mas_safeAreaLayoutGuideRight).mas_offset(-16);
}else{
make.left.mas_equalTo(12);
make.right.mas_equalTo(-16);
}
make.height.mas_equalTo(44);
if (inch_X) {
make.top.mas_equalTo(NavigationBarHeight-44);
}else{
make.top.mas_equalTo(20);
}
}];
[backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(0);
make.centerY.mas_equalTo(0);
make.size.mas_equalTo(CGSizeMake(24, 24));
}];
[_titleL mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(backBtn.mas_right).mas_offset(2);
make.centerY.mas_equalTo(backBtn);
make.right.mas_equalTo(-100);
}];
[_toolView mas_makeConstraints:^(MASConstraintMaker *make) {
if(@available(iOS 11.0, *)) {
//横屏状态
make.left.mas_equalTo(self.mas_safeAreaLayoutGuideLeft).mas_offset(16);
make.right.mas_equalTo(self.mas_safeAreaLayoutGuideRight).mas_offset(-16);
}else{
make.left.mas_equalTo(16);
make.right.mas_equalTo(-16);
}
make.height.mas_equalTo(30);
make.bottom.mas_equalTo(-30);
}];
[_operaBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(0);
make.centerY.mas_equalTo(0);
make.size.mas_equalTo(CGSizeMake(22, 22));
}];
[_startL mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(_operaBtn.mas_right).mas_offset(10);
make.centerY.mas_equalTo(0);
make.width.mas_equalTo(36);
}];
[_slider mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(_startL.mas_right).mas_offset(10);
make.centerY.mas_equalTo(0);
}];
[_endL mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(_slider.mas_right).mas_offset(10);
make.centerY.mas_equalTo(0);
make.width.mas_equalTo(36);
}];
[rotateBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(_endL.mas_right).mas_offset(10);
make.right.mas_equalTo(0);
make.centerY.mas_equalTo(0);
make.size.mas_equalTo(CGSizeMake(22, 22));
}];
}
#pragma mark - 关闭
- (void)backAction {
if (self.closeBlock) {
self.closeBlock();
}
}
#pragma mark - 显示隐藏栏目
- (void)tapAction {
_topView.hidden = !_topView.hidden;
_toolView.hidden = !_toolView.hidden;
}
- (void)showToolView {
_topView.hidden = NO;
_toolView.hidden = NO;
}
- (void)hideToolView {
_topView.hidden = YES;
_toolView.hidden = YES;
}
#pragma mark - 拖拽播放
- (void)sliderTouchBeginAction {
[_player pause];
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpbf"] forState:UIControlStateNormal];
}
- (void)sliderChangeAction {
NSTimeInterval currentTime = _slider.value * CMTimeGetSeconds(_player.currentItem.duration);
[self setStartTime:currentTime];
}
- (void)sliderTouchEndAction {
NSTimeInterval changedTime = _slider.value * CMTimeGetSeconds(_player.currentItem.duration);
if (changedTime == CMTimeGetSeconds(_player.currentItem.duration)) {
changedTime -= 0.5;
}
[_player.currentItem seekToTime:CMTimeMakeWithSeconds(changedTime,NSEC_PER_SEC)];
_playImageV.hidden = YES;
[_player play];
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpzt"] forState:UIControlStateNormal];
_playBtn.hidden = YES;
}
#pragma mark - 旋转
- (void)rotateAction {
//强制转屏
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
SEL selector = NSSelectorFromString([NSString stringWithFormat:@"%@%@",@"setOrien",@"tation:"]);
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val;
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
if (orientation == UIDeviceOrientationPortrait) {
val = UIInterfaceOrientationLandscapeRight;
}else{
val = UIInterfaceOrientationPortrait;
}
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
}
#pragma mark - 标题
- (void)setPlayTitle:(NSString *)playTitle {
_playTitle = playTitle;
_titleL.text = playTitle;
}
- (void)setPlayImageUrl:(NSString *)playImageUrl {
[PublicAction setImageView:_playImageV withImage:playImageUrl placeHolderImage:placeHold208];
}
#pragma mark - 播放
- (void)playWithUrl:(NSString *)url {
_playImageV.hidden = NO;
[_loadView startAnimating];
_url = url;
AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:url]];
if (_player) {
[_player replaceCurrentItemWithPlayerItem:item];
}else{
_player = [[AVPlayer alloc] initWithPlayerItem:item];
[((AVPlayerLayer *)_playerView.layer) setPlayer:_player];
_player.muted = YES;//默认静音
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playFinishNotification:) name:AVPlayerItemDidPlayToEndTimeNotification object:item];
}
if (@available(iOS 10.0, *)) {
_player.automaticallyWaitsToMinimizeStalling = NO;//坑坑坑,要加不然会卡主第一帧很久才播放
}
__weak typeof(self) weakSelf = self;
//状态
[self.KVOController observe:item keyPath:@"status" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSString *,id> * _Nonnull change) {
__strong typeof(weakSelf) strongSelf = weakSelf;
AVPlayerItem *item = (AVPlayerItem *)object;
if (item.status == AVPlayerItemStatusReadyToPlay) {
strongSelf.isFail = NO;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[strongSelf.loadView stopAnimating];
strongSelf.playImageV.hidden = YES;
if ([BaseNetWork networkType]==ReachableViaWiFi) {
[strongSelf continuePlay];
}
});
CMTime duration = item.duration;
[strongSelf setEndTime:CMTimeGetSeconds(duration)];
}else if(item.status == AVPlayerItemStatusFailed){
strongSelf.isFail = YES;
[strongSelf.loadView stopAnimating];
[PublicAction showHudOnlyText:@"视频加载失败" view:firstView hideDelay:hudDurTime];
if (strongSelf.endBlock) {
strongSelf.endBlock();
}
}
}];
//缓冲
[self.KVOController observe:item keyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSString *,id> * _Nonnull change) {
__strong typeof(weakSelf) strongSelf = weakSelf;
NSArray *loadedTimeRanges = [[strongSelf.player currentItem] loadedTimeRanges];
CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域
float startSeconds = CMTimeGetSeconds(timeRange.start);
float durationSeconds = CMTimeGetSeconds(timeRange.duration);
NSTimeInterval result = startSeconds + durationSeconds;// 计算缓冲总进度
NSTimeInterval current = strongSelf.player.currentTime.value/strongSelf.player.currentTime.timescale;//当前播放进度
if (strongSelf.isPlay && (result>current+2 || result==CMTimeGetSeconds(strongSelf.player.currentItem.duration))) {
if (strongSelf.isBuffer) {
strongSelf.isBuffer = NO;
[strongSelf.loadView stopAnimating];
[strongSelf.player play];
}
}
}];
//缓冲
[self.KVOController observe:item keyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSString *,id> * _Nonnull change) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf.isPlay && !strongSelf.isBuffer) {
strongSelf.isBuffer = YES;
[strongSelf.loadView startAnimating];
[strongSelf.player pause];
}
}];
// 每秒回调一次
_playTimeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
__strong typeof(weakSelf) strongSelf = weakSelf;
NSTimeInterval totalTime = CMTimeGetSeconds(strongSelf.player.currentItem.duration);//总时长
NSTimeInterval currentTime = time.value / time.timescale;//当前时间进度
strongSelf.slider.value = currentTime / totalTime;
[strongSelf setStartTime:currentTime];
}];
}
#pragma mark - 设置时长
- (void)setEndTime:(CGFloat)second {
NSString *time = [PublicAction stringFromDate:[NSDate dateWithTimeIntervalSince1970:second] form:@"mm:ss"];
_endL.text = time;
}
- (void)setStartTime:(CGFloat)second {
NSString *time = [PublicAction stringFromDate:[NSDate dateWithTimeIntervalSince1970:second] form:@"mm:ss"];
_startL.text = time;
}
- (void)playFinishNotification:(NSNotification *)noti {
[self stop];
}
#pragma mark - 停止
- (void)stop {
_isPlay = NO;
if (_player) {
[_player.currentItem cancelPendingSeeks];
[_player.currentItem.asset cancelLoading];
[_player pause];
[_player.currentItem seekToTime:kCMTimeZero];
_playImageV.hidden = NO;
[_loadView stopAnimating];
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpbf"] forState:UIControlStateNormal];
_playBtn.hidden = NO;
}
if (self.endBlock) {
self.endBlock();
}
}
#pragma mark - 继续
- (void)continuePlay {
if (!_isPlay) {
[_player play];
_isPlay = YES;
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpzt"] forState:UIControlStateNormal];
_playBtn.hidden = YES;
}
}
#pragma mark - 暂停
- (void)pausePlay {
if (_isPlay) {
[_player pause];
_isPlay = NO;
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpbf"] forState:UIControlStateNormal];
_playBtn.hidden = NO;
}
}
#pragma mark - 操作
- (void)operaAction {
if (_isPlay) {
_playImageV.hidden = NO;
[_loadView stopAnimating];
[_player pause];
_isPlay = NO;
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpbf"] forState:UIControlStateNormal];
_playBtn.hidden = NO;
}else{
if (_isFail) {
[self playWithUrl:_url];
}else{
_playImageV.hidden = YES;
[_player play];
_isPlay = YES;
[_operaBtn setImage:[UIImage imageNamed:@"app_icon_qpzt"] forState:UIControlStateNormal];
_playBtn.hidden = YES;
}
}
}
#pragma mark - 静音
- (void)onMute {
_player.muted = YES;
}
- (void)offMute {
_player.muted = NO;
}
@end