AVPlayer 实现视频播放器的开发

最近由于需求要自己单独实现视频播放,但是在网上走遍,取到的Demo都不尽人意,要么无法实现按钮的显示隐藏,要么拖动视频进度滑竿无法快进,再次自己做了一个Demo,链接为
视频播放器Demo
视频播放器播放效果图
在iOS开发中,播放视频通常有两种方式,一种是使用MPMoviePlayerController(需要导入 MediaPlayer.Framework框架)使用方法可参考 http://blog.csdn.net/zzfsuiye/article/details/7824692,还有一种是使用AVPlayer,需要导入 AVFoundation/AVFoundation.h框架,使用稍微麻烦点,不过功能更加强大.其不仅能够播放视频(设置layer层时),而且可以实现音频播放(取消layer层的添加),能够实现在线播放等功能.

storyBoard的布局如图:

第一步 : 首先创建一个播放器视图控制器MoviePlayerController,继承自UIViewController,在其MoviePlayerController.m的延展接口 内配置如下属性:

#import "MoviePlayerController.h"
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>

//声明宏 显示主屏的宽高
#define  kHeight    ([[UIScreen mainScreen]bounds].size.width)
#define  kWidth     ([[UIScreen mainScreen]bounds].size.height)

@interface MoviePlayerController ()

@property(nonatomic,strong)AVPlayer *player; //创建播放器
@property(nonatomic,strong)AVPlayerItem *playItem; //播放对象
@property(nonatomic,strong)AVPlayerLayer *layer; //播放图层
@property (strong, nonatomic) IBOutlet UIView *backView;//和屏幕大小一样的透明的视图,其上加载有滑竿,topView,暂停按钮 , 置于控制器视图最前端
@property (strong, nonatomic) IBOutlet UIView *topView;//其上放置了返回按钮(还可以添加label显示电影名,此处省略没有添加)
@property (strong, nonatomic) IBOutlet UIButton *backButton;//返回按钮
@property (strong, nonatomic) IBOutlet UIButton *playPauseButton;//播放/暂停按钮
@property (strong, nonatomic) IBOutlet UISlider *slideView;//进度滑竿
@end

二.在viewDidLoad方法中创建播放器,并通过通知中心添加观察者监控当前播放节目的状态,同时添加计时器监听节目的时间来实现滑竿的进度变化,为了实现轻拍手势显隐 backView上的控件需要将backView置于界面的最上层

- (void)viewDidLoad {
    [super viewDidLoad];
    [self playMovie];
        //AVPlayer播放完成通知
    //给电影播放器player的当前播放对象 添加观察者,监控当前电影的播放进度
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:_player.currentItem];
   //计时器监听正在播放的节目的当前时间进度,每隔1秒 改变滑竿的滑块位置
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(sliderChange) userInfo:nil repeats:YES];

    //将放置按钮 (返回, 暂停,滑竿等)的backView移动至最顶层
    [self.view bringSubviewToFront:self.backView];
}
//改变滑竿的滑块位置(滑竿的范围设置为0-1)
- (void)sliderChange {
    CGFloat rateK = CMTimeGetSeconds(self.player.currentTime) / CMTimeGetSeconds(self.playItem.duration);    //当前时间除以总的视频时间,(这里滑竿的范围设置为0-1,如果不为0-1则需要rateK * 滑竿范围(max - min)后赋值给下边代码的value)
    self.slideView.value = rateK;
}
***AVPlayer实现的播放器需要添加layer层(相当于影院放映室的幕布),并将其添加到视图控制器的layer层上***

#pragma mark --------------------播放节目
-(void)playMovie{
    //创建要播放的节目
    self.playItem  = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://baobab.cdn.wandoujia.com/14468618701471.mp4"]];
    //创建播放器及播放的节目
    self.player = [AVPlayer playerWithPlayerItem:self.playItem];
//     self.player = [AVPlayer playerWithURL:[ NSURL URLWithString:@"http://baobab.cdn.wandoujia.com/14468618701471.mp4"]];
    //创建播放图层(框) : 相当于电影播放时的幕布
    AVPlayerLayer * playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
    playerLayer.frame = CGRectMake(0, 0, kWidth, kHeight);//设置播放框大小
    //视频根据重力重设自适应size(用于横屏等转屏实现)
    playerLayer.videoGravity = AVLayerVideoGravityResize;

    [self.view.layer addSublayer:playerLayer];
    [self.player play];//播放器播放节目
}

三. 通常点击视频播放后视频进入横屏状态其代码段如下:

#pragma mark -------------------------------------- 横屏代码  (UIViewController的方法)
//当前viewcontroller是否支持转屏
- (BOOL)shouldAutorotate{
    return NO;
}
//当前viewcontroller支持哪些转屏方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscape;
}
//设置转屏方式
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeRight;
}
//设置转屏bar隐藏
- (BOOL)prefersStatusBarHidden {
    return NO; // 返回NO表示要显示,返回YES将hidden
}

四. 对于事件的处理,主要包括 轻拍实现暂停/播放按钮 , 返回按钮,滑竿等控件的显示隐藏

#pragma mark -----------------------------------------轻拍手势事件
- (IBAction)handleTapGuesterAction:(UITapGestureRecognizer *)sender {
    if (self.backView.hidden == NO) {//显示
        self.backView.hidden =!self.backView.hidden;
    } else {
        self.backView.hidden =!self.backView.hidden;
    }
}

#pragma mark --------------------------------------------button事件
//  播放/暂停
- (IBAction)handlePlayPauseButtonAction:(UIButton *)sender {
    //当播放速率为零时表示暂停,为1表示正常速率播放
   if (self.player.rate == 0) {
      [self.player play];
      [sender setImage:[UIImage imageNamed:@"playBtn"] forState:UIControlStateNormal];
    }else{
      [self.player pause];
      [sender setImage:[UIImage imageNamed:@"pauseBtn"] forState:UIControlStateNormal];
    }
}

//返回电影列表界面(返回按钮)
- (IBAction)goBackMovieListButtonAction:(UIButton *)sender {
    [self.player pause];
    [self dismissViewControllerAnimated:YES completion:^{
    }];
}

#pragma mark ----------------------------------------拖动滑竿滑块改变视频播放进度
- (IBAction)prograssSliderAction:(UISlider *)sender {
    if (self.player.status == AVPlayerStatusReadyToPlay) {
        //计算出拖动停止时滑块位置对应的视频的时间
        //self.playItem.duration.value  当前节目的帧数,
        //self.playItem.duration.timescale  当前节目的每一秒播放的帧数
        float currTimeSecond = sender.value * (self.playItem.duration.value/self.playItem.duration.timescale);
        //转换成CMTime才能给player来控制播放进度, 因为视频的播放是以帧为单位的
        CMTime dragedCMTime = CMTimeMake(currTimeSecond, 1);
        [self.player seekToTime:dragedCMTime completionHandler:^(BOOL finish){
            [_player play];
        }];
    }
}
#pragma mark ----------------------播放结束事件
- (void)moviePlayDidEnd:(id)sender {
    //    [_player pause];
    [self dismissViewControllerAnimated:YES completion:^{
    }];
}

Share with you, never stop asking others when you have any questions , send emails to my email : nynxsjy@163.com


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值