AVPlayer 卡顿后缓存好自动播放

  • 效果图:

效果图.png
  • 问题:利用AVPlayer做网络视频播放时,若此时网络出现问题,AVPlayer会自动将其暂停,而若几分钟网络好时它并不会自动播放,你必须手动调用AVPlayer的播放方法play才会继续播放。

  • 解决:所以现在的问题,就是,何时进行AVPlayer的手动让其播放。我们可以AVPlayer提供给我们的属性currentItem的属性值loadedTimeRanges进行监听 视频 缓存大小,当视频缓存大小 > 当前播放时长 ,就 调用AVPlayer的play方法进行播放.

  • 实现代码如下:

    • 解析:点击控制器view进行播放网络视频,当开始播放后,你可以模拟 关掉网络,然后会发现 视频播放到缓存时间后,会自动暂停,当你网络打开,AVPlayer默认会继续缓存时,当缓存值 > 当前播放时间,又开始继续播放了。
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>

@interface ViewController ()

/** 播放器 */
@property (nonatomic, strong) AVPlayer *player;

@property (nonatomic, strong) NSString *status_playType; // 正在播放, 等待播放
@property (nonatomic, strong) UILabel *currentTimeLable; // 显示 当前播放时长

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.currentTimeLable = [[UILabel alloc ] initWithFrame:CGRectMake(0, 240, self.view.frame.size.width, 400)];
    self.currentTimeLable.backgroundColor = [UIColor greenColor];
    [self.view addSubview:self.currentTimeLable];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"status"]) {
        AVPlayerItemStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
        //        NSLog(@"%d", status);
        if (AVPlayerItemStatusReadyToPlay == status) {


        } else {


        }
    }else if ([keyPath isEqualToString:@"loadedTimeRanges"]){
        NSTimeInterval timeInterval = [self availableDuration];// 计算缓冲进度
        NSLog(@"已缓存时长 : %f",timeInterval);

        self.currentTimeLable.text = [NSString stringWithFormat:@"当前播放时长: %f \\n 已缓存: %f", self.getCurrentPlayingTime, timeInterval];

        if (timeInterval > self.getCurrentPlayingTime+5){ // 缓存 大于 播放 当前时长+5

            if ([self.status_playType  isEqual: @"等待播放"]) { // 接着之前 播放时长 继续播放
                [self.player play];
                self.status_playType = @"正在播放";
            }
        }else{
            self.status_playType = @"等待播放"; // 出现问题,等待播放
            NSLog(@"等待播放,网络出现问题");
        }
    }
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self.player play];
    self.status_playType = @"正在播放";

    [[self.player.currentItem valueForKey:@"_playerItem"] addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

    [self.player.currentItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];// 监听loadedTimeRanges属性
}

#pragma mark - 懒加载代码
- (AVPlayer *)player
{
    if (_player == nil) {
        // 1.创建URL
        NSURL *url = [NSURL URLWithString:@"http://v1.mukewang.com/19954d8f-e2c2-4c0a-b8c1-a4c826b5ca8b/L.mp4"];
        // NSURL *url = [[NSBundle mainBundle] URLForResource:@"01-知识回顾.mp4" withExtension:nil];

        // 2.创建AVPlayer对象
        AVPlayerItem *_playerItem = [[AVPlayerItem alloc] initWithURL:url];
        _player = [[AVPlayer alloc] initWithPlayerItem:_playerItem];

        // 3.创建播放layer
        AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:_player];
        layer.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.width * 9 / 16);
        [self.view.layer addSublayer:layer];
    }
    return _player;
}

/**
 *  返回 当前 视频 播放时长
 */
- (double)getCurrentPlayingTime{
    return self.player.currentTime.value/self.player.currentTime.timescale;
}

/**
 *  返回 当前 视频 缓存时长
 */
- (NSTimeInterval)availableDuration{
        NSArray *loadedTimeRanges = [[self.player currentItem] loadedTimeRanges];
        CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域
        float startSeconds = CMTimeGetSeconds(timeRange.start);
        float durationSeconds = CMTimeGetSeconds(timeRange.duration);
        NSTimeInterval result = startSeconds + durationSeconds;// 计算缓冲总进度

     return result;
}

@end
  • HTTPS处理,相关提示错误:
 App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.**
  • 注意:HTTPS处理,在Info.plist文件中加入下面代码
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
posted @ 2017-06-01 14:31  ios4  阅读(3962)  评论(0编辑  收藏  举报