AVPlayer
来源:互联网 发布:怎么给网络加密 编辑:程序博客网 时间:2024/04/20 13:33
//
// MoviePlayerViewController.m
// MoviePlayerViewController
//
// Created by pljhonglu on 13-12-18.
// Copyright (c) 2013年 pljhonglu. All rights reserved.
//
#import "MoviePlayerViewController.h"
#import <MediaPlayer/MediaPlayer.h>
#import <CoreMedia/CoreMedia.h>
#import "MBProgressHUD.h"
#define TopViewHeight 44
#define BottomViewHeight 72
#define VolumeStep 0.02f
#define BrightnessStep 0.02f
#define MovieProgressStep 5.0f
#define IOS7 ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending)
typedefNS_ENUM(NSInteger, GestureType){
GestureTypeOfNone =0,
GestureTypeOfVolume,
GestureTypeOfBrightness,
GestureTypeOfProgress,
};
//记住播放进度相关的数据库操作类
@interface DatabaseManager :NSObject
+ (id)defaultDatabaseManager;
- (void)addPlayRecordWithIdentifier:(NSString *)identifier progress:(CGFloat)progress;
- (CGFloat)getProgressByIdentifier:(NSString *)identifier;
@end
@interface MoviePlayerViewController ()
@property (nonatomic,assign)BOOL isPlaying;
@property (nonatomic,strong)AVPlayer *player;
@property (nonatomic,strong)NSMutableArray *itemTimeList;
@property (nonatomic)CGFloat movieLength;
@property (nonatomic)NSInteger currentPlayingItem;
@property (nonatomic,strong)MBProgressHUD *progressHUD;
@property (nonatomic,strong)UIView *topView;
@property (nonatomic,strong)UIButton *returnBtn;
@property (nonatomic,strong)UILabel *titleLable;
@property (nonatomic,strong)UIView *bottomView;
@property (nonatomic,strong)UIButton *playBtn;
@property (nonatomic,strong)UIButton *backwardBtn;
@property (nonatomic,strong)UIButton *forwardBtn;
@property (nonatomic,strong)UIButton *fastBackwardBtn;
@property (nonatomic,strong)UIButton *fastForeardBtn;
@property (nonatomic,strong)UISlider *movieProgressSlider;
@property (nonatomic,strong)UILabel *currentLable;
@property (nonatomic,strong)UILabel *remainingTimeLable;
@property (nonatomic,strong)UIImageView *brightnessView;
@property (nonatomic,strong)UIProgressView *brightnessProgress;
@property (nonatomic,strong)UIView *progressTimeView;
@property (nonatomic,strong)UILabel *progressTimeLable_top;
@property (nonatomic,strong)UILabel *progressTimeLable_bottom;
@property (nonatomic,assign)CGFloat ProgressBeginToMove;
@property (nonatomic,weak)id timeObserver;
@property (nonatomic,assign)GestureType gestureType;
@property (nonatomic,assign)CGPoint originalLocation;
@property (nonatomic,assign)CGFloat systemBrightness;
@property (nonatomic,assign)BOOL isFirstOpenPlayer;//第一次打开需要读取历史观看进度
@end
@implementation MoviePlayerViewController
- (void)didReceiveMemoryWarning
{
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
#pragma mark - init
- (id)initNetworkMoviePlayerViewControllerWithURLList:(NSArray *)urlList movieTitle:(NSString *)movieTitle;{
self = [superinit];
if (self) {
_isPlaying = YES;
_isFirstOpenPlayer =NO;
//_movieURL = url;
_movieURLList = urlList;
_movieTitle = movieTitle;
_itemTimeList = [[NSMutableArrayalloc]initWithCapacity:5];
_mode =MoviePlayerViewControllerModeNetwork;
}
return self;
}
- (id)initLocalMoviePlayerViewControllerWithURL:(NSURL *)url movieTitle:(NSString *)movieTitle{
self = [superinit];
if (self) {
_isPlaying = YES;
_isFirstOpenPlayer =NO;
_movieURL = url;
_movieURLList = @[url];
_movieTitle = movieTitle;
_itemTimeList = [[NSMutableArrayalloc]initWithCapacity:5];
_mode =MoviePlayerViewControllerModeLocal;
}
return self;
}
- (id)initLocalMoviePlayerViewControllerWithURLList:(NSArray *)urlList movieTitle:(NSString *)movieTitle{
self = [superinit];
if (self) {
_isPlaying = YES;
_isFirstOpenPlayer =NO;
_movieURL = nil;
_movieURLList = urlList;
_movieTitle = movieTitle;
_itemTimeList = [[NSMutableArrayalloc]initWithCapacity:5];
_mode =MoviePlayerViewControllerModeLocal;
}
return self;
}
- (void)viewDidLoad
{
[superviewDidLoad];
// Do any additional setup after loading the view.
[[UIApplicationsharedApplication] setStatusBarHidden:YESwithAnimation:UIStatusBarAnimationNone];
if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
// iOS 7
[selfprefersStatusBarHidden];
[selfperformSelector:@selector(setNeedsStatusBarAppearanceUpdate)];
}
self.view.backgroundColor = [UIColorblackColor];
[selfcreateTopView];
[selfcreateBottomView];
[selfcreateAvPlayer];
[selfcreateBrightnessView];
[selfcreateProgressTimeLable];
[selfperformSelector:@selector(hidenControlBar)withObject:nilafterDelay:3];
[self.viewbringSubviewToFront:_topView];
[self.viewbringSubviewToFront:_bottomView];
//监控 app活动状态,打电话/锁屏时暂停播放
[[NSNotificationCenterdefaultCenter] addObserver:self
selector:@selector(becomeActive)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenterdefaultCenter] addObserver:self
selector:@selector(resignActive)
name:UIApplicationWillResignActiveNotification
object:nil];
NSUserDefaults *userd = [NSUserDefaultsstandardUserDefaults];
if (![userdboolForKey:@"isFirstOpenMoviePlayerViewController"]) {
//第一次打开,显示引导页
UIButton *btn = [[UIButtonalloc]initWithFrame:CGRectMake(0,0, self.view.frame.size.height,self.view.frame.size.width)];
btn.contentMode =UIViewContentModeScaleAspectFill;
if (self.view.frame.size.height>500) {
[btn setImage:[UIImageimageNamed:@"player_guide_1136.png"]forState:UIControlStateNormal];
}else{
[btn setImage:[UIImageimageNamed:@"player_guide_960.png"]forState:UIControlStateNormal];
}
[btn addTarget:selfaction:@selector(firstCoverOnClick:)forControlEvents:UIControlEventTouchDown];
[self.viewaddSubview:btn];
[userd setBool:YESforKey:@"isFirstOpenMoviePlayerViewController"];
[userdsynchronize];
}
}
- (void)viewWillAppear:(BOOL)animated{
_systemBrightness = [UIScreenmainScreen].brightness;
}
- (void)createAvPlayer{
AVAudioSession *audioSession = [AVAudioSessionsharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlaybackerror:nil];
CGRect playerFrame =CGRectMake(0,0, self.view.layer.bounds.size.height,self.view.layer.bounds.size.width);
__block CMTime totalTime =CMTimeMake(0,0);
[_movieURLListenumerateObjectsUsingBlock:^(id obj,NSUInteger idx, BOOL *stop) {
NSURL *url = (NSURL *)obj;
AVPlayerItem *playerItem = [AVPlayerItemplayerItemWithURL:url];
totalTime.value += playerItem.asset.duration.value;
totalTime.timescale = playerItem.asset.duration.timescale;
[_itemTimeListaddObject:[NSNumbernumberWithDouble:((double)playerItem.asset.duration.value/totalTime.timescale)]];
}];
_movieLength = (CGFloat)totalTime.value/totalTime.timescale;
_player = [AVPlayerplayerWithPlayerItem:[AVPlayerItemplayerItemWithURL:(NSURL *)_movieURLList[0]]];
AVPlayerLayer *playerLayer = [AVPlayerLayerplayerLayerWithPlayer:_player];
playerLayer.frame = playerFrame;
playerLayer.videoGravity =AVLayerVideoGravityResizeAspect;
[self.view.layeraddSublayer:playerLayer];
// [_player play];
_currentPlayingItem =0;
//注册检测视频加载状态的通知
[_player.currentItemaddObserver:selfforKeyPath:@"status"options:NSKeyValueObservingOptionNewcontext:nil];
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(playerItemDidReachEnd:)name:AVPlayerItemDidPlayToEndTimeNotificationobject:nil];
// [_player.currentItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
//这里为了避免timer双重引用引起的内存泄漏
__weak typeof(_player) player_ =_player;
__weaktypeof(_movieProgressSlider) movieProgressSlider_ =_movieProgressSlider;
__weaktypeof(_currentLable) currentLable_ =_currentLable;
__weaktypeof(_remainingTimeLable) remainingTimeLable_ =_remainingTimeLable;
__weaktypeof(_itemTimeList) itemTimeList_ =_itemTimeList;
typeof(_movieLength) *movieLength_ = &_movieLength;
typeof(_gestureType) *gestureType_ = &_gestureType;
typeof(_currentPlayingItem) *currentPlayingItem_ = &_currentPlayingItem;
//第一个参数反应了检测的频率
_timeObserver = [_playeraddPeriodicTimeObserverForInterval:CMTimeMake(3,30) queue:NULLusingBlock:^(CMTime time){
if ((*gestureType_) != GestureTypeOfProgress) {
//获取当前时间
CMTime currentTime = player_.currentItem.currentTime;
double currentPlayTime = (double)currentTime.value/currentTime.timescale;
NSInteger currentTemp = *currentPlayingItem_;
while (currentTemp > 0) {
currentPlayTime += [(NSNumber *)itemTimeList_[currentTemp-1]doubleValue];
--currentTemp;
}
//转成秒数
CGFloat remainingTime = (*movieLength_) - currentPlayTime;
movieProgressSlider_.value = currentPlayTime/(*movieLength_);
NSDate *currentDate = [NSDatedateWithTimeIntervalSince1970:currentPlayTime];
NSDate *remainingDate = [NSDatedateWithTimeIntervalSince1970:remainingTime];
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setTimeZone:[NSTimeZonetimeZoneForSecondsFromGMT:0]];
[formattersetDateFormat:(currentPlayTime/3600>=1)?@"h:mm:ss":@"mm:ss"];
NSString *currentTimeStr = [formatter stringFromDate:currentDate];
[formattersetDateFormat:(remainingTime/3600>=1)?@"h:mm:ss":@"mm:ss"];
NSString *remainingTimeStr = [NSStringstringWithFormat:@"-%@",[formatterstringFromDate:remainingDate]];
currentLable_.text = currentTimeStr;
remainingTimeLable_.text = remainingTimeStr;
}
}];
_progressHUD = [[MBProgressHUDalloc]initWithView:self.view];
[self.viewaddSubview:_progressHUD];
[_progressHUD show:YES];
}
- (void)createTopView{
CGFloat titleLableWidth = 400;
_topView = [[UIViewalloc]initWithFrame:CGRectMake(0,0, self.view.bounds.size.height,TopViewHeight)];
_topView.backgroundColor = [UIColorcolorWithRed:0green:0blue:0alpha:0.7];
_returnBtn = [[UIButtonalloc]initWithFrame:CGRectMake(0,0, 50,TopViewHeight)];
[_returnBtnsetTitle:@"返回"forState:UIControlStateNormal];
[_returnBtnsetTitleColor:[UIColorcolorWithRed:0.01fgreen:0.48fblue:0.98falpha:1.00f]forState:UIControlStateNormal];
[_returnBtnaddTarget:selfaction:@selector(popView)forControlEvents:UIControlEventTouchUpInside];
[_topView addSubview:_returnBtn];
_titleLable = [[UILabelalloc]initWithFrame:CGRectMake(self.view.bounds.size.height/2-titleLableWidth/2,0, titleLableWidth, TopViewHeight)];
_titleLable.backgroundColor = [UIColorclearColor];
_titleLable.text =_movieTitle;
_titleLable.textColor = [UIColorwhiteColor];
_titleLable.textAlignment =NSTextAlignmentCenter;
[_topView addSubview:_titleLable];
[self.viewaddSubview:_topView];
}
- (void)createBottomView{
CGRect bounds = self.view.bounds;
_bottomView = [[UIViewalloc]initWithFrame:CGRectMake(0, bounds.size.width-BottomViewHeight, bounds.size.height,BottomViewHeight)];
_bottomView.backgroundColor = [UIColorcolorWithRed:0.fgreen:0.fblue:0.falpha:0.4f];
// top
CGFloat marginTop = 13;
_playBtn = [[UIButtonalloc]initWithFrame:CGRectMake(bounds.size.height/2-20, marginTop-12, 40,40)];
[_playBtnsetImage:[UIImageimageNamed:@"pause_nor.png"]forState:UIControlStateNormal];
[_playBtnaddTarget:selfaction:@selector(pauseBtnClick)forControlEvents:UIControlEventTouchUpInside];
[_bottomView addSubview:_playBtn];
_fastBackwardBtn = [[UIButtonalloc]initWithFrame:CGRectMake(_playBtn.frame.origin.x-56-21, marginTop, 21, 16)];
_fastBackwardBtn.tag =1;
[_fastBackwardBtnsetImage:[UIImageimageNamed:@"fast_backward_nor.png"]forState:UIControlStateNormal];
[_fastBackwardBtnaddTarget:selfaction:@selector(fastAction:)forControlEvents:UIControlEventTouchUpInside];
[_bottomView addSubview:_fastBackwardBtn];
_fastForeardBtn = [[UIButtonalloc]initWithFrame:CGRectMake(_playBtn.frame.origin.x+_playBtn.frame.size.width+56, marginTop, 21, 16)];
_fastForeardBtn.tag =2;
[_fastForeardBtnsetImage:[UIImageimageNamed:@"fast_forward_nor.png"]forState:UIControlStateNormal];
[_fastForeardBtnaddTarget:selfaction:@selector(fastAction:)forControlEvents:UIControlEventTouchUpInside];
[_bottomView addSubview:_fastForeardBtn];
_forwardBtn = [[UIButtonalloc]initWithFrame:CGRectMake(_fastForeardBtn.frame.origin.x+_fastForeardBtn.frame.size.width+56, marginTop, 16,16)];
_forwardBtn.tag =1;
[_forwardBtnsetImage:[UIImageimageNamed:@"forward_disable.png"]forState:UIControlStateNormal];
[_forwardBtnsetImage:[UIImageimageNamed:@"forward_disable.png"]forState:UIControlStateHighlighted
];
[_bottomView addSubview:_forwardBtn];
_backwardBtn = [[UIButtonalloc]initWithFrame:CGRectMake(_fastBackwardBtn.frame.origin.x-56-16, marginTop, 16, 16)];
_backwardBtn.tag =2;
[_backwardBtnsetImage:[UIImageimageNamed:@"backward_disable.png"]forState:UIControlStateNormal];
[_backwardBtnsetImage:[UIImageimageNamed:@"backward_disable.png"]forState:UIControlStateHighlighted];
[_bottomView addSubview:_backwardBtn];
if (_datasource) {
if ([_datasourceisHaveNextMovie]) {
[_forwardBtnsetImage:[UIImageimageNamed:@"forward_nor.png"]forState:UIControlStateNormal];
[_forwardBtnaddTarget:selfaction:@selector(forWordOrBackWardMovieAction:)forControlEvents:UIControlEventTouchUpInside];
}
if ([_datasourceisHavePreviousMovie]) {
[_backwardBtnsetImage:[UIImageimageNamed:@"backward_nor.png"]forState:UIControlStateNormal];
[_backwardBtnaddTarget:selfaction:@selector(forWordOrBackWardMovieAction:)forControlEvents:UIControlEventTouchUpInside];
}
}
//bottom
CGFloat bottomOrigin_y = BottomViewHeight - 30;
_currentLable = [[UILabelalloc]initWithFrame:CGRectMake(0 , bottomOrigin_y,63, 20)];
_currentLable.font = [UIFontsystemFontOfSize:13];
_currentLable.textColor = [UIColorwhiteColor];
_currentLable.backgroundColor = [UIColorclearColor];
_currentLable.textAlignment =NSTextAlignmentCenter;
[_bottomView addSubview:_currentLable];
_movieProgressSlider = [[UISlideralloc]initWithFrame:CGRectMake(63, bottomOrigin_y, bounds.size.height-126,20)];//height 34
[_movieProgressSlidersetMinimumTrackTintColor:[UIColorwhiteColor]];
[_movieProgressSlidersetMaximumTrackTintColor:[UIColorcolorWithRed:0.49fgreen:0.48fblue:0.49falpha:1.00f]];
[_movieProgressSlidersetThumbImage:[UIImageimageNamed:@"progressThumb.png"]forState:UIControlStateNormal];
[_movieProgressSlideraddTarget:selfaction:@selector(scrubbingDidBegin)forControlEvents:UIControlEventTouchDown];
[_movieProgressSlideraddTarget:selfaction:@selector(scrubbingDidEnd)forControlEvents:(UIControlEventTouchUpInside |UIControlEventTouchCancel)];
[_bottomView addSubview:_movieProgressSlider];
_remainingTimeLable = [[UILabelalloc]initWithFrame:CGRectMake(bounds.size.height-63, bottomOrigin_y, 63, 20)];
_remainingTimeLable.font = [UIFontsystemFontOfSize:13];
_remainingTimeLable.textColor = [UIColorwhiteColor];
_remainingTimeLable.backgroundColor = [UIColorclearColor];
_remainingTimeLable.textAlignment =NSTextAlignmentCenter;
[_bottomView addSubview:_remainingTimeLable];
[self.viewaddSubview:_bottomView];
}
- (void)createBrightnessView{
_brightnessView = [[UIImageViewalloc]initWithFrame:CGRectMake(self.view.bounds.size.height/2-63,self.view.frame.size.width/2-63,125, 125)];
_brightnessView.image = [UIImageimageNamed:@"video_brightness_bg.png"];
_brightnessProgress = [[UIProgressViewalloc]initWithFrame:CGRectMake(_brightnessView.frame.size.width/2-40,_brightnessView.frame.size.height-30,80, 10)];
_brightnessProgress.trackImage = [UIImageimageNamed:@"video_num_bg.png"];
_brightnessProgress.progressImage = [UIImageimageNamed:@"video_num_front.png"];
_brightnessProgress.progress = [UIScreenmainScreen].brightness;
[_brightnessViewaddSubview:_brightnessProgress];
[self.viewaddSubview:_brightnessView];
_brightnessView.alpha =0;
}
- (void)createProgressTimeLable{
_progressTimeView = [[UIViewalloc]initWithFrame:CGRectMake(self.view.bounds.size.height/2-100,self.view.bounds.size.width/2-30,200, 60)];
_progressTimeLable_top = [[UILabelalloc]initWithFrame:CGRectMake(0,0, 200,30)];
_progressTimeLable_top.textAlignment =NSTextAlignmentCenter;
_progressTimeLable_top.textColor = [UIColorwhiteColor];
_progressTimeLable_top.backgroundColor = [UIColorclearColor];
_progressTimeLable_top.font = [UIFontsystemFontOfSize:25];
_progressTimeLable_top.shadowColor = [UIColorcolorWithRed:0green:0blue:0alpha:0.4];
_progressTimeLable_top.shadowOffset =CGSizeMake(1.0,1.0);
[_progressTimeViewaddSubview:_progressTimeLable_top];
_progressTimeLable_bottom = [[UILabelalloc]initWithFrame:CGRectMake(0,30, 200, 30)];
_progressTimeLable_bottom.textAlignment =NSTextAlignmentCenter;
_progressTimeLable_bottom.textColor = [UIColorwhiteColor];
_progressTimeLable_bottom.backgroundColor = [UIColorclearColor];
_progressTimeLable_bottom.font = [UIFontsystemFontOfSize:25];
_progressTimeLable_bottom.shadowColor = [UIColorcolorWithRed:0green:0blue:0alpha:0.4];
_progressTimeLable_bottom.shadowOffset =CGSizeMake(1.0,1.0);
[_progressTimeViewaddSubview:_progressTimeLable_bottom];
[self.viewaddSubview:_progressTimeView];
}
- (void)updateProfressTimeLable{
double currentTime =floor(_movieLength *_movieProgressSlider.value);
double changeTime =floor(_movieLength*ABS(_movieProgressSlider.value-_ProgressBeginToMove));
//转成秒数
NSDate *currentDate = [NSDatedateWithTimeIntervalSince1970:currentTime];
NSDate *changeDate = [NSDatedateWithTimeIntervalSince1970:changeTime];
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setTimeZone:[NSTimeZonetimeZoneForSecondsFromGMT:0]];
[formattersetDateFormat:(currentTime/3600>=1)?@"h:mm:ss":@"mm:ss"];
NSString *currentTimeStr = [formatter stringFromDate:currentDate];
[formattersetDateFormat:(changeTime/3600>=1)?@"h:mm:ss":@"mm:ss"];
NSString *changeTimeStr = [formatter stringFromDate:changeDate];
_progressTimeLable_top.text = currentTimeStr;
_progressTimeLable_bottom.text = [NSStringstringWithFormat:@"[ks:%@ %@]",(_movieProgressSlider.value-_ProgressBeginToMove) < 0? @"-":@"+",changeTimeStr];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"status"]) {
AVPlayerItem *playerItem = (AVPlayerItem*)object;
if (playerItem.status ==AVPlayerStatusReadyToPlay) {
//视频加载完成,去掉等待
[_progressHUDhide:YES];
//获取上次播放进度,仅对本地有效
if (!_isFirstOpenPlayer) {
CGFloat progress = [[DatabaseManagerdefaultDatabaseManager] getProgressByIdentifier:_movieTitle];
_movieProgressSlider.value = progress;
_isFirstOpenPlayer = YES;
[selfscrubbingDidEnd];
}
}
}
// if ([keyPath isEqualToString:@"loadedTimeRanges"]){
// float bufferTime = [self availableDuration];
// NSLog(@"缓冲进度%f",bufferTime);
// float durationTime = CMTimeGetSeconds([[_player currentItem] duration]);
// NSLog(@"缓冲进度:%f ,百分比:%f",bufferTime,bufferTime/durationTime);
// }
}
//加载进度
//- (float)availableDuration
//{
// NSArray *loadedTimeRanges = [[_player currentItem] loadedTimeRanges];
// if ([loadedTimeRanges count] > 0) {
// CMTimeRange timeRange = [[loadedTimeRanges objectAtIndex:0] CMTimeRangeValue];
// float startSeconds = CMTimeGetSeconds(timeRange.start);
// float durationSeconds = CMTimeGetSeconds(timeRange.duration);
// return (startSeconds + durationSeconds);
// }else{
// return 0.0f;
// }
//}
#pragma mark - action
/*
*程序活动的动作
*/
- (void)becomeActive{
[self pauseBtnClick];
}
/*
*程序不活动的动作
*/
- (void)resignActive{
[self pauseBtnClick];
}
//播放/暂停
- (void)pauseBtnClick
{
_isPlaying = !_isPlaying;
if (_isPlaying) {
[_playerplay];
[_playBtnsetImage:[UIImageimageNamed:@"pause_nor.png"]forState:UIControlStateNormal];
}else{
[_playerpause];
[_playBtnsetImage:[UIImageimageNamed:@"play_nor.png"]forState:UIControlStateNormal];
}
}
//#define RateStep 0.5
//快退/快进
- (void)fastAction:(UIButton *)btn{
if (btn.tag ==1) {
[selfmovieProgressAdd:-MovieProgressStep];
}elseif (btn.tag ==2){
[selfmovieProgressAdd:MovieProgressStep];
}
}
//上一部/下一部
- (void)forWordOrBackWardMovieAction:(UIButton *)btn{
_movieProgressSlider.value =0.f;
[_progressHUD show:YES];
//下一部
[_player.currentItemremoveObserver:selfforKeyPath:@"status"];
NSDictionary *dic = nil;
if (btn.tag ==1) {
dic = [_datasourcenextMovieURLAndTitleToTheCurrentMovie];
}elseif(btn.tag ==2){
dic = [_datasourcepreviousMovieURLAndTitleToTheCurrentMovie];
}
_movieURL = (NSURL *)[dicobjectForKey:KURLOfMovieDicTionary];
AVPlayerItem *playerItem = [AVPlayerItemplayerItemWithURL:_movieURL];
[_playerreplaceCurrentItemWithPlayerItem:playerItem];
_movieTitle = [dicobjectForKey:KTitleOfMovieDictionary];
_titleLable.text =_movieTitle;
//注册检测视频加载状态的通知
[_player.currentItemaddObserver:selfforKeyPath:@"status"options:NSKeyValueObservingOptionNewcontext:nil];
//检测上一部/下一部电影的存在性
if (_datasource && [_datasourceisHaveNextMovie]) {
[_forwardBtnsetImage:[UIImageimageNamed:@"forward_nor.png"]forState:UIControlStateNormal];
[_forwardBtnaddTarget:selfaction:@selector(forWordOrBackWardMovieAction:)forControlEvents:UIControlEventTouchUpInside];
}else{
[_forwardBtnsetImage:[UIImageimageNamed:@"forward_disable.png"]forState:UIControlStateNormal];
[_forwardBtnsetImage:[UIImageimageNamed:@"forward_disable.png"]forState:UIControlStateHighlighted];
[_forwardBtnremoveTarget:selfaction:@selector(forWordOrBackWardMovieAction:)forControlEvents:UIControlEventTouchUpInside];
}
if (_datasource && [_datasourceisHavePreviousMovie]) {
[_backwardBtnsetImage:[UIImageimageNamed:@"backward_nor.png"]forState:UIControlStateNormal];
[_backwardBtnaddTarget:selfaction:@selector(forWordOrBackWardMovieAction:)forControlEvents:UIControlEventTouchUpInside];
}else{
[_backwardBtnsetImage:[UIImageimageNamed:@"backward_disable.png"]forState:UIControlStateNormal];
[_backwardBtnsetImage:[UIImageimageNamed:@"backward_disable.png"]forState:UIControlStateHighlighted];
[_backwardBtnremoveTarget:selfaction:@selector(forWordOrBackWardMovieAction:)forControlEvents:UIControlEventTouchUpInside];
}
}
//视频播放到结尾
- (void)playerItemDidReachEnd:(NSNotification *)notification{
if (_currentPlayingItem+1 ==_movieURLList.count) {
[selfpopView];
}else{
++_currentPlayingItem;
[_playerreplaceCurrentItemWithPlayerItem:[AVPlayerItemplayerItemWithURL:_movieURLList[_currentPlayingItem]]];
if (_isPlaying ==YES){
[_playerplay];
}
// [_player.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
}
}
//声音增加
- (void)volumeAdd:(CGFloat)step{
[MPMusicPlayerControllerapplicationMusicPlayer].volume += step;;
}
//亮度增加
- (void)brightnessAdd:(CGFloat)step{
[UIScreen mainScreen].brightness += step;
_brightnessProgress.progress = [UIScreenmainScreen].brightness;
}
//快进/快退
- (void)movieProgressAdd:(CGFloat)step{
_movieProgressSlider.value += (step/_movieLength);
[selfscrubberIsScrolling];
}
//首次打开引导的点击消失
- (void)firstCoverOnClick:(UIButton *)button{
[button removeFromSuperview];
}
//返回事件
- (void)popView
{
//保存本次播放进度
[[DatabaseManagerdefaultDatabaseManager] addPlayRecordWithIdentifier:_movieTitleprogress:_movieProgressSlider.value];
[_player removeTimeObserver:_timeObserver];
[_playerreplaceCurrentItemWithPlayerItem:nil];//自动移除 observer
[[selfclass] cancelPreviousPerformRequestsWithTarget:self];
[[UIApplicationsharedApplication] setStatusBarHidden:NOwithAnimation:UIStatusBarAnimationNone];
[selfdismissViewControllerAnimated:YEScompletion:^{
self.timeObserver =nil;
self.player =nil;
[UIScreen mainScreen].brightness =_systemBrightness;
if ([_delegaterespondsToSelector:@selector(movieFinished:)]) {
[_delegatemovieFinished:_movieProgressSlider.value];
}
}];
}
//按动滑块
-(void)scrubbingDidBegin
{
_gestureType =GestureTypeOfProgress;
_ProgressBeginToMove =_movieProgressSlider.value;
_progressTimeView.hidden =NO;
}
//拖动进度条
-(void)scrubberIsScrolling
{
if (_mode ==MoviePlayerViewControllerModeNetwork) {
[_progressHUDshow:YES];
}
double currentTime =floor(_movieLength *_movieProgressSlider.value);
int i = 0;
double temp = [((NSNumber *)_itemTimeList[i])doubleValue];
while (currentTime > temp) {
++i;
temp += [((NSNumber *)_itemTimeList[i])doubleValue];
}
if (i !=_currentPlayingItem) {
[_playerreplaceCurrentItemWithPlayerItem:[AVPlayerItemplayerItemWithURL:(NSURL *)_movieURLList[i]]];
// [_player.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
_currentPlayingItem = i;
}
temp -= [((NSNumber *)_itemTimeList[i])doubleValue];
[selfupdateProfressTimeLable];
//转换成CMTime才能给player来控制播放进度
CMTime dragedCMTime = CMTimeMake(currentTime-temp, 1);
[_playerseekToTime:dragedCMTime completionHandler:
^(BOOL finish){
if (_isPlaying ==YES){
[_playerplay];
}
}];
}
//释放滑块
-(void)scrubbingDidEnd
{
_gestureType =GestureTypeOfNone;
_progressTimeView.hidden =YES;
[selfscrubberIsScrolling];
}
#pragma mark touch event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint currentLocation = [touch locationInView:self.view];
CGFloat offset_x = currentLocation.x -_originalLocation.x;
CGFloat offset_y = currentLocation.y -_originalLocation.y;
if (CGPointEqualToPoint(_originalLocation,CGPointZero)) {
_originalLocation = currentLocation;
return;
}
_originalLocation = currentLocation;
CGRect frame = [UIScreenmainScreen].bounds;
if (_gestureType == GestureTypeOfNone) {
if ((currentLocation.x > frame.size.height*0.8) && (ABS(offset_x) <= ABS(offset_y))){ _gestureType = GestureTypeOfVolume;
}elseif ((currentLocation.x < frame.size.height*0.2) && (ABS(offset_x) <= ABS(offset_y))){ _gestureType = GestureTypeOfBrightness;
}elseif ((ABS(offset_x) > ABS(offset_y))) {
_gestureType = GestureTypeOfProgress;
_progressTimeView.hidden =NO;
}
}
if ((_gestureType == GestureTypeOfProgress) && (ABS(offset_x) > ABS(offset_y))) {
if (offset_x > 0) {
// NSLog(@"横向向右");
_movieProgressSlider.value +=0.005;
}else{
// NSLog(@"横向向左");
_movieProgressSlider.value -=0.005;
}
[self updateProfressTimeLable];
}elseif ((_gestureType == GestureTypeOfVolume) && (currentLocation.x > frame.size.height*0.8) && (ABS(offset_x) <= ABS(offset_y))){
if (offset_y > 0){
[self volumeAdd:-VolumeStep];
}else{
[self volumeAdd:VolumeStep];
}
}elseif ((_gestureType == GestureTypeOfBrightness) && (currentLocation.x < frame.size.height*0.2) && (ABS(offset_x) <= ABS(offset_y))){
if (offset_y > 0) {
_brightnessView.alpha =1;
[self brightnessAdd:-BrightnessStep];
}else{
_brightnessView.alpha =1;
[self brightnessAdd:BrightnessStep];
}
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
_originalLocation = CGPointZero;
_ProgressBeginToMove = _movieProgressSlider.value;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
if (_gestureType == GestureTypeOfNone && !CGRectContainsPoint(_bottomView.frame, point) && !CGRectContainsPoint(_topView.frame, point)) {
//这说明是轻拍收拾,隐藏/现实状态栏
[UIView animateWithDuration:0.25 animations:^{
CGRect topFrame = _topView.frame;
CGRect bottomFrame = _bottomView.frame;
if (topFrame.origin.y<0) {
//显示
topFrame.origin.y =0;
bottomFrame.origin.y =self.view.frame.size.width-BottomViewHeight;
[self performSelector:@selector(hidenControlBar) withObject:nil afterDelay:3];
}else{
//隐藏
topFrame.origin.y = -TopViewHeight;
bottomFrame.origin.y =self.view.frame.size.width;
}
_topView.frame = topFrame;
_bottomView.frame = bottomFrame;
}];
}elseif (_gestureType == GestureTypeOfProgress){
_gestureType = GestureTypeOfNone;
_progressTimeView.hidden =YES;
[self scrubberIsScrolling];
}else{
_gestureType = GestureTypeOfNone;
_progressTimeView.hidden =YES;
if (_brightnessView.alpha) {
[UIView animateWithDuration:1 animations:^{
_brightnessView.alpha =0;
}];
}
}
}
- (void)hidenControlBar{
[UIView animateWithDuration:0.25 animations:^{
CGRect topFrame = _topView.frame;
CGRect bottomFrame = _bottomView.frame;
topFrame.origin.y = -TopViewHeight;
bottomFrame.origin.y =self.view.frame.size.width;
_topView.frame = topFrame;
_bottomView.frame = bottomFrame;
}];
}
#pragma mark - 系统相关
//隐藏状态栏
- (BOOL)prefersStatusBarHidden
{
returnYES;//隐藏为YES,显示为NO
}
//横屏
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscapeRight;
}
//- (void)dealloc{
// NSLog(@"dealloc");
// [super dealloc];
//}
@end
/*
* DatabaseManager
* 通过把播放过的影片的进度信息保存在plist文件中,实现记住播放历史的功能
* plist 文件采用队列形式,队列长度为50
*/
NSString *const MoviePlayerArchiveKey_identifier =@"identifier";
NSString *const MoviePlayerArchiveKey_date =@"date";
NSString *const MoviePlayerArchiveKey_progress =@"progress";
NSIntegerconst MoviePlayerArchiveKey_MaxCount = 50;
@implementation DatabaseManager
- (id)init{
self = [super init];
if (self) {
}
return self;
}
+ (DatabaseManager *)defaultDatabaseManager{
static DatabaseManager *manager = nil;
if (manager == nil) {
manager = [[DatabaseManager alloc]init];
}
return manager;
}
+ (NSString *)pathOfArchiveFile{
NSArray *filePath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentPath = [filePath lastObject];
NSString *plistFilePath = [documentPath stringByAppendingPathComponent:@"playRecord.plist"];
return plistFilePath;
}
- (void)addPlayRecordWithIdentifier:(NSString *)identifier progress:(CGFloat)progress{
NSMutableArray *recardList = [[NSMutableArray alloc]initWithContentsOfFile:[DatabaseManager pathOfArchiveFile]];
if (!recardList) {
recardList = [[NSMutableArray alloc]init];
}
if (recardList.count==MoviePlayerArchiveKey_MaxCount) {
[recardList removeObjectAtIndex:0];
}
NSDictionary *dic =@{MoviePlayerArchiveKey_identifier:identifier,MoviePlayerArchiveKey_date:[NSDate date],MoviePlayerArchiveKey_progress:@(progress)};
[recardList addObject:dic];
[recardList writeToFile:[DatabaseManager pathOfArchiveFile] atomically:YES];
}
- (CGFloat)getProgressByIdentifier:(NSString *)identifier{
NSMutableArray *recardList = [[NSMutableArray alloc]initWithContentsOfFile:[DatabaseManager pathOfArchiveFile]];
__block CGFloat progress = 0;
[recardList enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx,BOOL *stop) {
NSDictionary *dic = obj;
if ([dic[MoviePlayerArchiveKey_identifier] isEqualToString:identifier]) {
progress = [dic[MoviePlayerArchiveKey_progress] floatValue];
*stop =YES;
}
}];
if (progress > 0.9 || progress <0.05) {
return 0;
}
return progress;
}
@end
- avplayer
- AVplayer
- AVPlayer
- AVPlayer
- AVPlayer
- AVPlayer
- AVPlayer
- AVPlayer
- AVPlayer音量
- boost avplayer
- avplayer 分析
- 使用AVPlayer
- AVPlayer介绍
- 自定义AVPlayer
- AVPlayer demo
- [绍棠] avplayer
- AVPlayer翻译
- 封装Avplayer
- usrpasswd
- IOS block 块实现简单的页面跳转传值
- Leetcode 树 Binary Tree Level Order Traversal II
- 利用git制作和提交patch
- url
- AVPlayer
- 第十二话。还是上周的胖太,还是原来的味道!一指戳掉你二两肥肉
- ViewPager的简单应用
- log4j的学习
- POJ1269_Intersecting Lines(计算几何/两直线位置关系模板)
- linux和window文件共享 安装samba
- android 虚拟按键 增减和删除的方法
- 任何人的后入式
- 实现一个挺高级的字符匹配算法: 给一串很长字符串,要求找到符合要求的字符串,例如目的串:123 1******3***2 ,12*****3 这些都要找出来