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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM