視訊播放學習

weixin_33860722發表於2018-05-17

一、 AVPlayer

  • 1、基本使用
    AVPlayer是一個可以播放任何格式的全功能影音播放器,可定製度高,功能強大,是做視訊開發的首選。但不支援流媒體。
    支援視訊格式: WMV,AVI,MKV,RMVB,RM,XVID,MP4,3GP,MPG等。
    支援音訊格式:MP3,WMA,RM,ACC,OGG,APE,FLAC,FLV等。
   //1、獲取url
    NSURL *url=[[NSBundle mainBundle]URLForResource:@"EP00.mp4" withExtension:nil];
    
    //2、建立AVPlayerItem (AVPlayerItem:管理資源物件,提供播放資料來源)
    AVPlayerItem *playItem=[AVPlayerItem playerItemWithURL:url];
    
    //3、建立 AVPlayer(控制播放器的播放,暫停,播放速度)
    AVPlayer *player=[AVPlayer playerWithPlayerItem:playItem];
    
    //4、新增AVPlayerLayer(AVPlayerLayer:負責顯示視訊,如果沒有新增該類,只有聲音沒有畫面)
    AVPlayerLayer *playlayer = [AVPlayerLayer playerLayerWithPlayer:player];
    [self.view.layer addSublayer:playlayer];
    playlayer.frame=CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.width * 9 / 16);
    
    //5、開始播放
    [player play];
    //5、開始播放
    [player play];

1、AVPlayer一次只能播放一個媒體資源。播放器可以使用其- (void)replaceCurrentItemWithPlayerItem:(nullable AVPlayerItem *)item方法來切換視訊
2、播放器的播放狀態判斷可以通過播放器的播放速度 rate 來獲得,如果 rate 為0說明是停止狀態,為1時則是正常播放狀態。想要獲取視訊播放情況、緩衝情況等的實時變化,可以通過 KVO 監控 AVPlayerItem 的 status、loadedTimeRanges 等屬性來獲得。

//使用KVO監測playItem.status,可以獲取播放狀態的變化
[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
     if ([keyPath isEqualToString:@"status"]) {
        switch (_playerItem.status) {
       case AVPlayerItemStatusReadyToPlay://準備播放
     //推薦將視訊播放放在這裡
       [self play];
        break;
        case AVPlayerItemStatusUnknown://未知資源
        NSLog(@"AVPlayerItemStatusUnknown");
        break;

   case AVPlayerItemStatusFailed://載入失敗
         NSLog(@"AVPlayerItemStatusFailed")
        break;
       default:
       break;
   }

}
  • 2、自定義簡單的視訊播放器
    2.1、@interface AVPlayerItem
    @property (nonatomic, readonly) CMTime duration ;//視訊的總時長

    @interface AVPlayer

  • (CMTime)currentTime;//當前已播放的時間

  • (void)seekToTime:(CMTime)time拖動滑塊播放跳躍播放,跳到指定的播放時間;//時間跳轉都不是很精確

  • (void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter//精準定位

2.2 、播放進度的控制


#pragma mark - 開始拖拽進度
- (void)valuebeginchangewithslider:(UISlider *)slider{
     [self removetimer];
}

#pragma mark - 正在拖拽中
- (void)valuechangewithslider:(UISlider *)slider{
    NSTimeInterval duration = CMTimeGetSeconds(self.player.currentItem.duration);
    NSTimeInterval currenttime = slider.value*duration;
    self.toolView.timeLable.text=[self stringWithCurrentTime:currenttime duration:duration];
   
}

#pragma mark- 結束拖拽
- (void)valueendchangewithslider:(UISlider *)slider{
    //新增定時器
    [self addtimer];
    
    //獲取當前已播放時長
    NSTimeInterval currentTime = CMTimeGetSeconds(self.player.currentItem.duration) * slider.value;
    
    //跳躍到當前拖拽到的時間點
     [self.player seekToTime:CMTimeMakeWithSeconds(currentTime, NSEC_PER_SEC) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
    
    //繼續開始播放視訊
    [self.player play];
 
    
}

#pragma mark - 新增定時器
- (void)addtimer{
    NSTimer *progresstimer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateUI) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:progresstimer forMode:NSRunLoopCommonModes];
    self.timer=progresstimer;
}

#pragma mark - 移除定時器
- (void)removetimer{
    [self.timer invalidate];
    self.timer=nil;
    
}


#pragma mark - 時長格式處理
- (NSString *)stringWithCurrentTime:(NSTimeInterval)currentTime duration:(NSTimeInterval)duration
{
    NSInteger dMin = duration / 60;
    NSInteger dSec = (NSInteger)duration % 60;
    
    NSInteger cMin = currentTime / 60;
    NSInteger cSec = (NSInteger)currentTime % 60;
    
    NSString *durationString = [NSString stringWithFormat:@"%02ld:%02ld", dMin, dSec];
    NSString *currentString = [NSString stringWithFormat:@"%02ld:%02ld", cMin, cSec];
    
    return [NSString stringWithFormat:@"%@/%@", currentString, durationString];
}

#pragma mark - 更新當前的時間顯示和進度位置
- (void)updateUI{
    NSTimeInterval duration = CMTimeGetSeconds(self.player.currentItem.duration);
    NSTimeInterval currentTime = CMTimeGetSeconds(self.player.currentTime);
    NSString *timestring=[self stringWithCurrentTime:currentTime duration:duration];
    self.toolView.timeLable.text=timestring;
    self.toolView.slider.value=currentTime/duration;
    
}

2.3、視訊全屏播放
思路:新建一個全屏控制器讓這個控制器只支援向左的水平方向,然後點選全屏按鈕.將播放畫面新增到全屏view上

@implementation FullViewController

-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    
    return  UIInterfaceOrientationMaskLandscapeLeft;//只支援向左旋轉的方向
}

    if (isfull) {
    [self presentViewController:self.fullVc animated:YES completion:^{
        
            //新增到全屏控制器上
            [self.fullVc.view addSubview:self.playView];
            [self.playView mas_remakeConstraints:^(MASConstraintMaker *make) {
                make.left.right.top.equalTo(self.fullVc.view);
            }];
            
    }];
    }else{
        [self.fullVc dismissViewControllerAnimated:YES completion:^{
            //新增到控制器上
            [self.view addSubview:self.playView];
            //恢復的frame
            [playview mas_updateConstraints:^(MASConstraintMaker *make) {
                make.left.right.top.equalTo(self.view);
                make.bottom.equalTo(self.view);
            }];
        }];
    }
    

相關文章