天天看點

iOS視訊播放器AVPlayer建立

前言

:AVPlayer是用于管理媒體資産的播放和定時控制器對象它提供了控制播放器的有運輸行為的接口,如它可以在媒體的時限内播放,暫停,和改變播放的速度,并有定位各個動态點的能力。可以使用AVPlayer來播放本地和遠端的視訊媒體檔案,如QuickTime影片和MP3音頻檔案,以及視聽媒體使用HTTP流媒體直播服務。

一個普通播放器的組成
iOS視訊播放器AVPlayer建立

蘋果在視訊播放方面提供了多個架構供我們選擇使用。分别為:

基于mediaPlayer類庫的MPMediaPlayerController(iOS9後遭到廢棄,被AVPlayerViewController所替代)

基于AVFounditon類庫的AVPlayer

基于AVKit類庫的AVPlayerViewController(iOS8後才可使用)

正文

AVPlayer與MPMediaPlayerController比較:

AVplayer有比較靈活,當然,也需要你去自定義建構UI。還有一大優勢,例如其擴充的AVQueuePlayer,可以實作

視訊無縫隊列播放、多視訊同時播放、視訊轉換、編解碼

等功能。

MPMediaPlayerController實際上是基于AVPlayer的簡單UI封裝,對于一般的播放要求,幾行代碼就可實作,省心省事。

因為MPMediaPlayerController是對AVPlayer進行的單例封裝,是以

不能進行多視訊播放

播放器Demo(全屏)已實作功能點:

push到播放器頁面,橫屏顯示。

單機隐藏or顯示上方标題欄與下方操作欄。

呼出右側設定欄。

視訊播放操作與進度條設定。

在螢幕上左右拖動,進行視訊快進與快退。

在螢幕左側上下拖動,進行亮度調整。

在螢幕右側上下拖動,進行音量調整。

想到但是暫未實作的功能點:(大多為優化或與業務相關)

螢幕或進度條拖動快進操作時,添加提示框進行快進時間的實時提示。

使用者無操作兩三秒之後自動隐藏上下View。

視訊清晰度調整按鈕。(更換視訊源)

操作加鎖按鈕。(加鎖後未進行解鎖操作之前不可進行操作)

彈幕相關。

使用者允許橫屏狀态下,橫屏豎屏自動進行頁面切換與動畫效果等。

網絡視訊的緩存、下載下傳等。

軟硬解碼模式切換等。

筆者Demo選擇使用了AVPlayer進行視訊播放器的建構。由于UI的代碼實作,加上略蛋疼的邏輯代碼,播放器頁面的代碼量達到400多行,之後有時間的話會再進行優化。這裡隻貼出部分代碼,想要檢視或借鑒完整Demo,可以到本人

github

去下載下傳。

使用AVPlayer建構播放器

1.導入頭檔案

#import<AVFoundation/AVFoundation.h>

2.其實沒什麼可說的,很簡單,先初始化AVPlayer,然後添加到AVPlayerLayer,最後将其添加到視圖的layer層。

#pragma mark - Demo中此視圖的屬性

#define TopViewHeight 55

#define BottomViewHeight 72

#define mainWidth [UIScreen mainScreen].bounds.size.width

#define mainHeight [UIScreen mainScreen].bounds.size.height

//上層建築@property(nonatomic,strong)UIView*topView;

@property(nonatomic,strong)UIButton*backBtn;

@property(nonatomic,strong)UILabel*titleLabel;

@property(nonatomic,strong)UIButton*settingsBtn;

@property(nonatomic,strong)UIView*bottomView;

@property(nonatomic,strong)UIButton*playBtn;

@property(nonatomic,strong)UILabel*textLabel;

@property(nonatomic,assign)BOOLisPlay;

@property(nonatomic,strong)UISlider*movieProgressSlider;//進度條@property(nonatomic,assign)CGFloatProgressBeginToMove;

@property(nonatomic,assign)CGFloattotalMovieDuration;//視訊總時間@property(nonatomic,strong)AVPlayer*player;

@property(nonatomic,strong)UIView*settingsView;

@property(nonatomic,strong)UIView*rightView;

@property(nonatomic,strong)UIButton*setTestBtn;

//touch evens

@property(nonatomic,assign)BOOLisShowView;

@property(nonatomic,assign)BOOLisSettingsViewShow;

@property(nonatomic,assign)BOOLisSlideOrClick;

@property(nonatomic,strong)UISlider*volumeViewSlider;

@property(nonatomic,assign)floatsystemVolume;//系統音量值@property(nonatomic,assign)floatsystemBrightness;//系統亮度@property(nonatomic,assign)CGPointstartPoint;//起始位置坐标@property(nonatomic,assign)BOOLisTouchBeganLeft;//起始位置方向@property(nonatomic,copy)NSString*isSlideDirection;//滑動方向@property(nonatomic,assign)floatstartProgress;//起始進度條

#pragma mark - 播放器

- (void)createAvPlayer{

//設定靜音狀态也可播放聲音

AVAudioSession*audioSession = [AVAudioSessionsharedInstance]; 

  [audioSession setCategory:AVAudioSessionCategoryPlaybackerror:nil];

CGRectplayerFrame =CGRectMake(0,0,self.view.layer.bounds.size.height,self.view.layer.bounds.size.width);AVURLAsset  *asset = [AVURLAssetassetWithURL: _url]; 

  Float64 duration = CMTimeGetSeconds(asset.duration);

//擷取視訊總時長

_totalMovieDuration = duration;

AVPlayerItem*playerItem = [AVPlayerItemplayer ItemWithAsset: asset]; 

_player = [[AVPlayer  alloc]initWithPlayerItem:playerItem];

AVPlayerLayer  *playerLayer = [AVPlayerLayer  playerLayerWithPlayer:_player];    playerLayer.frame = playerFrame;  

playerLayer.videoGravity =AVLayerVideoGravityResizeAspect; 

  [self.view.layer addSublayer:playerLayer];

//需要設定自動播放的直接play即可

//[_player play];

}

螢幕單擊手勢與視訊快進

螢幕單擊

1.符合條件的情況下(手指按下後離開螢幕,并且沒有拖動)通過BOOL值判斷,隐藏或顯示上下View

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event{

CGPointpoint = [[touches anyObject] locationInView:self.view];

if(_isShowView) {

//上下View為顯示狀态,此時點選上下View直接return

if((point.y>CGRectGetMinY(self.topView.frame)&&point.yCGRectGetMinY(self.bottomView.frame))) {

return

}   

    _isShowView =NO;    

  [UIView  animateWithDuration:0.5  animations:^{   

        _topView.alpha =0;       

    _bottomView.alpha =0; 

      }];

  }else{    

  _isShowView =YES;     

  [UIView  animateWithDuration:0.5  animations:^{    

      _topView.alpha =1;       

    _bottomView.alpha =1;   

    }]; 

  }

2.右側View顯示的狀态下,點選螢幕左半空白區域,隐藏右側View

if(_isSettingsViewShow) {

if(point.x>CGRectGetMinX(_rightView.frame)&&point.x< CGRectGetMaxX(_rightView.frame)) {   

    return;

  }

_settingsView.alpha =0;

_isSettingsViewShow= NO;

拖動快進

1.計算後得出拖動方向為橫向拖動。

CGPoint location = [[touches  anyObject] locationInView:self.view];

CGFloatchangeY = location.y - _startPoint.y;

CGFloat  changeX = location.x - _startPoint.x;

if(fabs(changeX) > fabs(changeY)){ 

  _isSlideDirection =@"橫向";//設定為橫向

}else if(fabs(changeY)>fabs(changeX)){

  _isSlideDirection =@"縱向";//設定為縱向

}else{ 

  _isSlideOrClick =NO;

NSLog(@"不在五行中。");

2.根據手指按下與離開螢幕後,橫向位移的坐标值,對視訊播放進度進行重新整理。

if(_isSlideOrClick) { 

      _isSlideDirection =@"";  

    _isSlideOrClick =NO;

CGFloatchangeY = point.y - _startPoint.y;

CGFloatchangeX = point.x - _startPoint.x;

//如果位置改變 重新整理進度條

if(fabs(changeX) > fabs(changeY)){    

      [selfscrubberIsScrolling];  

    }

return;

    }

//拖動進度條

-(void)scrubberIsScrolling{

//計算出拖動的目前秒數(總長*目前百分比)

NSInteger  dragedSeconds = floorf(_totalMovieDuration * _movieProgressSlider.value);

CMTime  newCMTime =CMTimeMake(dragedSeconds,1);   

[_player seekToTime:newCMTime completionHandler:^(BOOLfinished) {  

    [_player play];   

    [_playBtn setTitle:@"暫停"forState:UIControlStateNormal];  

}];

MPMediaPlayerController與AVPlayerViewController的使用介紹

MPMediaPlayerController與AVPlayerViewController,兩者都是基于AVPlayer的簡單UI封裝,如果隻是需要簡單的視訊播放功能,可以使用這兩個類快速的建構視訊播放器。

MPMediaPlayerController
#import<MediaPlayer/MediaPlayer.h>

2.初始化mp,幾行代碼既可以實作。

@property(nonatomic,strong)MPMoviePlayerController *mp;

NSURL*url1 = [[NSBundle  mainBundle]URLForResource:@"chenyifaer"withExtension:@"mp4"];

_mp = [[MPMoviePlayerController  alloc] initWithContentURL:url1];

_mp.controlStyle =MPMovieControlStyleNone;

_mp.view.frame = CGRectMake(0,0,self.view.layer.bounds.size.height,self.view.layer.bounds.size.width);[self.view addSubview:_mp.view];

[_mp play];

controlStyle屬性有三個值:

MPMovieControlStyleNone,      //無控制

MPMovieControlStyleEmbedded,  //有全屏按鈕與控制

MPMovieControlStyleFullscreen, // 預設全屏,有退出和控制

當然還有一些其他屬性,有需要可以自行進行設定。

AVPlayerViewController

1.導入架構與頭檔案

#import<AVKit/AVKit.h>

2.初始化AVPlayerViewController,建立一個AVPlayer添加上。然後将其添加到視圖上,再将View添加到self.View上,然後play即可

NSURL*url1 = [[NSBundle mainBundle]URLForResource:@"chenyifaer"withExtension:@"mp4"];

AVPlayer* player = [AVPlayer playerWithURL:url1];

AVPlayerViewController *playerController = [[AVPlayerViewControlleralloc]init];

playerController.player = player;

[self addChildViewController:playerController];

[self.view addSubview:playerController.view];

playerController.view.frame =CGRectMake(0,0,self.view.layer.bounds.size.height,self.view.layer.bounds.size.width);[player  play];

同樣幾行代碼,即可實作。

音量調整

2.借助MPVolumeView類來擷取到其音量進度條,進而進行音量擷取與控制

@property(nonatomic,strong)UISlider*movieProgressSlider;//進度條MPVolumeView*volumeView = [[MPVolumeViewalloc] init];

_volumeViewSlider =nil;

for(UIView*view  in [volumeView subviews]){

if([view.class.description isEqualToString:@"MPVolumeSlider"]){        _volumeViewSlider = (UISlider*)view;

break;

3.觸摸螢幕時,記錄手指按下的位置、擷取按下時系統的音量(實作touchesBegan方法)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{        _startProgress = _movieProgressSlider.value;

4.手指在規定行為下(手指按下位置為視圖右半區,且縱向滑動)持續滑動時,動态改變系統音量(實作touchesMoved方法)

//手指持續滑動,此方法會持續調用

- (void)touchesMoved:(NSSet *)toucheswithEvent:(UIEvent *)event{  

CGPoint location = [[touches anyObject]locationInView:self.view];

intindex = location.y - _startPoint.y;if(index>0){        [_volumeViewSlidersetValue:_systemVolume - (abs(index)/10*0.05)animated:YES];        [_volumeViewSlidersendActionsForControlEvents:UIControlEventTouchUpInside];    }else{  

  [_volumeViewSlidersetValue:_systemVolume + (abs(index)/10*0.05)animated:YES];        [_volumeViewSlidersendActionsForControlEvents:UIControlEventTouchUpInside];    }

亮度調整

1.觸摸螢幕時,記錄手指按下的位置、按下時螢幕的亮度(實作touchesBegan方法)

2.手指在規定行為下(手指按下位置為視圖左半區,且縱向滑動)持續滑動時,不斷動态處理(實作touchesMoved方法)

3.改變螢幕亮度:[UIScreen mainScreen].brightness = X (0~1);

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{    CGPointlocation= [[touches anyObject] locationInView:self.view];

int index= location.y - _startPoint.y;

if(index>0){     

 [UIScreen mainScreen].brightness = _systemBrightness -abs(index)/10*0.01; 

  }else{   

    _movieProgressSlider.value = _startProgress -abs(index)/10*0.008;   

}

螢幕旋轉

1.設定應用支援橫屏(預設支援)。

2.在根視圖中設定預設豎屏(Nav、TabBar、VC基類)

- (BOOL)shouldAutorotate{returnNO;}- (UIInterfaceOrientationMask)supportedInterfaceOrientations{

returnUIInterfaceOrientationMaskPortrait;

3.在需要橫屏的VC中重寫下列方法即可

//允許橫屏旋轉

- (BOOL)shouldAutorotate{returnYES;

//支援左右旋轉

-(UIInterfaceOrientationMask)supportedInterfaceOrientations{

return UIInterfaceOrientationMaskLandscapeRight|UIInterfaceOrientationMaskLandscapeLeft;

}//預設為右旋轉

-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{

returnUIInterfaceOrientationLandscapeRight;

參考:

1.

http://www.techotopia.com/index.php/iOS8AVPlayerAndPlayerViewController 2. http://stackoverflow.com/questions/8146942/avplayer-and-mpmovieplayercontroller-differences 3. http://www.jianshu.com/p/e64fe3c7f9ab 4. http://www.th7.cn/Program/IOS/201504/439086.shtml