显示下载进度条,支持边下载边播放。想支持边下边播放需要把视频文件放到指定类型的服务器上,服务器不支持流媒体类型无法支持该功能。
支持整屏播放和缩小屏幕播放。
整屏播放示例:
*vpcView = [[BGVideoPlayerContainerView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width)];
[self.view addSubview:vpcView];
[vpcView updateWithWaitTime:[self.entity.watch_video_minutes integerValue] urlVideo:self.entity.part_course_video logo:nil playImage:[UIImage imageNamed:@"play_icon"] isShowPlayTime:NO isStartPlay:YES];
缩小局部播放代码示例:
-(BGVideoPlayerContainerView *)vpcView{
if (!_vpcView) {
_vpcView = [[BGVideoPlayerContainerView alloc]initWithFrame:CGRectMake(0, 0, sCommonUnitFullWidth(), 217.5*FULL_WIDTH/375)];
[self.contentView addSubview:_vpcView];
}
return _vpcView;
}
[self.vpcView updateWithWaitTime:waitTime urlVideo:videoUrl logo:logo playImage:[UIImage imageNamed:@"play_icon"] isShowPlayTime:YES isStartPlay:NO];
BGVideoPlayerToolsView.h
#import
#define
@protocol BGVideoPlayerToolsViewDelegate <NSObject>
-(void)playButtonWithStates:(BOOL)state;
@end
@interface BGVideoPlayerToolsView : UIView
@property (nonatomic, strong) UIButton *bCheck;//播放暂停按钮
@property (nonatomic, strong) UISlider *progressSr;//进度条
@property (nonatomic, strong) UIProgressView *bufferPV;//缓冲条
@property (nonatomic, strong) UILabel *lTime;//时间进度和总时长
@property (nonatomic, strong) UIActivityIndicatorView * activityIndicator;
@property (nonatomic, weak) id<BGVideoPlayerToolsViewDelegate> delegate;
BGVideoPlayerToolsView.m
#import
@interface BGVideoPlayerToolsView ()
@end
@implementation BGVideoPlayerToolsView
-(instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.01];
[self createUI];//创建UI
}
return self;
}
#pragma
-(void)createUI{
[self addSubview:self.bCheck];//开始暂停按钮
[self addSubview:self.bufferPV];//缓冲条
[self addSubview:self.progressSr];//创建进度条
[self addSubview:self.lTime];//视频时间
[self addSubview:self.activityIndicator];
}
#pragma
-(UILabel *)lTime{
if (!_lTime) {
_lTime = [UILabel new];
_lTime.frame = CGRectMake(CGRectGetMaxX(_progressSr.frame) + 20, 0, self.frame.size.width - CGRectGetWidth(_progressSr.frame) - 40 - CGRectGetWidth(_bCheck.frame), self.frame.size.height);
_lTime.text = @"00:00/00:00";
_lTime.textColor = [UIColor whiteColor];
_lTime.textAlignment = NSTextAlignmentCenter;
_lTime.font = [UIFont systemFontOfSize:12];
_lTime.adjustsFontSizeToFitWidth = YES;
}
return _lTime;
}
#pragma
-(UISlider *)progressSr{
if (!_progressSr) {
_progressSr = [UISlider new];
_progressSr.frame = CGRectMake(CGRectGetMinX(_bufferPV.frame) - 2, CGRectGetMidY(_bufferPV.frame) - 10, CGRectGetWidth(_bufferPV.frame) - 4+10, 20);
_progressSr.maximumTrackTintColor = [UIColor clearColor];
_progressSr.minimumTrackTintColor = [UIColor whiteColor];
[_progressSr setThumbImage:[UIImage imageNamed:@"point"] forState:0];
}
return _progressSr;
}
#pragma
-(UIProgressView *)bufferPV{
if (!_bufferPV) {
_bufferPV = [UIProgressView new];
_bufferPV.frame = CGRectMake(CGRectGetMaxX(_bCheck.frame) + 20, CGRectGetMidY(_bCheck.frame) - 2, 200, 4);
_bufferPV.trackTintColor = [UIColor grayColor];
_bufferPV.progressTintColor = [UIColor cyanColor];
}
return _bufferPV;
}
-(UIActivityIndicatorView *)activityIndicator{
if (!_activityIndicator) {
// _activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyleWhite)];
_activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyleGray)];
//设置小菊花的frame
_activityIndicator.frame= CGRectMake(80, 10, 20, 20);
//设置小菊花颜色
_activityIndicator.color = [UIColor redColor];
//设置背景颜色
_activityIndicator.backgroundColor = [UIColor clearColor];
//刚进入这个界面会显示控件,并且停止旋转也会显示,只是没有在转动而已,没有设置或者设置为YES的时候,刚进入页面不会显示
_activityIndicator.hidesWhenStopped = NO;
}
return _activityIndicator;
}
#pragma
-(UIButton *)bCheck{
if (!_bCheck) {
_bCheck = [UIButton new];
_bCheck.frame = CGRectMake(50, 0, self.frame.size.height, self.frame.size.height);
[_bCheck setImage:[UIImage imageNamed:@"pause"] forState:0];
[_bCheck addTarget:self action:@selector(btnCheckSelect:) forControlEvents:UIControlEventTouchUpInside];
}
return _bCheck;
}
-(void)btnCheckSelect:(UIButton *)sender{
sender.selected = !sender.isSelected;
if (sender.selected) {
[_bCheck setImage:[UIImage imageNamed:@"play"] forState:0];
}else{
[_bCheck setImage:[UIImage imageNamed:@"pause"] forState:0];
}
if ([_delegate respondsToSelector:@selector(playButtonWithStates:)]) {
[_delegate playButtonWithStates:sender.selected];
}
}
BGVideoPlayerContainerView.h
#import
NS_ASSUME_NONNULL_BEGIN
@interface BGVideoPlayerContainerView : UIView
@property (nonatomic, strong) NSString *urlVideo;
@property (nonatomic, strong) UIImage *playImage;
//@property (nonatomic, strong) NSString *videoUrl;
@property (nonatomic, strong) NSString *logo;
@property (nonatomic, assign) NSInteger waitTime;
@property (nonatomic, assign) BOOL isShowPlayTime;
@property (nonatomic, assign) BOOL isStartPlay;
-(void)dealloc;
- (void)updateWithWaitTime:(NSInteger)waitTime urlVideo:(NSString *)urlVideo logo:(NSString *)logo playImage:(UIImage *)playImage isShowPlayTime:(BOOL)isShowPlayTime isStartPlay:(BOOL)isStartPlay;
BGVideoPlayerContainerView.m
#import
#import
#import
#import
#import
#import
#import
@interface BGVideoPlayerContainerView ()<BGVideoPlayerToolsViewDelegate>
@property (nonatomic, strong) AVPlayer *player;
@property (nonatomic, strong) AVPlayerLayer *playerLayer;
//@property (nonatomic, strong) NetworkSpeedMonitor *speedMonitor;//网速监听
@property (nonatomic, strong) UILabel *speedTextLabel;//显示网速Label
@property (nonatomic, strong) BGVideoPlayerToolsView *vpToolsView;//工具条
@property (nonatomic, strong) id playbackObserver;
@property (nonatomic) BOOL buffered;//是否缓冲完毕
@property (nonatomic) BOOL isLoad;
@property (nonatomic) BOOL isStartBuffer;
@property (nonatomic, strong) UILabel *describeTitleLabel;
@property (nonatomic, strong) UIView *bigBackgroundView;
@property (nonatomic, strong) UIImageView *photoImageView;
@property (nonatomic, strong) UIImageView *iconImageView;
@property (nonatomic, strong) UIButton *playButton;
@property (nonatomic, assign) BOOL isPlay;
@property (nonatomic, assign) BOOL isAuditionOver;
@property (nonatomic, assign) float progress;
@end
@implementation BGVideoPlayerContainerView
设置播放地址
//-(void)setUrlVideo:(NSString *)urlVideo{
//
// [self.player seekToTime:CMTimeMakeWithSeconds(0, NSEC_PER_SEC) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
// [self.player play];//开始播放视频
[self updatePlayBtn];
[self.speedMonitor startNetworkSpeedMonitor];//开始监听网速
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkSpeedChanged:) name:NetworkDownloadSpeedNotificationKey object:nil];
// _urlVideo = urlVideo;
// AVPlayerItem *item = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:urlVideo]];
// [self vpc_addObserverToPlayerItem:item];
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// [self.player replaceCurrentItemWithPlayerItem:item];
// [self vpc_playerItemAddNotification];
// });
//
//}
//设置播放地址
-(void)startBuffer
{
[self.player seekToTime:CMTimeMakeWithSeconds(0, NSEC_PER_SEC) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
[self.player play];//开始播放视频
// [self updatePlayBtn];
// [self.speedMonitor startNetworkSpeedMonitor];//开始监听网速
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkSpeedChanged:) name:NetworkDownloadSpeedNotificationKey object:nil];
// _urlVideo = urlVideo;
AVPlayerItem *item = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:self.urlVideo]];
[self vpc_addObserverToPlayerItem:item];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self.player replaceCurrentItemWithPlayerItem:item];
[self vpc_playerItemAddNotification];
});
self.isStartBuffer = YES;
[self.vpToolsView.activityIndicator startAnimating];
}
-(instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor blackColor];//[UIColor groupTableViewBackgroundColor];
[self.layer addSublayer:self.playerLayer];
[self addSubview:self.speedTextLabel];
[self addSubview:self.vpToolsView];
[self setupViewWithFrame:frame];
}
return self;
}
-(void)setupViewWithFrame:(CGRect)frame
{
self.backgroundColor = [UIColor blackColor];
// self.bigBackgroundView = [[UIView alloc]init];
// self.bigBackgroundView.backgroundColor = [UIColor clearColor];
// [self addSubview:self.bigBackgroundView];
self.frame = frame;
[self addSubview:self.photoImageView];
[self addSubview:self.playButton];
[self addSubview:self.iconImageView];
[self addSubview:self.describeTitleLabel];
[self unitsSdLayout];
// @weakify(self);
// [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil] subscribeNext:^(id x) {
// @strongify(self);
// [self.player pause];
// self.isPlay = NO;
// self.vpToolsView.hidden = !self.isStartPlay;
// [self updatePlayBtn];
// [[BITNoticeView currentNotice] showErrorNotice:@"试听结束"];
// }];
// [BGCommonCustomTimer sharedInstance].scanningTimerCallBack = ^{
// @strongify(self);
// if(self.waitTime >0)
// {
// long long timeInterval = (self.startTime + self.waitTime*60000 - (long long)([[NSDate date] timeIntervalSince1970]*1000 + [BITSingleObject sharedInstance].localServerDifferenceTime))/1000 -113;
// NSLog(@"timeInterval:%lld, self.waitTime:%d", timeInterval, self.waitTime);
// if(timeInterval <= 0)
// {
self.isNotFirstPlay = YES;
// [self stopTime];
// }
// else if(timeInterval > self.waitTime*60000)
// {
self.isNotFirstPlay = YES;
// [self stopTime];
// }
// else
// {
long long minute = timeInterval / 60;
self.describeTitleLabel.text = [NSString stringWithFormat:@"%lld:%lld", minute, timeInterval % 60];
//
// }
// }
// else
// {
// self.hidden = YES;
// }
// };
}
-(void)unitsSdLayout
{
// self.bigBackgroundView.sd_layout
// .topSpaceToView(self, 0)
// .leftSpaceToView(self, 0)
// .widthIs(self.frame.size.width)
// .heightIs(self.frame.size.height);
self.photoImageView.sd_layout
.topSpaceToView(self, 0)
.leftSpaceToView(self, 0)
.widthIs(self.frame.size.width)
.heightIs(self.frame.size.height);
self.iconImageView.sd_layout
.centerYEqualToView(self)
.centerXEqualToView(self)
.widthIs(80)
.heightIs(80);
// self.playButton.backgroundColor = [UIColor redColor];
self.playButton.sd_layout
.topSpaceToView(self, 0)
.leftSpaceToView(self, 0)
.widthIs(self.frame.size.width)
.heightIs(self.frame.size.height-50);
self.describeTitleLabel.sd_layout
.topSpaceToView(self.iconImageView, 10)
.leftSpaceToView(self, 15)
.rightSpaceToView(self, 15)
.heightIs(14);
// [self.describeTitleLabel setSingleLineAutoResizeWithMaxWidth:200];
}
- (void)updateWithWaitTime:(NSInteger)waitTime urlVideo:(NSString *)urlVideo logo:(NSString *)logo playImage:(UIImage *)playImage isShowPlayTime:(BOOL)isShowPlayTime isStartPlay:(BOOL)isStartPlay
{
if(self.waitTime > 0 && [self achiveStringWithWeb:urlVideo])
{
if(!self.isLoad)
{
[self.layer addSublayer:self.playerLayer];
[self addSubview:self.speedTextLabel];
[self addSubview:self.vpToolsView];
self.isLoad = YES;
}
}
self.waitTime = waitTime;
self.logo = logo;
self.playImage = playImage;
self.isShowPlayTime = isShowPlayTime;
self.isStartPlay = isStartPlay;
self.isStartBuffer = NO;
if([self achiveStringWithWeb:urlVideo])
{
// self.bigBackgroundView.hidden = isStartPlay;
self.urlVideo = urlVideo;
if(isStartPlay)
{
[self startBuffer];
// self.playButton.hidden = YES;
self.photoImageView.hidden = YES;
self.iconImageView.hidden = YES;
self.describeTitleLabel.hidden = YES;
self.isPlay = YES;
}
else
{
self.isPlay = NO;
[self updatePlayBtn];
[self.player pause];
}
self.vpToolsView.hidden = !isStartPlay;
}
else
{
self.vpToolsView.hidden = YES;
self.isPlay = NO;
// self.playButton.hidden = YES;
self.photoImageView.hidden = YES;
self.iconImageView.hidden = YES;
self.describeTitleLabel.hidden = YES;
}
}
- (BOOL)achiveStringWithWeb:(NSString *)infor
{
if([infor isKindOfClass:[NSNull class]] || infor == nil || ![infor isKindOfClass:[NSString class]])
{
return NO;
}
NSString *emailRegex = @"[a-zA-z]+://.*";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
return [emailTest evaluateWithObject:infor];
}
-(void)setPlayImage:(UIImage *)playImage
{
if(playImage)
{
_playImage = playImage;
self.iconImageView.image = playImage;
self.iconImageView.sd_layout
.centerYEqualToView(self)
.centerXEqualToView(self)
.widthIs(self.playImage.size.width)
.heightIs(self.playImage.size.width);
[self.iconImageView updateLayout];
[self.describeTitleLabel updateLayout];
}
}
-(void)setIsShowPlayTime:(BOOL)isShowPlayTime
{
_isShowPlayTime = isShowPlayTime;
self.describeTitleLabel.hidden = !isShowPlayTime;
if(isShowPlayTime)
{
if(self.waitTime == 10000000)
{
self.describeTitleLabel.hidden = YES;
}
else
{
self.describeTitleLabel.hidden = NO;
self.describeTitleLabel.text = [NSString stringWithFormat:@"可试听%ld分钟", self.waitTime];
}
[self.iconImageView updateLayout];
[self.describeTitleLabel updateLayout];
}
}
-(void)setLogo:(NSString *)logo
{
if([self achiveStringWithWeb:logo])
{
[self.photoImageView sd_setImageWithURL:[NSURL URLWithString:logo]];
// self.photoImageView.hidden = NO;
if([self achiveStringWithWeb:logo])
{
// [self.photoImageView sd_setImageWithURL:[NSURL URLWithString:logo]];
self.photoImageView.hidden = NO;
}
else
{
self.photoImageView.hidden = YES;
}
}
else
{
self.photoImageView.hidden = YES;
}
_logo = logo;
}
- (UILabel *)describeTitleLabel {
if(!_describeTitleLabel)
{
_describeTitleLabel = [self createLabel];
_describeTitleLabel.backgroundColor = [UIColor clearColor];
_describeTitleLabel.text = @"可试听5分钟";//[NSString stringWithFormat:@"可试听%ld分钟", self.waitTime];
_describeTitleLabel.font = [UIFont systemFontOfSize:14];
_describeTitleLabel.textColor = [UIColor whiteColor];
_describeTitleLabel.textAlignment = NSTextAlignmentCenter;
_describeTitleLabel.hidden = YES;
}
return _describeTitleLabel;
}
- (UIButton *)playButton {
if (!_playButton)
{
_playButton = [[UIButton alloc] init];
[_playButton setTitle:@"" forState:UIControlStateNormal];
// [_playButton setImage:[UIImage imageNamed:@"play_icon"] forState:UIControlStateNormal];
_playButton.backgroundColor = [UIColor clearColor];
_playButton.userInteractionEnabled = YES;
// _playButton.hidden = YES;
@weakify(self);
[[_playButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
@strongify(self);
if(self.isAuditionOver)
{
[self.player pause];
self.isPlay = NO;
self.vpToolsView.hidden = !self.isStartPlay;
[self updatePlayBtn];
[[BITNoticeView currentNotice] showErrorNotice:@"试听结束"];
return;
}
if (self.isPlay) {
[self.player pause];
self.isPlay = NO;
self.vpToolsView.hidden = !self.isStartPlay;
}else{
self.vpToolsView.hidden = NO;
if(!self.isStartBuffer)
{
[self startBuffer];
}
else
{
[self.player play];
}
self.isPlay = YES;
}
[self updatePlayBtn];
// if(self.isNotFirstPlay || self.waitTime <= 0)
// [self startPlay];
}];
}
return _playButton;
}
- (UIImageView *)photoImageView {
if(!_photoImageView)
{
_photoImageView = [self createImageView];
// [_photoImageView.layer setMasksToBounds:YES];
_photoImageView.contentMode = UIViewContentModeScaleAspectFit;//等比缩放把图片整体显示在ImageView中,所以可能会出现ImageView有空白部分 ;//等比缩放图片把整个ImageView填充满,所以可能会出现图片部分显示不出来
_photoImageView.clipsToBounds = YES;
// _photoImageView.contentMode = UIViewContentModeScaleAspectFill;//等比缩放图片把整个ImageView填充满,所以可能会出现图片部分显示不出来
_photoImageView.hidden = NO;
_photoImageView.backgroundColor = [UIColor clearColor];
_photoImageView.userInteractionEnabled = YES;
}
return _photoImageView;
}
-(UILabel *)createLabel
{
UILabel *label = [[UILabel alloc] init];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentLeft;
label.font = [UIFont systemFontOfSize:14];
label.textColor = [UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1];
label.text = @"";
return label;
}
- (UIImageView *)createImageView {
UIImageView *imageView = [[UIImageView alloc] init];
imageView.contentMode = UIViewContentModeScaleAspectFit;//等比缩放把图片整体显示在ImageView中,所以可能会出现ImageView有空白部分 UIViewContentModeScaleAspectFill;//等比缩放图片把整个ImageView填充满,所以可能会出现图片部分显示不出来
imageView.clipsToBounds = YES;
imageView.backgroundColor = [UIColor whiteColor];
return imageView;
}
- (UIImageView *)iconImageView {
if(!_iconImageView)
{
_iconImageView= [[UIImageView alloc] init];
_iconImageView.contentMode = UIViewContentModeScaleAspectFit;//等比缩放把图片整体显示在ImageView中,所以可能会出现ImageView有空白部分 UIViewContentModeScaleAspectFill;//等比缩放图片把整个ImageView填充满,所以可能会出现图片部分显示不出来
_iconImageView.clipsToBounds = YES;
_iconImageView.backgroundColor = [UIColor clearColor];
_iconImageView.image = [UIImage imageNamed:@"play_icon"];
// [_iconImageView addCornerWithCornerRadius:75.0/2];
}
return _iconImageView;
}
-(void)updatePlayBtn
{
if([self achiveStringWithWeb:self.urlVideo])
{
self.playButton.hidden = NO;
if([self achiveStringWithWeb:self.logo])
{
// [self.photoImageView sd_setImageWithURL:[NSURL URLWithString:logo]];
self.photoImageView.hidden = NO;
self.photoImageView.hidden = self.isPlay;
}
else
{
self.photoImageView.hidden = YES;
}
// self.photoImageView.hidden = NO;
self.iconImageView.hidden = self.isPlay;
self.describeTitleLabel.hidden = self.isPlay;
// [self.playButton setImage:[UIImage imageNamed:@"play_icon"] forState:UIControlStateNormal];
// [self.photoImageView sd_setImageWithURL:[NSURL URLWithString:self.entity.pic]];
}
else
{
self.playButton.hidden = YES;
self.photoImageView.hidden = YES;
self.iconImageView.hidden = YES;
self.describeTitleLabel.hidden = YES;
}
}
//- (void)networkSpeedChanged:(NSNotification *)sender {
// NSString *downloadSpped = [sender.userInfo objectForKey:NetworkSpeedNotificationKey];
// self.speedTextLabel.text = downloadSpped;
//}
#pragma
-(BGVideoPlayerToolsView *)vpToolsView{
if (!_vpToolsView) {
_vpToolsView = [[BGVideoPlayerToolsView alloc]initWithFrame:CGRectMake(0, CGRectGetHeight(self.frame) - (40+kVideoPlayerMainBottomHeightShift), CGRectGetWidth(self.frame), 40)];
_vpToolsView.delegate = self;
// _vpToolsView.progressSr.backgroundColor = [UIColor redColor];
[_vpToolsView.progressSr addTarget:self action:@selector(vpc_sliderTouchBegin:) forControlEvents:UIControlEventTouchDown];
[_vpToolsView.progressSr addTarget:self action:@selector(vpc_sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
[_vpToolsView.progressSr addTarget:self action:@selector(vpc_sliderTouchEnd:) forControlEvents:UIControlEventTouchUpInside];
}
return _vpToolsView;
}
-(void)playButtonWithStates:(BOOL)state{
// if (state) {
// [self.player pause];
// }else{
// [self.player play];
// }
}
- (void)vpc_sliderTouchBegin:(UISlider *)sender {
if(self.isAuditionOver)
{
[self.player pause];
self.isPlay = NO;
self.vpToolsView.hidden = !self.isStartPlay;
[self updatePlayBtn];
[[BITNoticeView currentNotice] showErrorNotice:@"试听结束"];
return;
}
if (self.isPlay) {
[self.player pause];
self.isPlay = NO;
self.vpToolsView.hidden = !self.isStartPlay;
}else{
self.vpToolsView.hidden = NO;
if(!self.isStartBuffer)
{
[self startBuffer];
}
else
{
[self.player play];
}
self.isPlay = YES;
}
[self updatePlayBtn];
}
#pragma
//- (void)updateProgress:(UISlider *)slider{
// [self.player seekToTime:CMTimeMakeWithSeconds(slider.value, self.player.currentItem.currentTime.timescale)];
//}
- (void)vpc_sliderValueChanged:(UISlider *)sender {
NSTimeInterval currentTime = CMTimeGetSeconds(self.player.currentItem.duration) * _vpToolsView.progressSr.value;
NSInteger currentMin = currentTime / 60;
NSInteger currentSec = (NSInteger)currentTime % 60;
_vpToolsView.lTime.text = [NSString stringWithFormat:@"%02ld:%02ld",currentMin,currentSec];
NSLog(@"time:%@, _vpToolsView.progressSr.value:%f", [NSString stringWithFormat:@"%02ld:%02ld",currentMin,currentSec], _vpToolsView.progressSr.value);
// if(self.isAuditionOver || currentMin >= self.waitTime)
// {
// if(!self.isAuditionOver)
// {
// [self.player pause];
// self.isPlay = NO;
// self.vpToolsView.hidden = !self.isStartPlay;
// [self updatePlayBtn];
// [[BITNoticeView currentNotice] showErrorNotice:@"试听结束"];
// return;
// }
self.isAuditionOver = YES;
// if (self.isPlay) {
// [self.player pause];
// self.isPlay = NO;
// self.vpToolsView.hidden = !self.isStartPlay;
// }else{
// self.vpToolsView.hidden = NO;
// if(!self.isStartBuffer)
// {
// [self startBuffer];
// }
// else
// {
// [self.player play];
// }
// self.isPlay = YES;
// }
// [self updatePlayBtn];
// }
}
- (void)vpc_sliderTouchEnd:(UISlider *)sender {
if(self.isAuditionOver)
{
[self.player pause];
self.isPlay = NO;
self.vpToolsView.hidden = !self.isStartPlay;
[self updatePlayBtn];
[[BITNoticeView currentNotice] showErrorNotice:@"试听结束"];
return;
}
NSTimeInterval currentTime = CMTimeGetSeconds(self.player.currentItem.duration) * _vpToolsView.progressSr.value;
NSInteger currentMin = currentTime / 60;
NSInteger currentSec = (NSInteger)currentTime % 60;
_vpToolsView.lTime.text = [NSString stringWithFormat:@"%02ld:%02ld",currentMin,currentSec];
NSLog(@"time:%@, _vpToolsView.progressSr.value:%f", [NSString stringWithFormat:@"%02ld:%02ld",currentMin,currentSec], _vpToolsView.progressSr.value);
if(self.isAuditionOver || currentMin >= self.waitTime)
{
[self.player pause];
self.isPlay = NO;
self.vpToolsView.hidden = !self.isStartPlay;
[self updatePlayBtn];
[[BITNoticeView currentNotice] showErrorNotice:@"试听结束"];
return;
// if(!self.isAuditionOver)
// {
// [self.player pause];
// self.isPlay = NO;
// self.vpToolsView.hidden = !self.isStartPlay;
// [self updatePlayBtn];
// [[BITNoticeView currentNotice] showErrorNotice:@"试听结束"];
// return;
// }
// self.isAuditionOver = YES;
}
else if(self.progress <= _vpToolsView.progressSr.value)
{
// if (self.isPlay) {
// [self.player pause];
// self.isPlay = NO;
// self.vpToolsView.hidden = !self.isStartPlay;
// }else{
self.vpToolsView.hidden = NO;
if(!self.isStartBuffer)
{
[self startBuffer];
}
else
{
[self.player play];
}
self.isPlay = YES;
// }
[self updatePlayBtn];
return;
}
self.isPlay = YES;
NSTimeInterval slideTime = CMTimeGetSeconds(self.player.currentItem.duration) * _vpToolsView.progressSr.value;
if (slideTime == CMTimeGetSeconds(self.player.currentItem.duration)) {
slideTime -= 0.5;
}
[self.player seekToTime:CMTimeMakeWithSeconds(slideTime, NSEC_PER_SEC) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
// [self.player play];
self.vpToolsView.hidden = NO;
if(!self.isStartBuffer)
{
[self startBuffer];
}
else
{
[self.player play];
}
self.isPlay = YES;
[self updatePlayBtn];
}
//#pragma mark - 网速监听器
//- (NetworkSpeedMonitor *)speedMonitor {
// if (!_speedMonitor) {
// _speedMonitor = [[NetworkSpeedMonitor alloc] init];
// }
// return _speedMonitor;
//}
#pragma
- (UILabel *)speedTextLabel {
if (!_speedTextLabel) {
_speedTextLabel = [UILabel new];
_speedTextLabel.frame = CGRectMake(0, 0, self.frame.size.width, 20);
_speedTextLabel.textColor = [UIColor whiteColor];
_speedTextLabel.font = [UIFont systemFontOfSize:12.0];
_speedTextLabel.textAlignment = NSTextAlignmentCenter;
_speedTextLabel.hidden = YES;
_speedTextLabel.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
}
return _speedTextLabel;
}
#pragma
-(AVPlayer *)player{
if (!_player) {
_player = [[AVPlayer alloc] init];
__weak typeof(self) weakSelf = self;
// 每秒回调一次
self.playbackObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) {
[weakSelf vpc_setTimeLabel];
NSTimeInterval totalTime = CMTimeGetSeconds(weakSelf.player.currentItem.duration);//总时长
NSTimeInterval currentTime = time.value / time.timescale;//当前时间进度
weakSelf.vpToolsView.progressSr.value = currentTime / totalTime;
}];
}
return _player;
}
#pragma
-(AVPlayerLayer *)playerLayer{
if (!_playerLayer) {
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
_playerLayer.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
}
return _playerLayer;
}
#pragma
#pragma
- (void)vpc_setTimeLabel {
NSTimeInterval totalTime = CMTimeGetSeconds(self.player.currentItem.duration);//总时长
NSTimeInterval currentTime = CMTimeGetSeconds(self.player.currentTime);//当前时间进度
// 切换视频源时totalTime/currentTime的值会出现nan导致时间错乱
if (!(totalTime >= 0) || !(currentTime >= 0)) {
totalTime = 0;
currentTime = 0;
}
NSInteger totalMin = totalTime / 60;
NSInteger totalSec = (NSInteger)totalTime % 60;
NSString *totalTimeStr = [NSString stringWithFormat:@"%02ld:%02ld",totalMin,totalSec];
NSInteger currentMin = currentTime / 60;
NSInteger currentSec = (NSInteger)currentTime % 60;
NSString *currentTimeStr = [NSString stringWithFormat:@"%02ld:%02ld",currentMin,currentSec];
_vpToolsView.lTime.text = [NSString stringWithFormat:@"%@/%@",currentTimeStr,totalTimeStr];
NSLog(@"time:%@", [NSString stringWithFormat:@"%@/%@",currentTimeStr,totalTimeStr]);
if(self.isAuditionOver || currentMin >= self.waitTime)
{
if(!self.isAuditionOver)
{
[[BITNoticeView currentNotice] showErrorNotice:@"试听结束"];
}
self.isAuditionOver = YES;
if (self.isPlay) {
[self.player pause];
self.isPlay = NO;
self.vpToolsView.hidden = !self.isStartPlay;
}else{
self.vpToolsView.hidden = NO;
if(!self.isStartBuffer)
{
[self startBuffer];
}
else
{
[self.player play];
}
self.isPlay = YES;
}
[self updatePlayBtn];
}
}
#pragma
- (void)vpc_playerItemAddNotification {
// 播放完成通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(vpc_playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}
-(void)vpc_playbackFinished:(NSNotification *)noti{
[_vpToolsView.progressSr setValue:1.0];
[self.player pause];
}
- (void)vpc_addObserverToPlayerItem:(AVPlayerItem *)playerItem {
// 监听播放状态
[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
// 监听缓冲进度
[playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)vpc_playerItemRemoveNotification {
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}
- (void)vpc_playerItemRemoveObserver {
[self.player.currentItem removeObserver:self forKeyPath:@"status"];
[self.player.currentItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"status"]) {
AVPlayerStatus status= [[change objectForKey:@"new"] intValue];
if (status == AVPlayerStatusReadyToPlay) {
self.isPlay = YES;
[self vpc_setTimeLabel];
}
} else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
NSArray *array = self.player.currentItem.loadedTimeRanges;
CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次缓冲时间范围
NSTimeInterval startSeconds = CMTimeGetSeconds(timeRange.start);//本次缓冲起始时间
NSTimeInterval durationSeconds = CMTimeGetSeconds(timeRange.duration);//缓冲时间
NSTimeInterval totalBuffer = startSeconds + durationSeconds;//缓冲总长度
float totalTime = CMTimeGetSeconds(self.player.currentItem.duration);//视频总长度
float progress = totalBuffer/totalTime;//缓冲进度
NSLog(@"progress = %lf, !self.buffered:%d, (progress == 1.0):%d",progress, !self.buffered, (progress == 1.0));
self.progress = progress;
//如果缓冲完了,拖动进度条不需要重新显示缓冲条
if (!self.buffered) {
if (fabs(1.0 - progress) <= 0.001) {
self.buffered = YES;
[self.vpToolsView.activityIndicator stopAnimating];
self.vpToolsView.activityIndicator.hidden = YES;
}
[self.vpToolsView.bufferPV setProgress:progress];
}
NSLog(@"yon = %@",self.buffered ? @"yes" : @"no");
}
}
- (void)dealloc {
// [self.speedMonitor stopNetworkSpeedMonitor];
// [[NSNotificationCenter defaultCenter] removeObserver:self name:NetworkDownloadSpeedNotificationKey object:nil];
//
[self.player removeTimeObserver:self.playbackObserver];
[self vpc_playerItemRemoveObserver];
[self.player replaceCurrentItemWithPlayerItem:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}