视频播放器(AVPlayer)

1.首先得创建AVPlayer,一个播放对象。
2.但是AVPlayer不能直接添加到self.view上,所以我们得创建一个 AVPlayerLayer的对象,是播放器所在的图层,设置视频填充的模式,然后将AVPlayer添加到此图层上,再将这个图层添加到self.view或者子视图的layer图层上。
3.设置播放的对象,就是AVPlayer播放的资源

下面是代码的展示:
一:首先我们需要引进能够支持AVPlayer视频播放的框架。同时这个框架还是音频播放的框架
#import <AVFoundation/AVFoundation.h>

将self.view的尺寸设置成全局
#define WIDTH self.view.bounds.size.width
#define HEIGHT self.view.bounds.size.height

@interface ViewController ()
在Main.storyboard将这些布局设置好。
@property ( weak , nonatomic ) IBOutlet UIView *buttomVIew; /**< 底部控制区 */
@property ( weak , nonatomic ) IBOutlet UIButton *buttomBtn;
@property ( weak , nonatomic ) IBOutlet UISlider *progress; /**< 进度条 */
@property ( weak , nonatomic ) IBOutlet UILabel *timeLabel; /**< 时间显示 */
@property ( weak , nonatomic ) IBOutlet UIView *playerView; /**< 播放视图 */

进行基本属性的设置
@property ( nonatomic , strong ) AVPlayer *player; /**< 播放器对象 */
@property ( nonatomic , strong ) AVPlayerLayer *playerLayer; /**< 播放图层 */
@property ( nonatomic , strong ) AVPlayerItem *playerItem; /**< 播放对象 */
@property ( nonatomic , assign ) BOOL isPlay; /**< 是否播放 */
@property ( nonatomic , assign ) BOOL isDismiss; /**< 是否隐藏 */
@property ( nonatomic , assign ) CGFloat totalDuration; /**< 总时长 */
@end

二:在viewDidLoad中需要实现的方法或者设置的总体步骤
- ( void )viewDidLoad {
    [
super viewDidLoad ];
   
// Do any additional setup after loading the view, typically from a nib.
   
// 初始化播放器
    [
self createAVPlayer ];
   
// 播放
    [
_player play ];
   
// 开始播放
   
_isPlay = YES ;
   
// 初始化时间显示
   
_timeLabel . text = @"00:00/00:00" ;
   
// 初始化进度条
    _progress.value = 0;
    // 添加手势 隐藏边栏<下边栏>
    [ self addTapToDismissBar ];
   
// 通过通知中心监听 播放器 / 视频 / 页面 状态信息
    [
self addNotificationCenter ];
   
// 进度条监听
    [self progressObserving];

:初始化这个播放器

#pragma mark - 初始化播放器
- ( void )createAVPlayer
{
    // 视频网址
    NSURL *url = [ NSURL URLWithString :str];
    // 创建播放对象 (playerItem),就是需要播放的资源
    self . playerItem = [ AVPlayerItem playerItemWithURL :url];
    // 创建播放器 (player)
    self . player = [ AVPlayer playerWithPlayerItem : _playerItem ];
    // 创建显示 layer(playerLayer) 只有放在这个layer上才可以显示。
    self . playerLayer = [ AVPlayerLayer playerLayerWithPlayer : _player ];
    // layer 需要设置大小
    _playerLayer . frame = CGRectMake ( 5 , 5 , self . view . bounds . size . width - 10 , _playerView . frame . size . height - 10 );
    // 视频填充模式 
    _playerLayer . videoGravity = AVLayerVideoGravityResizeAspectFill ;
    // 将显示的图层 放在页面里显示
    [ _playerView . layer insertSublayer : _playerLayer atIndex : 0 ];
}

四:添加手势
#pragma mark - 添加手势
- ( void )addTapToDismissBar
{
    UITapGestureRecognizer *tap = [[ UITapGestureRecognizer alloc ] initWithTarget : self action : @selector (tapAction:)];
    [ _playerView addGestureRecognizer :tap];
}

#pragma mark - 隐藏边栏
- ( void )tapAction:( UITapGestureRecognizer *)tap
{
    // 初始播放 还未隐藏 isDismiss = NO
    // 隐藏
    if (! _isDismiss ) {
        // 隐藏边栏
        [ UIView animateWithDuration : 0.5 animations :^{
            _buttomVIew . alpha = 0 ;
        }];
    } else {
        // 显示边栏
        [ UIView animateWithDuration : 0.5 animations :^{
            _buttomVIew . alpha = 0.8 ;
        }];
    }
    _isDismiss = ! _isDismiss ;
}

五:#pragma mark - 通知中心
- ( void )addNotificationCenter
{
    // 是否播放完成
    [[ NSNotificationCenter defaultCenter ] addObserver : self selector : @selector (moviePlayDidEnd:) name : AVPlayerItemDidPlayToEndTimeNotification object : nil ];
    // 监听屏幕旋转
    [[ NSNotificationCenter defaultCenter ] addObserver : self selector : @selector (statusBarPositionChange:) name : UIApplicationDidChangeStatusBarOrientationNotification object : nil ];
}
#pragma mark -视频播放结束时进行的操作,可以在这里设置,进行下一个视频的播放。
- ( void )moviePlayDidEnd:( NSNotification *)noti
{
    NSLog ( @" 视频播放已经结束 " );
}
#pragma mark -监听屏幕是否旋转
- ( void )statusBarPositionChange:( NSNotification *)noti
{
    // 使用代码监听横竖屏
    // 获取状态栏方向
    UIInterfaceOrientation orientation = [[ UIApplication sharedApplication ] statusBarOrientation ];
    // 判断
    if (orientation == UIInterfaceOrientationLandscapeLeft ) {
        NSLog ( @" 向左横屏 " );
        [ self landscape ];
    } else if (orientation == UIInterfaceOrientationLandscapeRight ) {
        NSLog ( @" 向右横屏 " );
        [ self landscape ];
    } else if (orientation == UIInterfaceOrientationPortrait ) {
        NSLog ( @" 竖屏 " );
        [ self portrait ];
    }
}
#pragma mark - 横屏设置
- ( void )landscape
{
    _playerView . frame = self . view . bounds ;
    _playerView . backgroundColor = [ UIColor redColor ];
    _playerLayer . frame = CGRectMake ( 5 , 5 , WIDTH - 10 , HEIGHT - 10 );
    NSLog ( @"%@ %@" , NSStringFromCGRect ( _playerView . frame ), NSStringFromCGRect ( self . view . frame ));
}
#pragma mark - 竖屏设置
- ( void )portrait
{
    _playerView . backgroundColor = [ UIColor cyanColor ];
    _playerLayer . frame = CGRectMake ( 5 , 5 , WIDTH - 10 , 230 );
}

六:进度条监听 
/*
 CMTimeMake 是用來建立 CMTime 用的 ,
 CMTime 可是专门用来表示视频时间的 ,
  用法 : CMTimeMake(time, timeScale)
 
 time 指的就是时间 ( 不是秒 ),
  而时间要换成秒就要看第二个参数 timeScale .
 timeScale 指的是 1 秒需要由多少帧率构成 ,
  真正表示时间秒是 time / timeScale .
 
 CMTime curFrame = CMTimeMake( 第几帧, 帧率)
 
 */
#pragma mark - 进度条监听
- ( void )progressObserving
{
    // 设置 (1, 1) 每秒刷新一次
    // 参数 1: 时间监听器刷新时间
    // 参数 2: 队列
    // 参数 3: 刷新时执行的 block
    __weak ViewController *vc = self ;
    [ _player addPeriodicTimeObserverForInterval : CMTimeMake ( 1 , 1 ) queue : dispatch_get_main_queue () usingBlock :^( CMTime time) {
        // 获取总时长
        CGFloat duration = CMTimeGetSeconds (vc. playerItem . duration );
        // 获取当前时长
        CGFloat current = CMTimeGetSeconds (vc. player . currentTime );
        // 获取倒计时
        CGFloat rem = duration - current;
       
        // 剩余时间
        NSString *totalT = [ NSString stringWithFormat : @"%02d:%02d" , ( int )rem / 60 , ( int )rem % 60 ];
        // 当前时间
        NSString *currentT = [ NSString stringWithFormat : @"%02d:%02d" , ( int )current / 60 , ( int )current % 60 ];
        // 拼接时间
        NSString *timeStr = [ NSString stringWithFormat : @"%@/%@" , currentT, totalT];
        vc. timeLabel . text = timeStr;
        // 保存总时长 用于 slider 手动控制进度
        vc. totalDuration = duration;
        // 控制 slider 的当前进度
        vc. progress . value = current / duration;
    }];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值