AVPlayer网络、本地视频播放(音乐也可以直接传入即可播放)

横竖屏切换方法整理
横竖屏参考链接


1. AVPlayer播放原理整个播放视频的步骤。

1,首先,得到视频的URL
2,根据URL创建AVPlayerItem
3,把AVPlayerItem 提供给 AVPlayer
4,AVPlayerLayer 显示视频。
5,AVPlayer 控制视频, 播放, 暂停, 跳转 等等。
6,播放过程中获取缓冲进度,获取播放进度。
7,视频播放完成后做些什么,是暂停还是循环播放,还是获取最后一帧图像。

2,AVPlayer相关概念

#1,AVPlayer 管理和调控(播放, 暂停, 跳转 等等)。
#2,AVPlayerLayer 显示视频,
#3,AVPlayerItem 提供视频信息(一个 AVPlayerItem 对应着一个URL视频资源。)

#使用 AVPlayer 时需要注意,AVPlayer 本身并不能显示视频, 显示视频的是 AVPlayerLayer。 
#AVPlayerLayer 继承自 CALayer,添加到 view.layer 上就可以使用了。

注意1:

在播放视频时,特别是播放网络视频往往需要知道视频加载情况、缓冲情况、播放情况,这些信息可以通过KVO监控AVPlayerItem的status、loadedTimeRanges属性来获得。

注意2:

当AVPlayerItem的status属性为AVPlayerStatusReadyToPlay是说明正在播放,只有处于这个状态时才能获得视频时长等信息;

注意3:缓存进度条UIProgress和滑块UISlider分别是干什么的?

1,UIProgress:显示当前视频缓存的进度。
2,UISlider:显示当前播放位置,以及快进、后退功能。


3,AVPlayerItem常用属性:(由2,3可以做缓存进度条功能)
1,asset;//URL视频的信息. 
2,duration; // 获取视频总时间长度
#注意:使用CMTimeGetSeconds(duration)把时间转化成秒。
3,loadedTimeRanges; //已缓冲进度。(kvo监听)
// 计算当前已经缓冲的时间 = start + duration
- (NSTimeInterval)availableDurationRanges {
    // 1,获取item的缓冲数组
    NSArray *loadedTimeRanges = [_playerItem loadedTimeRanges];
    
    // CMTimeRange 结构体 start、duration 表示起始位置 和 持续时间
    CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue]; // 获取缓冲区域
    float startSeconds = CMTimeGetSeconds(timeRange.start);
    float durationSeconds = CMTimeGetSeconds(timeRange.duration);
    
    // 计算总缓冲时间 = start + duration
    NSTimeInterval result = startSeconds + durationSeconds;
    return result;
}

4,AVPlayer:可以监听每秒的状态,从而获取每秒钟,AVPlayerItem正在播放第几秒。(可以完成UISlider功能,显示当前播放位置)

/*
 用于监听播放时每秒的状态。
该方法在卡顿的时候不会回调,没有找到相关API。
采用的是开启定时器,然后用一个lastTime保留当前的播放进度,当下次调用的时候用lastTime跟当前的进度进行比较,如果相等说明播放卡顿了。
 self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(upadte)];
    [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

//更新方法
- (void)upadte
{
    NSTimeInterval current = CMTimeGetSeconds(self.avPlayer.currentTime);
    NSTimeInterval total = CMTimeGetSeconds(self.avPlayer.currentItem.duration);
   //如果用户在手动滑动滑块,则不对滑块的进度进行设置重绘
    if (!self.slider.isSliding) {
        self.slider.sliderPercent = current/total;
    }

    if (current!=self.lastTime) {
        [self.activity stopAnimating];
        self.timeLabel.text = [NSString stringWithFormat:@"%@/%@", [self formatPlayTime:current], [self formatPlayTime:total]];
    }else{
        [self.activity startAnimating];
    }
    self.lastTime = current;
}

    interval:为响应的间隔时间,这里设为每秒都响应,
    queue:是队列,传NULL代表在主线程执行。
- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block;

    这里通过addPeriodicTimeObserverForInterval获取每秒的状态,
    但还是通过AVPlayerItem的属性currentTime来获取当前播放在第几秒
 */
- (void)monitoringPlayback:(AVPlayerItem *)item {
    __weak typeof(self)WeakSelf = self;
    _playTimeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
            // 当前播放在第几秒
            float currentPlayTime = (double)item.currentTime.value/ item.currentTime.timescale;
            [WeakSelf updateVideoSlider:currentPlayTime];
    }];
}
// 更新滑动条
- (void)updateVideoSlider:(float)currentTime {
    self.playProgress.value = currentTime;
    //convertTime:秒转时间格式mm:ss
    self.beginLabel.text = [NSString convertTime:currentTime];
}

5,两个细节:

//一定要设置AVPlayerLayer中的模式,videoGravity模式默认为AVLayerVideoGravityResizeAspect,就不会是会有空隙,不是铺满父类view。所以要设为填充:
_playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
- (void)layoutSubviews { 
   [super layoutSubviews];        
   //_playerLayer.frame要重新设置下,不然视频不显示。      
   _playerLayer.frame = self.bounds;      
   //_playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
}

6,按照第一步中的步骤,如下操作实现播放。

#传入网络视频URL
- (void)updatePlayerWithURL:(NSURL *)url {
    //TODO:    1,获取视频URL
    //TODO:    2,根据视频索引取得AVPlayerItem对象
    _playerItem = [AVPlayerItem playerItemWithURL:url];
    //TODO:    3,把AVPlayerItem 提供给 AVPlayer,
    //TODO:    4,AVPlayerLayer 显示视频。
    [self initializeAVPlayer];
    //TODO:    5,AVPlayer 控制视频, 播放, 暂停, 跳转 等等。
    [self addObserverAndNotification]; // 添加观察者,通知
}

你可能感兴趣的:(AVPlayer网络、本地视频播放(音乐也可以直接传入即可播放))