2017-03-01 46 views
3

在我的應用程序AI加載下一個到來的視頻加載了所有的視頻網址到AVPlayer,它在這裏有一個和下一個按鈕,我已經安裝播放器iOS的Objective C中如何同時播放當前視頻無延遲

-(void)setUpMyNewPlayer 
    { 
      [self addTimer]; 
     NSURL *url=[NSURL URLWithString:_videosArray[0]]; 
     _currentIndex =0; 
     videoPlayer = [[AVPlayer alloc]init]; //WithPlayerItem:_avPlayerItem]; 
     videoPlayer.automaticallyWaitsToMinimizeStalling = NO; 
     AVAsset *asset = [AVAsset assetWithURL:url]; 
     [asset loadValuesAsynchronouslyForKeys:@[@"playable"] completionHandler:^{ 

      AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset]; 
      videoPlayer = [AVPlayer playerWithPlayerItem:item]; 
      AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:videoPlayer]; 
      playerLayer.videoGravity = AVLayerVideoGravityResize; 
      playerLayer.frame = CGRectMake(0, 0, self.playView.frame.size.width, self.playView.frame.size.height); 
      [self.playView.layer addSublayer:playerLayer]; 
      [videoPlayer play]; 
      CMTime interval = CMTimeMakeWithSeconds(0.5, NSEC_PER_SEC); 
      dispatch_queue_t mainQueue = dispatch_get_main_queue(); 


      __weak typeof(self) weakSelf = self; 
      [videoPlayer addPeriodicTimeObserverForInterval:interval 
                 queue:mainQueue 
               usingBlock:^(CMTime time) { 
                // Use weak reference to self 
                if (_currentIndex==_contentImages.count-1) { 
                 weakSelf.nextButton.hidden=YES; 
                 weakSelf.previousButton.hidden=NO; 
                } 
                else if (_currentIndex==0) 
                { 
                 weakSelf.previousButton.hidden=YES; 
                 if (_contentImages.count>1) { 
                  weakSelf.nextButton.hidden=NO; 
                 } 
                 else 
                 { 
                  weakSelf.nextButton.hidden=YES; 
                 } 

                } 
                else if (_currentIndex>0 && _currentIndex!=_contentImages.count-1) 
                { 
                 // NSLog(@"Showing Both"); 
                 weakSelf.nextButton.hidden=NO; 
                 weakSelf.previousButton.hidden=NO; 
                } 

               }]; 
      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying1:) name:AVPlayerItemDidPlayToEndTimeNotification object:item]; 
     }]; 

    } 

-(void)itemDidFinishPlaying1:(NSNotification *) notification { 
    // 
    // Will be called when AVPlayer finishes playing playerItem 
    if (_currentIndex == _videosArray.count-1) { 

    } 
    else{ 

     _currentIndex = _currentIndex+1; 
     NSURL *url=[NSURL URLWithString:_videosArray[_currentIndex]]; 
     AVAsset *asset = [AVAsset assetWithURL:url]; 
     AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset]; 
     [videoPlayer replaceCurrentItemWithPlayerItem:item]; 
     [self changePage:UIPageViewControllerNavigationDirectionForward]; 
     [self addTimer]; 
    } 

} 


-(void)addTimer 
{ 
    myTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1 target: self 
              selector: @selector(callAfterOneSecond1:) userInfo: nil repeats: YES]; 
} 

-(void) callAfterOneSecond1:(NSTimer*)t 
{ 
    [[AppDelegate shared] showLoading]; 
    if (videoPlayer.rate !=0 && videoPlayer.error == nil && videoPlayer.status == AVPlayerStatusReadyToPlay) { 
     [[AppDelegate shared]removeLoading]; 
     [myTimer invalidate]; 
     myTimer=nil; 
    } 

} 

編譯標誌 - PreviousAction

- (IBAction)previousButtonAction:(id)sender { 

    if (_currentIndex == 0) { 

    } 
    else{ 
     _currentIndex = _currentIndex-1; 
     NSURL *url=[NSURL URLWithString:_videosArray[_currentIndex]]; 
     AVAsset *asset = [AVAsset assetWithURL:url]; 
     AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset]; 
     [videoPlayer replaceCurrentItemWithPlayerItem:item]; 
     [videoPlayer play]; 
     [self changePage:UIPageViewControllerNavigationDirectionReverse]; 
     [self addTimer]; 
    } 
    } 

編譯mark-個動作

- (IBAction)nextButtonAction:(id)sender { 

    if (_currentIndex == _videosArray.count-1) { 

    } 
    else{ 
     _currentIndex = _currentIndex+1; 
     NSURL *url=[NSURL URLWithString:_videosArray[_currentIndex]]; 
     AVAsset *asset = [AVAsset assetWithURL:url]; 
     AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset]; 
     [videoPlayer replaceCurrentItemWithPlayerItem:item]; 
     [videoPlayer play]; 
     [self changePage:UIPageViewControllerNavigationDirectionForward]; 
      [self addTimer]; 
    } 
} 

在這裏,玩家正在玩但延遲很小。 。如何在播放當前視頻的同時加載下一個視頻。

回答

1

我有點生疏,整個AVFoundation的iOS文檔如果你想做一些稍微複雜的事情,可悲的是不足。它已經有一段時間,因爲我做了這一點,但這樣的事情應該工作(我假設你有一個NSArray*pAssets包含所有的影片爲AVAsset*

// Define the composition. 
AVMutableComposition*  pComposition  = [AVMutableComposition composition]; 

// Define the tracks in the composition. 
AVMutableCompositionTrack* pCompositionVideoTrack = [pComposition addMutableTrackWithMediaType: AVMediaTypeVideo preferredTrackID: 1]; 
AVMutableCompositionTrack* pCompositionAudioTrack = [pComposition addMutableTrackWithMediaType: AVMediaTypeAudio preferredTrackID: 2]; 

CMTime time = kCMTimeZero; 
for (AVAsset* pAssetsAsset in pAssets) 
{ 
    // Grab first video and audio tracks 
    AVAssetTrack* pAssetsAssetVideoTrack = [pAssetsAsset tracksWithMediaType: AVMediaTypeVideo].firstObject;  
    AVAssetTrack* pAssetsAssetAudioTrack = [pAssetsAsset tracksWithMediaType: AVMediaTypeAudio].firstObject; 

    // Get time range of entire video. 
    CMTimeRange  timeRange = CMTimeRangeMake(kCMTimeZero, timepAssetsAsset.duration); 

    // Insert the entire video and audio into their respective tracks at "time". 
    NSError* pVideoError  = nil; 
    NSError* pAudioError  = nil; 
    [pCompositionVideoTrack insertTimeRange: timeRange ofTrack: pAssetsAssetVideoTrack atTime: time error: &pVideoError];  
    [pCompositionAudioTrack insertTimeRange: timeRange ofTrack: pAssetsAssetAudioTrack atTime: time error: &pAudioError]; 

    // Move time along appropriately. 
    time = CMTimeAdd(time, pAssetsAsset.duration); 
} 

如果再經過AVMutableCompositionAVAsset所以衍生您可以將其作爲正常使用,並將其放入AVPlayer(通過AVPlayerItem)。

現在你可以尋求視頻中的任何一點。存儲每個視頻的開始/結束點,您可以輕鬆找到它。

編輯:它的超簡單使用AVPlayer。首先你需要創建一個AVPlayerItem ..然後你需要播放它。

AVPlayerItem* pPlayerItem = [AVPlayerItem playerItemWithAsset: pComposition]; 
AVPlayer* pPlayer  = [AVPlayer playerWithPlayerItem: pPlayerItem]; 

現在您需要將它附加到視圖的圖層。因此,從您的視圖控制器裏面做這樣的事情:

AVPlayerLayer* pLayer  = [AVPlayerLayer playerLayerWithPlayer: pPlayer]; 
[self.view.layer addSublayer: pLayer]; 
+0

嗨戈茲貝達我剛接觸AVPlayer請你提供我在這樣的一個例子。 –

+0

嗨Goz你已經初始化pAVComposition而不是在上面的代碼中使用。 。並使用pComposition初始化了一個玩家項目,我已經添加了這個項目,請你詳細幫助我。 –

+0

它提供錯誤終止應用程序由於未捕獲的異常'NSInvalidArgumentException',原因:' - [AVPlayerItem tracksWithMediaType:]:無法識別的選擇發送到實例0x60000001a2e0' –

0

使用AVQueuePlayer,而不是簡單AVPlayer。在當前視頻結束時,它會預載下一個視頻。

瞭解如何在這裏使用AVQueuePlayerhttps://stackoverflow.com/a/22785665/1271424

+0

好吧,哥哥,我會盡力讓你知道。 。 。 –

+0

AVQueuePlayer不會緩衝視頻項目。 –

+0

您也無法使用AVQueuePlayer正確尋找後退和前向... – Goz

相關問題