采用AVFoundation 框架开发的iOS原生播放器,支持时间定为播放及全屏播放
一、ETTVideoPlayer
@implementation ETVideoModel
-(void)putinData:(ETTIntent *)intent
{
if (intent)
{
_PlayerStatus = ETTPlayerStatusUnknown;
ETTBundle * bundel = [intent getExtras];
if(bundel)
{
_Asset = [AVAsset assetWithURL:[NSURL URLWithString:[bundel getObject:@"VideoUrl"]]];
_VideoTitle =[bundel getObject:@"VideoTitle"] ;
_MinTime =[bundel getInt:@"videoPlayTime"];
_InitializeTime = _MinTime;
_PlayRestrictions = [bundel getInt:@"PlayRestrictions"];
}
}
}
@end
@interface ETTVideoPlayer()
@property (nonatomic, retain) ETVideoModel * Model;
@property (nonatomic, retain) AVPlayerItem * PlayerItem;
@property (nonatomic, retain) AVPlayer * Player;
@property (weak, nonatomic) id
@property (strong, nonatomic) id TimeObserver;
@property (strong, nonatomic) id ItemEndObserver;
@property (assign, nonatomic) float LastPlaybackRate;
@property (strong, nonatomic) YZSinglePlayerView * PlayerView;
@property (strong, nonatomic) YZFullScreenPlayerView * FullPlayerView;
@property (strong, nonatomic) AVAssetImageGenerator *imageGenerator;
@property (nonatomic, retain)ETTFullScreenVideoViewController * FullVC;
@end
@implementation ETTVideoPlayer
-(instancetype)initWithFrame:(CGRect)frame intent:(ETTIntent *)intent
{
if (self = [super initWithFrame:frame])
{
_Model = [[ETVideoModel alloc]init];
[_Model putinData:intent];
[self prepareToPlay];
[self addSubview:self.PlayerView];
}
return self;
}
- (YZSinglePlayerView *)PlayerView
{
if (_PlayerView == nil)
{
_PlayerView = [[YZSinglePlayerView alloc] initWithPlayer:self.Player];
}
return _PlayerView;
}
- (YZFullScreenPlayerView *)FullPlayerView
{
if (_FullPlayerView == nil)
{
_FullPlayerView = [[YZFullScreenPlayerView alloc] initWithPlayer:self.Player];
}
return _FullPlayerView;
}
-(void)pauseAudioAndVideo
{
[_Transport pausePlay];
}
-(void)overPlayer
{
[self stop];
[self reportPlayerTime:self.Model.MinTime];
}
-(void)setVideoPlayState:(NSInteger )state
{
_Model.InitializeTime = state;
_Model.PlayRestrictions = state == -1?0:_Model.PlayRestrictions;
}
- (void)prepareToPlay
{
NSArray *keys = @[
@"tracks",
@"duration",
@"commonMetadata",
@"availableMediaCharacteristicsWithMediaSelectionOptions"
];
self.PlayerItem = [AVPlayerItem playerItemWithAsset:self.Model.Asset
automaticallyLoadedAssetKeys:keys];
[self.PlayerItem addObserver:self
forKeyPath:STATUS_KEYPATH
options:0
context:&PlayerItemStatusContext];
self.Player = [AVPlayer playerWithPlayerItem:self.PlayerItem];
self.PlayerView.backgroundColor = [UIColor blackColor];
self.Transport = self.PlayerView.transport;
self.Transport.delegate = self;
if (_Model.MinTime>0) {
[self scrubbedToTime:_Model.MinTime];
}
[self.Transport activity:YES];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if (context == &PlayerItemStatusContext)
{
dispatch_async(dispatch_get_main_queue(), ^{ // 1
[self.PlayerItem removeObserver:self forKeyPath:STATUS_KEYPATH];
if (self.PlayerItem.status == AVPlayerItemStatusReadyToPlay)
{
// Set up time observers. // 2
[self addPlayerItemTimeObserver];
[self addItemEndObserverForPlayerItem];
CMTime duration = self.PlayerItem.duration;
NSTimeInterval time =_Model.MinTime>0?_Model.MinTime:CMTimeGetSeconds(kCMTimeZero);
// Synchronize the time display
[self.Transport setCurrentTime:time
duration:CMTimeGetSeconds(duration)];
[self reportPlayerTime:time];
_Model.PlayerStatus = ETTPlayerStatusReadyToPlay;
[self.Transport readyToPlay];
// [self.player play];
}
else
{
_Model.PlayerStatus = ETTPlayerStatusFailed;
[[iToast makeText:@"视频加载失败"] show];
}
});
}
}
- (void)addItemEndObserverForPlayerItem {
NSString *name = AVPlayerItemDidPlayToEndTimeNotification;
NSOperationQueue *queue = [NSOperationQueue mainQueue];
__weak ETTVideoPlayer *weakSelf = self; // 1
void (^callback)(NSNotification *note) = ^(NSNotification *notification) {
[weakSelf.Player seekToTime:kCMTimeZero // 2
completionHandler:^(BOOL finished) {
[self playerComplete:CMTimeGetSeconds(weakSelf.PlayerItem.duration)];
[weakSelf.Transport playbackComplete];
// 3
}];
};
self.ItemEndObserver = // 4
[[NSNotificationCenter defaultCenter] addObserverForName:name
object:self.PlayerItem
queue:queue
usingBlock:callback];
}
#pragma mark - Time Observers
- (void)addPlayerItemTimeObserver {
// Create 0.5 second refresh interval - REFRESH_INTERVAL == 0.5
CMTime interval =
CMTimeMakeWithSeconds(REFRESH_INTERVAL, NSEC_PER_SEC); // 1
// Main dispatch queue
dispatch_queue_t queue = dispatch_get_main_queue(); // 2
// Create callback block for time observer
__weak ETTVideoPlayer *weakSelf = self; // 3
void (^callback)(CMTime time) = ^(CMTime time) {
NSTimeInterval currentTime = CMTimeGetSeconds(time);
NSTimeInterval duration = CMTimeGetSeconds(weakSelf.PlayerItem.duration);
if (weakSelf.Transport)
{
[weakSelf.Transport setCurrentTime:currentTime duration:duration]; // 4
}
NSInteger subTime =(currentTime -weakSelf.Model.MinTime);
if (subTime>=145 && (subTime%145 ==0)) {
weakSelf.Model.MinTime = currentTime;
[self reportPlayerTime:currentTime];
}
};
// Add observer and store pointer for future use
self.TimeObserver = // 5
[self.Player addPeriodicTimeObserverForInterval:interval
queue:queue
usingBlock:callback];
}
-(void)reportPlayerTime:(NSTimeInterval)currentTime
{
if (self.EVLearnSrcViewDelegate)
{
if (currentTime>=_Model.MinTime) {
[self.EVLearnSrcViewDelegate pReportPlayVideoTime:currentTime];
}
}
}
-(void)playerComplete:(NSTimeInterval)currentTime
{
if (self.EVLearnSrcViewDelegate)
{
[self.EVLearnSrcViewDelegate pReportPlayVideoComplete:currentTime];
}
}
#pragma mark - Housekeeping
- (UIView *)view
{
return self.PlayerView;
}
- (void)dealloc
{
[self stop];
if (self.ItemEndObserver)
{ // 5
NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self.ItemEndObserver name:AVPlayerItemDidPlayToEndTimeNotification object:self.Player.currentItem];
self.ItemEndObserver = nil;
[nc removeObserver:self];
}
if (PlayerItemStatusContext)
{
[self.PlayerItem removeObserver:self forKeyPath:STATUS_KEYPATH];
PlayerItemStatusContext = nil;
}
[self.Player.currentItem cancelPendingSeeks];
[self.Player.currentItem.asset cancelLoading];
}
/**
* Description 检查播放状态
*/
-(BOOL)checkPlayerStatus
{
if (self.Player.status == AVPlayerItemStatusReadyToPlay) {
return YES;
}
return false;
}
- (BOOL)checkPlayerItemStatus
{
if (self.PlayerItem.status == AVPlayerItemStatusReadyToPlay) {
return YES;
}
return false;
}
- (NSInteger)getPlayerPositioningTime
{
NSTimeInterval currentTime = CMTimeGetSeconds(self.PlayerItem.currentTime);
return MAX(currentTime, _Model.MinTime);
}
- (BOOL)checkCanChangePlayProgress:(CGFloat)progress
{
if (_Model.PlayRestrictions == 1)
{
if (progress<_Model.MinTime)
{
return YES;
}
else
{
return false;
}
}
else
{
return YES;
}
}
-(void)layoutSubviews
{
[super layoutSubviews];
self.PlayerView.frame = self.bounds;
}
- (void)fullScreen
{
// if(![self checkPlayerItemStatus])
// {
// return;
// }
_Model.IsFullScreen = !_Model.IsFullScreen;
if (_Model.IsFullScreen)
{
[UIApplication sharedApplication].idleTimerDisabled=YES;
[UIApplication sharedApplication].statusBarHidden = YES;
UIView * view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
view.backgroundColor = [UIColor blackColor];
_FullVC = [[ETTFullScreenVideoViewController alloc]init];
[_FullVC.view addSubview:self.FullPlayerView];
[_FullVC.view sendSubviewToBack:self.FullPlayerView];
self.Transport =_FullVC.transport;
self.Transport.delegate = self;
[self.Transport setTitle:_Model.VideoTitle];
[self.Transport playerStatus:_Model.PlayerStatus];
self.FullPlayerView.frame = CGRectMake(0, 96, SCREEN_WIDTH, SCREEN_HEIGHT-96*2);
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:_FullVC animated:false completion:nil];
}
else
{
[UIApplication sharedApplication].idleTimerDisabled=false;
[UIApplication sharedApplication].statusBarHidden = false;
self.Transport =self.PlayerView.transport;;
[self.Transport playerStatus:_Model.PlayerStatus];
self.Transport.delegate = self;
[self.FullPlayerView.superview removeFromSuperview];
[_FullVC dismissViewControllerAnimated:false completion:nil];
_FullVC = nil;
}
}
/**
* Description 开始播放
*/
- (void)play {
_Model.PlayerStatus = ETTPlayerStatusToPlay;
[self.Player play];
}
/**
* Description 赞同播放
*/
- (void)pause {
_Model.PlayerStatus = ETTPlayerStatusPause;
self.LastPlaybackRate = self.Player.rate;
[self.Player pause];
}
/**
* Description 停止播放
*/
- (void)stop {
[self.Player setRate:0.0f];
[self.Transport playbackComplete];
}
/**
* Description
*/
- (void)scrubbedToTime:(NSTimeInterval)time { // 2
[self.PlayerItem cancelPendingSeeks];
[self.Player seekToTime:CMTimeMakeWithSeconds(time, NSEC_PER_SEC) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
}
/**
* Description 设置播放时间点
*/
- (void)scrubbingDidStart { // 1
self.LastPlaybackRate = self.Player.rate;
[self.Player pause];
[self.Player removeTimeObserver:self.TimeObserver];
}
/**
* Description
*/
- (void)scrubbingDidEnd { // 3
[self addPlayerItemTimeObserver];
if (self.LastPlaybackRate > 0.0f) {
[self.Player play];
}
}
- (void)close {
}
- (void)jumpedToTime:(NSTimeInterval)time {
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end
二、封面
#import "YZSingleOverlayView.h"
@interface YZSingleOverlayView()
/**
* Description 头像
*/
@property (nonatomic,retain)UIImageView * Avatar;
@property (nonatomic,retain)UIImageView * coverImage;
@property (nonatomic,retain)UIView * NameBgView;
@property (nonatomic,retain)UIView * TitleBgView;
/**
* Description 名称
*/
@property (nonatomic,retain)UILabel * NameLabel;
/**
* Description 文本说明
*/
@property (nonatomic,retain)UILabel * TitleLabel;
/**
* Description 在关闭按钮
*/
@property (nonatomic,retain)UIButton * CloseButton;
/**
* Description 时间 滑块试图
*/
@property (nonatomic,retain)UISlider * SliderView;
@property (nonatomic,retain)UISlider * ScrubbingSliderView;
@property (nonatomic,retain)UIView * InfoView;
@property (nonatomic,retain)UILabel * ScrubbingTimeLabel;
/**
* Description 显示视频时长label
*/
@property (nonatomic,retain)UILabel * TimeLabel;
@property (nonatomic, strong)UILabel * StartTimeText;
/**
* Description 全屏按钮
*/
@property (nonatomic,retain)UIButton * ScreenButton;
@property (nonatomic,retain)UIButton * PlayerButton;
@property (nonatomic,retain)UIButton * StopButton;
@property (nonatomic,retain) UIActivityIndicatorView *indicatorView;
@property (nonatomic, assign) CGFloat infoViewOffset;
@property (nonatomic, strong)UIView * ProgressBarView;
@property (nonatomic, strong)UIButton * PlayOrPauseButton;
@property (nonatomic, retain)UIImageView * ScrubbingImageView;
@end
@implementation YZSingleOverlayView
@synthesize delegate = _delegate;
@synthesize VisitType = _VisitType;
//@dynamic TypeButton;
-(id)initWithFrame:(CGRect)frame
{
if (self == [super initWithFrame:frame])
{
// [self addSubview:self.coverImage];
[self addSubview:self.ProgressBarView];
[self.ProgressBarView addSubview:self.PlayOrPauseButton];
[self.ProgressBarView addSubview:self.SliderView];
[self.ProgressBarView addSubview:self.StartTimeText];
[self.ProgressBarView addSubview:self.TimeLabel];
[self.ProgressBarView addSubview:self.ScreenButton];
[self addSubview: self.indicatorView];
[self addSubview:self.InfoView];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopback) name:UIApplicationDidEnterBackgroundNotification object:nil];
}
return self;
}
-(void)setDelegate:(id
{
_delegate = delegate;
[self initStatus];
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
-(void)initStatus
{
if (self.delegate)
{
if ([self.delegate checkPlayerStatus])
{
[self readyToPlay];
}
}
}
-(void)layoutSubviews
{
[super layoutSubviews];
[_indicatorView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self);
}];
[_ProgressBarView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.mas_bottom);
make.left.equalTo(self);
make.width.equalTo(self);
make.height.mas_equalTo(48);
}];
[_PlayOrPauseButton mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(_ProgressBarView.mas_left).offset(16);
make.centerY.equalTo(_ProgressBarView);
make.size.mas_equalTo(_PlayOrPauseButton.currentImage.size);
}];
[_StartTimeText mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(_PlayOrPauseButton.mas_right).offset(24);
make.height.equalTo(_ProgressBarView);
make.width.mas_equalTo(50);
make.top.mas_equalTo(0);
}];
[_ScreenButton mas_remakeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(_ProgressBarView.mas_right).offset(-16);
make.centerY.equalTo(_ProgressBarView);
make.size.mas_equalTo(_PlayOrPauseButton.currentImage.size);
}];
[_TimeLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(_ScreenButton.mas_left).offset(-20);
make.height.equalTo(_ProgressBarView);
make.width.mas_equalTo(50);
make.top.mas_equalTo(0);
}];
[_SliderView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(_TimeLabel.mas_left).offset(-20);
make.left.equalTo (_StartTimeText.mas_right).offset(16);
make.centerY.equalTo(_PlayOrPauseButton);
make.height.mas_equalTo(20);
}];
[_InfoView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(200);
make.height.mas_equalTo(100);
make.center.mas_equalTo(self);
}];
[_ScrubbingImageView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(_ScrubbingImageView.image.size);
make.centerX.equalTo(_InfoView);
make.centerY.equalTo(_InfoView.mas_centerY).offset(-10);
// make.width.mas_equalTo(50);
// make.height.mas_equalTo(50);
// make.center.mas_equalTo(_InfoView);
}];
[_ScrubbingSliderView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(_InfoView.width-10);
make.height.mas_equalTo(3);
make.bottom.mas_equalTo(_InfoView.bottom).offset(-8);
make.centerX.mas_equalTo(_InfoView);
}];
}
-(UIView *)ProgressBarView
{
if (_ProgressBarView == nil)
{
_ProgressBarView = [[UIView alloc] initWithFrame:CGRectZero];
_ProgressBarView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];//
}
return _ProgressBarView;
}
-(UIButton *)PlayOrPauseButton
{
if (_PlayOrPauseButton == nil)
{
_PlayOrPauseButton = [UIButton buttonWithType:UIButtonTypeCustom];
_PlayOrPauseButton.showsTouchWhenHighlighted = YES;
[_PlayOrPauseButton setImage:ImageNamed(@"video_play") forState:UIControlStateNormal];
[_PlayOrPauseButton setImage:ImageNamed(@"video_pause") forState:UIControlStateSelected];
[_PlayOrPauseButton addTarget:self action:@selector(playback:) forControlEvents:UIControlEventTouchUpInside];
[_ProgressBarView addSubview:_PlayOrPauseButton];
}
return _PlayOrPauseButton;
}
-(UIActivityIndicatorView *)indicatorView
{
if (_indicatorView == nil)
{
_indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[_indicatorView stopAnimating];
// _indicatorView.color=[YZColor colorWithHexString:k_color_mainColor];
}
return _indicatorView;
}
-(UILabel *)StartTimeText
{
if (_StartTimeText == nil)
{
_StartTimeText = [[UILabel alloc]initWithFrame:CGRectZero];
_StartTimeText.textAlignment = NSTextAlignmentCenter;
_StartTimeText.textColor = WHITE_COLOR;
_StartTimeText.font = [UIFont systemFontOfSize:14.0f];
_StartTimeText.text = @"00:00";
}
return _StartTimeText;
}
-(UIView *)InfoView
{
if (_InfoView == nil)
{
_InfoView = [[UIView alloc]init];
_InfoView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8];
[_InfoView addSubview:self.ScrubbingTimeLabel];
[_InfoView addSubview:self.ScrubbingImageView];
[_InfoView addSubview:self.ScrubbingSliderView];
_InfoView.hidden = YES;
}
return _InfoView;
}
-(UISlider *)ScrubbingSliderView
{
if (_ScrubbingSliderView ==nil)
{
_ScrubbingSliderView = [[UISlider alloc]init];
[_ScrubbingSliderView setMinimumTrackImage:ImageNamed(@"audio_progress_played") forState:UIControlStateNormal];
[_ScrubbingSliderView setMaximumTrackImage:ImageNamed(@"audio_progress_unplay") forState:UIControlStateNormal];
CGSize s=CGSizeMake(1, 1);
UIGraphicsBeginImageContextWithOptions(s, 0, [UIScreen mainScreen].scale);
UIRectFill(CGRectMake(0, 0, 1, 1));
UIImage *img=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//添加图片,大按钮就去掉了,这个img置为空是去不掉的
[_ScrubbingSliderView setThumbImage:img forState:UIControlStateNormal];
// [_ScrubbingSliderView setThumbImage:ImageNamed(@"audio_slider_thumb") forState:UIControlStateNormal];
}
return _ScrubbingSliderView;
}
-(UIImageView *)ScrubbingImageView
{
if (_ScrubbingImageView == nil)
{
_ScrubbingImageView = [[UIImageView alloc]init];
_ScrubbingImageView.highlightedImage = [UIImage imageNamed:@"video_rew"];
_ScrubbingImageView.image = [UIImage imageNamed:@"video_ff"];
}
return _ScrubbingImageView;
}
-(UILabel *)ScrubbingTimeLabel
{
if (_ScrubbingTimeLabel == nil)
{
_ScrubbingTimeLabel = [[UILabel alloc]init];
_ScrubbingTimeLabel.textColor = WHITE_COLOR;
_ScrubbingTimeLabel.font = [UIFont systemFontOfSize:14.0f];
_ScrubbingTimeLabel.textAlignment = NSTextAlignmentCenter;
}
return _ScrubbingTimeLabel;
}
-(UIButton * )ScreenButton
{
if (_ScreenButton == nil)
{
_ScreenButton=[[UIButton alloc]init];
[_ScreenButton setImage:[UIImage imageNamed:@"video_window"] forState:UIControlStateNormal];
[_ScreenButton addTarget:self action:@selector(screenBack) forControlEvents:UIControlEventTouchUpInside];
}
return _ScreenButton;
}
#pragma mark ---全屏按钮回调--
-(void)screenBack
{
if (self.delegate)
{
[self.delegate fullScreen];
}
}
-(UIImageView *)coverImage
{
if (_coverImage == nil)
{
_coverImage = [[UIImageView alloc]init];
[ _coverImage setImage:[UIImage imageNamed:@"live_back_def"]];
}
return _coverImage;
}
-(void)closeWindow
{
if (self.delegate )
{
[self.delegate close];
}
}
-(UILabel *)TimeLabel
{
if (_TimeLabel == nil)
{
_TimeLabel = [[UILabel alloc]init];
_TimeLabel.textColor = WHITE_COLOR;
_TimeLabel.font = [UIFont systemFontOfSize:14.0f];
_TimeLabel.text = @"00:00";
}
return _TimeLabel;
}
-(UISlider *)SliderView
{
if (_SliderView == nil)
{
_SliderView = [[UISlider alloc]init];
[_SliderView setMinimumTrackImage:ImageNamed(@"audio_progress_played") forState:UIControlStateNormal];
[_SliderView setMaximumTrackImage:ImageNamed(@"audio_progress_unplay") forState:UIControlStateNormal];
[_SliderView setThumbImage:ImageNamed(@"audio_slider_thumb") forState:UIControlStateNormal];
[_SliderView addTarget:self action:@selector(showPopupUI) forControlEvents:UIControlEventValueChanged];
[_SliderView addTarget:self action:@selector(hidePopupUI) forControlEvents:UIControlEventTouchUpInside];
[_SliderView addTarget:self action:@selector(unhidePopupUI) forControlEvents:UIControlEventTouchDown];
// _SliderView.hidden = YES;
}
return _SliderView;
}
-(void)pausePlay
{
self.PlayOrPauseButton.selected = false;
[self.delegate pause];
}
-(void)stopback
{
if (self.PlayerButton.hidden)
{
self.PlayerButton.hidden = false;
if (self.delegate)
{
[self.delegate pause];
}
}
}
-(void)playback:(UIButton *)sender
{
if ([self.delegate checkPlayerItemStatus])
{
if (self.PlayOrPauseButton.selected) {
[self.delegate pause];
}
else
{
[self.delegate play];
}
self.PlayOrPauseButton.selected = !self.PlayOrPauseButton.selected;
}
}
-(void)activity:(BOOL)display
{
[self.indicatorView startAnimating];
}
-(void)playerStatus:(ETTPlayerStatus)status
{
if (status == ETTPlayerStatusToPlay)
{
self.PlayOrPauseButton.selected = YES;
}
else
{
self.PlayOrPauseButton.selected = false;
}
}
-(void)readyToPlay
{
[self.indicatorView stopAnimating];
self.SliderView.hidden = false;
}
- (void)playbackComplete {
self.SliderView.value = 0.0f;
self.PlayOrPauseButton.selected = false;
}
- (void)setCurrentTime:(NSTimeInterval)time duration:(NSTimeInterval)duration {
NSInteger currentSeconds = ceilf(time);
//double remainingTime = duration - time;
self.StartTimeText.text = [self formatSeconds:currentSeconds];
self.TimeLabel.text = [self formatSeconds:duration];
// self.remainingTimeLabel.text = [self formatSeconds:remainingTime];
self.SliderView.minimumValue = 0.0f;
self.SliderView.maximumValue = duration;
self.SliderView.value = time;
}
- (void)setTitle:(NSString *)title
{
// self.navigationBar.topItem.title = title ? title : @"Video Player";
// self.NameLabel.text = title;
// [self.NameLabel sizeToFit];
}
- (void)setSubtitles:(NSString *)subtitle
{
self.TitleLabel.text = subtitle;
[self.TitleLabel sizeToFit];
}
- (void)calculateInfoViewOffset {
[self.InfoView sizeToFit];
self.infoViewOffset = ceilf(CGRectGetWidth(self.InfoView.frame) / 2);
}
- (void)showPopupUI {
if (![self.delegate checkCanChangePlayProgress:self.SliderView.value])
{
self.SliderView.value = [self.delegate getPlayerPositioningTime];
return;
}
if ([self.delegate checkPlayerItemStatus])
{
self.InfoView.hidden = NO;
[self setScrubbingTime:self.SliderView.value];
[self.delegate scrubbedToTime:self.SliderView.value];
}
}
- (void)unhidePopupUI {
if ([self.delegate checkPlayerItemStatus])
{
self.InfoView.hidden = NO;
self.InfoView.alpha = 0.0f;
[UIView animateWithDuration:0.2f animations:^{
self.InfoView.alpha = 1.0f;
}];
[self.delegate scrubbingDidStart];
}
}
- (void)hidePopupUI {
if ([self.delegate checkPlayerItemStatus]) {
[UIView animateWithDuration:0.3f animations:^{
self.InfoView.alpha = 0.0f;
} completion:^(BOOL complete) {
self.InfoView.alpha = 1.0f;
self.InfoView.hidden = YES;
}];
[self.delegate scrubbingDidEnd];
}
}
- (void)setScrubbingTime:(NSTimeInterval)time
{
self.ScrubbingTimeLabel.frame =CGRectMake(0, self.InfoView.height-42, self.InfoView.width, 25);
self.ScrubbingTimeLabel.text = [NSString stringWithFormat:@"%@/%@", [self formatSeconds:time],self.TimeLabel.text];
CGFloat sf = self.ScrubbingTimeLabel.text.floatValue;
CGFloat st = self.StartTimeText.text.floatValue;
if (sf
self.ScrubbingImageView.highlighted = YES;
}
else
{
self.ScrubbingImageView.highlighted = false;;
}
self.ScrubbingSliderView.minimumValue = 0.0f;
self.ScrubbingSliderView.maximumValue = self.SliderView.maximumValue;
self.ScrubbingSliderView.value = self.SliderView.value;
// self.StartTimeText.text =[self formatSeconds:time];
}
- (NSString *)formatSeconds:(NSInteger)value {
NSInteger seconds = value % 60;
NSInteger minutes = value / 60;
return [NSString stringWithFormat:@"%02ld:%02ld", (long) minutes, (long) seconds];
}
- (CGFloat)boundsHeight {
return self.bounds.size.height;
}
-(UIView *)view
{
return self;
}
@end
@interface YZFullOverlayView()
@property (nonatomic,retain)UIView * TopBar;
@property (nonatomic,retain)UILabel * TopLable;
@property (nonatomic,retain)UIButton * BackButton;
@property (nonatomic,retain)UIButton * HidenButton;
@end
@implementation YZFullOverlayView
-(id)initWithFrame:(CGRect)frame
{
if (self == [super initWithFrame:frame])
{
[self addSubview:self.TopBar];
[self addSubview:self.HidenButton];
}
return self;
}
-(UILabel *)TopLable
{
if (_TopLable == nil)
{
_TopLable = [[UILabel alloc]init];
_TopLable.textColor = WHITE_COLOR;
_TopLable.font = [UIFont systemFontOfSize:14.0f];
}
return _TopLable;
}
-(UIButton *)BackButton
{
if (_BackButton == nil)
{
_BackButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_BackButton setImage:[UIImage imageNamed: @"back_placeholder"] forState:UIControlStateNormal];
[_BackButton addTarget:self action:@selector(backHandle) forControlEvents:UIControlEventTouchUpInside];
}
return _BackButton;
}
-(void)backHandle
{
if (self.delegate)
{
[self.delegate fullScreen];
}
}
-(UIButton *)HidenButton
{
if (_HidenButton == nil)
{
_HidenButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_HidenButton addTarget:self action:@selector(hidenHandle) forControlEvents:UIControlEventTouchUpInside];
}
return _HidenButton;
}
-(UIView *)TopBar
{
if (_TopBar == nil)
{
_TopBar = [[UIView alloc]initWithFrame:CGRectZero];
_TopBar.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8];
[_TopBar addSubview:self.BackButton];
[_TopBar addSubview:self.TopLable];
}
return _TopBar;
}
-(void)hidenHandle
{
self.HidenButton.selected = !self.HidenButton.selected;
self.TopBar.hidden = self.HidenButton.selected;
self.ProgressBarView.hidden = self.HidenButton.selected;
}
- (void)setTitle:(NSString *)title
{
// self.navigationBar.topItem.title = title ? title : @"Video Player";
self.TopLable.text = title;
}
-(void)layoutSubviews
{
[super layoutSubviews];
[_TopBar mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(0);
make.left.mas_equalTo(0);
make.width.mas_equalTo(self.width);
make.height.mas_equalTo(48);
}];
[_BackButton mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(12);
make.top.mas_equalTo(0);
make.width.mas_equalTo(48);
make.height.mas_equalTo(48);
}];
[_TopLable mas_remakeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(_TopBar.mas_bottom);
make.left.mas_equalTo(_BackButton.mas_right).offset(10);
float w = _TopBar.width -10-_BackButton.width-24;
make.width.mas_equalTo(w);
make.height.mas_equalTo(_TopBar);
}];
[_HidenButton mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(96);
make.left.mas_equalTo(0);
make.width.mas_equalTo(self);
make.height.mas_equalTo(self.height-96-48);
}];
}
@end
三、播放展现视图
@interface YZPlayerView()
@property (strong, nonatomic) YZSingleOverlayView *overlayView; // 1
-(void)setupOverlayView;
@end
@implementation YZPlayerView
@dynamic overlayView;
+ (Class)layerClass { // 2
return [AVPlayerLayer class];
}
-(id
{
return self.overlayView;
}
- (id)initWithPlayer:(AVPlayer *)player {
self = [super initWithFrame:CGRectZero]; // 3
if (self) {
self.backgroundColor = [UIColor blackColor];
self.autoresizingMask = UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleWidth;
[(AVPlayerLayer *) [self layer] setPlayer:player]; // 4
[(AVPlayerLayer *) [self layer] setVideoGravity: AVLayerVideoGravityResizeAspectFill];
[self setupOverlayView];
}
return self;
}
-(void)setupOverlayView
{
[self addSubview:self.overlayView];
}
@end
@interface YZSinglePlayerView()
@property (strong, nonatomic) YZSingleOverlayView *overlayView; // 1
@end
@implementation YZSinglePlayerView
@synthesize overlayView = _overlayView;
-(void)layoutSubviews
{
[super layoutSubviews];
self.overlayView.frame = self.bounds;
}
-(YZSingleOverlayView *)overlayView
{
if (_overlayView == nil)
{
_overlayView = [[YZSingleOverlayView alloc]initWithFrame:CGRectZero];
}
return _overlayView;
}
@end
四、全屏播放
#import "ETTFullScreenVideoViewController.h"
#import "YZSingleOverlayView.h"
@interface ETTFullScreenVideoViewController ()
@property (strong, nonatomic) YZSingleOverlayView *overlayView;
@end
@implementation ETTFullScreenVideoViewController
@synthesize overlayView = _overlayView;
- (BOOL)prefersStatusBarHidden
{
return YES;
}
-(void)setupContentViewBackground
{
}
-(void)setupNavBarSubView
{
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
[self.view addSubview:self.overlayView];
// Do any additional setup after loading the view.
}
-(YZSingleOverlayView *)overlayView
{
if (_overlayView == nil)
{
_overlayView = [[YZFullOverlayView alloc]initWithFrame:CGRectZero];
}
return _overlayView;
}
-(void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[self.overlayView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(SCREEN_WIDTH);
make.left.mas_equalTo(0);
make.height.mas_equalTo(SCREEN_HEIGHT-96);
make.top.equalTo(self.view.mas_top);
}];
}
-(id
{
return self.overlayView;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end