AVPlayer的使用,带缓冲

Posted mfmdaoyou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AVPlayer的使用,带缓冲相关的知识,希望对你有一定的参考价值。


#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()
{
    AVPlayer *player;
    AVPlayerItem *playerItem;
    
    UIProgressView * progressView;
    UISlider *_slider;
    
    //推断slider是否按下,
    BOOL isOpen;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self createUI];
    //进行初始化创建
    NSURL *url = [NSURL fileURLWithPath:@"/Users/qianfeng01/Downloads/千锋Swift视频教程-1.Swift语言介绍.mp4"];
    playerItem  = [[AVPlayerItem alloc]initWithURL:url];
    //创建player
    player = [[AVPlayer alloc]initWithPlayerItem:playerItem];
    //生成layer层
    AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:player];
    //设置坐标
    layer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    
    //把layer层假如到self.view.layer中
    [self.view.layer addSublayer:layer];
    //进行播放
    [player play];
    
    /**以上是主要的播放界面。可是没有前进后退**/
    //观察是否播放,KVO进行观察,观察playerItem.status
    [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    
    //观察缓存如今的进度,KVO进行观察,观察loadedTimeRanges
    [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
}

//观察是否播放
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if ([keyPath isEqualToString:@"status"]) {
        if (playerItem.status == AVPlayerStatusReadyToPlay) {
            NSLog(@"開始播放");
            //须要開始获取数据,包含播放的总时长。播放的缓存,播放的当时时间
            [self loadData];
        }else{
            NSLog(@"播放失败");
        }
    }else{
        //kvo触发的另外一个属性
        NSArray *array = [playerItem loadedTimeRanges];
        //获取范围i
        CMTimeRange range = [array.firstObject CMTimeRangeValue];
        //从哪儿開始的
        CGFloat start = CMTimeGetSeconds(range.start);
        //缓存了多少
        CGFloat duration = CMTimeGetSeconds(range.duration);
        //一共缓存了多少
        CGFloat allCache = start+duration;
        NSLog(@"缓存了多少数据:%f",allCache);
        
        //设置缓存的百分比
        CMTime allTime = [playerItem duration];
        //转换
        CGFloat time = CMTimeGetSeconds(allTime);
        CGFloat y = allCache/time;
        NSLog(@"缓存百分比:--------%f",y);
        progressView.progress = y;
    }
}


#pragma mark -- 获取播放数据
- (void)loadData{
    
    __weak AVPlayerItem *xx = playerItem;
    __weak UISlider *cc = _slider;
    //第一个參数是每隔多长时间调用一次。在这里设置的是每隔1秒调用一次
    [player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) {
        //当前播放时间
        CGFloat current = xx.currentTime.value/xx.currentTime.timescale;
        
        //获取总时长
        CMTime time1 = xx.duration;
        float x = CMTimeGetSeconds(time1);
        NSLog(@"当前播放的秒数------- %f --------%f",current,x);
        
        //设置滑动条进度
        float v = current/x;
        
        //推断slider是否按下,按下去就先别赋值
        if (!isOpen) {
            cc.value = v;
        }
        
    }];

}

#pragma mark --- 创建UI
- (void)createUI{
    progressView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];
    progressView.frame = CGRectMake(0, 460, self.view.frame.size.width, 20);
    
    [self.view addSubview:progressView];
    
    _slider = [[UISlider alloc]initWithFrame:CGRectMake(0, 480, self.view.frame.size.width, 20)];
    [self.view addSubview:_slider];
    
    
    //加入点击事件
    [_slider addTarget:self action:@selector(sliderClick:) forControlEvents:UIControlEventTouchUpInside];
    //抬起来的事件
    [_slider addTarget:self action:@selector(sliderClickUp:) forControlEvents:UIControlEventTouchUpInside];
}

    //加入点击事件
- (void)sliderClick:(UISlider *)slider{
    NSLog(@"加入点击事件");
    isOpen = YES;
}

    //抬起来的事件
- (void)sliderClickUp:(UISlider *)slider{
    NSLog(@"抬起来的事件");
    isOpen = NO;
    
    //从这里開始播放
    CGFloat g = slider.value;
    //获取总时长
    CMTime time1 = playerItem.duration;
    float x = CMTimeGetSeconds(time1);
    //进行播放
    [player seekToTime:CMTimeMake(x * g,1)];
    //播放
    [player play];
    
}


@end

以上是关于AVPlayer的使用,带缓冲的主要内容,如果未能解决你的问题,请参考以下文章

具有缓冲进度的 UISlider - AVPlayer

AVPlayer 缓冲后未恢复

AVPlayer 项目缓冲区为空

处于暂停状态时如何强制 AVPlayer 暂停缓冲?

如何仅使用 AVAudioPlayer 或 AVPlayer 播放 PCM 数据/缓冲区?

AVPlayer 在将 PlayerItem 加载到播放器之前开始缓冲它