iOS 教你使用MP、AVPlayer、AVPlayerVC构建视频播放器

苹果在视频播放方面提供了多个框架供我们选择使用。分别为:

基于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多行,之后有时间的话会再进行优化。

使用AVPlayer构建播放器

1.导入头文件

#import

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)BOOL isPlay;@property (nonatomic,strong)UISlider *movieProgressSlider;//进度条@property (nonatomic,assign)CGFloat ProgressBeginToMove;@property (nonatomic,assign)CGFloat totalMovieDuration;//视频总时间

//核心躯干@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)BOOL isShowView;@property (nonatomic,assign)BOOL isSettingsViewShow;@property (nonatomic,assign)BOOL isSlideOrClick;

@property (nonatomic,strong)UISlider *volumeViewSlider;@property (nonatomic,assign)float systemVolume;//系统音量值@property (nonatomic,assign)float systemBrightness;//系统亮度@property (nonatomic,assign)CGPoint startPoint;//起始位置坐标

@property (nonatomic,assign)BOOL isTouchBeganLeft;//起始位置方向@property (nonatomic,copy)NSString *isSlideDirection;//滑动方向@property (nonatomic,assign)float startProgress;//起始进度条

#pragma mark - 播放器躯干

- (void)createAvPlayer{

    //设置静音状态也可播放声音

    AVAudioSession *audioSession = [AVAudioSession sharedInstance];

    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];

    CGRect playerFrame = CGRectMake(0, 0, self.view.layer.bounds.size.height, self.view.layer.bounds.size.width);

    AVURLAsset *asset = [AVURLAsset assetWithURL: _url];

    Float64 duration = CMTimeGetSeconds(asset.duration);

    //获取视频总时长

    _totalMovieDuration = duration;

    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset: 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{

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

     if (_isShowView) {

        //上下View为显示状态,此时点击上下View直接return

        if ((point.y>CGRectGetMinY(self.topView.frame)&&point.y< CGRectGetMaxY(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];CGFloat changeY = 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;

        CGFloat changeY = point.y - _startPoint.y;

        CGFloat changeX = point.x - _startPoint.x;

        //如果位置改变 刷新进度条

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

            [self scrubberIsScrolling];

        }

        return;

    }//拖动进度条

-(void)scrubberIsScrolling{

    //计算出拖动的当前秒数(总长*当前百分比)

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

    CMTime newCMTime = CMTimeMake(dragedSeconds, 1);

    [_player seekToTime:newCMTime completionHandler:^(BOOL finished) {

        [_player play];

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

    }];

}

MPMediaPlayerController与AVPlayerViewController的使用介绍

MPMediaPlayerController与AVPlayerViewController,两者都是基于AVPlayer的简单UI封装,如果只是需要简单的视频播放功能,可以使用这两个类快速的构建视频播放器。

MPMediaPlayerController

1.导入头文件

#import

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

2.初始化AVPlayerViewController,创建一个AVPlayer添加上。然后将其添加到视图上,再将View添加到self.View上,然后play即可

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

AVPlayer * player = [AVPlayer playerWithURL:url1];AVPlayerViewController *playerController = [[AVPlayerViewController alloc]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];

同样几行代码,即可实现。

音量调整

1.导入头文件

#import

2.借助MPVolumeView类来获取到其音量进度条,进而进行音量获取与控制

@property (nonatomic,strong)UISlider *movieProgressSlider;//进度条

MPVolumeView *volumeView = [[MPVolumeView alloc] 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 *)touches withEvent:(UIEvent *)event{

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

    int index = location.y - _startPoint.y;

    if(index>0){

        [_volumeViewSlider setValue:_systemVolume - (abs(index)/10 * 0.05) animated:YES];

        [_volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

    }else{

       [_volumeViewSlider setValue:_systemVolume + (abs(index)/10 * 0.05) animated:YES];

        [_volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

    }

}

亮度调整

1.触摸屏幕时,记录手指按下的位置、按下时屏幕的亮度(实现touchesBegan方法)

2.手指在规定行为下(手指按下位置为视图左半区,且纵向滑动)持续滑动时,不断动态处理(实现touchesMoved方法)

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

//手指持续滑动,此方法会持续调用

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

    CGPoint location = [[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{

    return NO;

}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{

    return UIInterfaceOrientationMaskPortrait;

}

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

//允许横屏旋转

- (BOOL)shouldAutorotate{

    return YES;

}

//支持左右旋转

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{

    return UIInterfaceOrientationMaskLandscapeRight|UIInterfaceOrientationMaskLandscapeLeft;

}

//默认为右旋转

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{

    return UIInterfaceOrientationLandscapeRight;

}

结语

      怎么样,实现一个简单的视频播放器是不是很简单。当然,要做一个好的视频播放器,需要更多的优化处理、UI处理、业务功能扩展、动画效果....

the end

评论(0)