2017-01-25 33 views
0

過去兩天我一直在用煩人的毛刺抨擊我的頭,並希望有人能夠擺脫一些光線。AVPlayer快速向前/向後跳過平移手勢

基本設置:我有一個球員,在視圖中平移手勢識別的AVPlayerLayer,我希望用戶能夠將他們的手指輕掃來回視頻將相應地尋求。

美中不足的是:如果用戶再次提起他們的手指,並把它,在屏幕任意位置的快進或後退的,我想繼續在離開的地方的確切相同的幀,並繼續從進展那裏。

我見過這兩個問題: Pan Gesture with AVPlayerPan to seek AVPlayer

我在這裏試過蘋果的建議:https://developer.apple.com/library/content/qa/qa1820/_index.html 爲好,但問題是,每當我開始一個新的移動手勢,玩家跳躍幾幀,然後恢復。

我最近的做法是設置當前時間,一旦查找完成塊完成,然後嘗試追加新的查找時間。

這裏是我的設置:

self.item = [AVPlayerItem playerItemWithURL:resource]; 
self.player = [AVPlayer playerWithPlayerItem:self.item]; 
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; 

[self.view.layer addSublayer:self.playerLayer]; 
self.playerLayer.frame = self.view.bounds; 

UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)]; 

[self.view addGestureRecognizer:recognizer]; 

我的手勢識別處理:

- (void)swipe:(UIPanGestureRecognizer *)paramRecognizer 
{ 
    switch(paramRecognizer.state) { 
     // case UIGestureRecognizerStateBegan: 
     case UIGestureRecognizerStateChanged: 
     { 
      [self.player pause]; 

      CGPoint translation = [paramRecognizer translationInView:self.view]; 

      float horizontalTranslation = translation.x; 

      float durationInSeconds = CMTimeGetSeconds(self.player.currentItem.asset.duration); 

      //I'd like to be able to swipe across the whole view. 
      float translationLimit = self.view.bounds.size.width; 
      float minTranslation = 0; 
      float maxTranslation = translationLimit; 

      if (horizontalTranslation > maxTranslation) { 
       horizontalTranslation = maxTranslation; 
      } 

      if (horizontalTranslation < minTranslation) { 
       horizontalTranslation = minTranslation; 
      } 

     float timeToSeekTo = [self normalize:horizontalTranslation 
           andMinDelta:minTranslation 
           andMaxDelta:maxTranslation 
           andMinDuration:0 
           andMaxDuration:durationInSeconds]; 

      if(CMTIME_IS_VALID(self.currentTime)){ 
       float seconds = self.currentTime.value/self.currentTime.timescale; 

       [self.player seekToTime:CMTimeMakeWithSeconds(seconds+timeToSeekTo, self.player.currentTime.timescale) 
         toleranceBefore:kCMTimeZero 
         toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) 
       { 
        if(finished) 
        self.currentTime = self.player.currentItem.currentTime; 
       }]; 
      } 
      else 
      { 
       [self.player seekToTime:CMTimeMakeWithSeconds(timeToSeekTo, 
                   self.player.currentTime.timescale) toleranceBefore:kCMTimeZero 
         toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) { 
          if(finished) 
        self.currentTime = self.player.currentItem.currentTime; 
       }]; 
      } 

     } 
      break; 
    } 
} 

的標準化的方法是這樣的:

- (float) normalize:(float)delta 
    andMinDelta:(float)minDelta 
    andMaxDelta:(float)maxDelta 
andMinDuration:(float)minDuration 
andMaxDuration:(float)maxDuration{ 

float result = ((delta - minDelta) * (maxDuration - minDuration)/(maxDelta - minDelta) + minDuration); 
return result; 

}

任何幫助極端非常感謝!

+0

稍顯混亂的措辭是,如果你開始在3.00秒paning和且說鍋2像素提升,它應該在玩你說再次5.00或3.00? – SeanLintern88

+0

@ SeanLintern88它應該再次發揮3.0,對不起清除它 –

+0

好吧,只是爲了澄清,你會在3.0,平移和擦洗前/後,然後回到3.0?但是在視頻清理過程中,視頻會根據平移來平滑地前後移動?如果是這個問題到底是什麼? – SeanLintern88

回答

0

UIGestureRecognizerStateBegan保存CMTime通過從AVPlayer然後做你的德爾塔變化平移,然後在UIGestureRecognizerStateEnded只是尋求回到原來的保存時間?

只是爲了平滑尋求注意不要暫停視頻,設置速度爲0

+0

你確實是對的,我在閱讀你的評論後發現問題,如果你看看我的示例代碼,我在UIGestureRecognizerStateChanged下設置了初始查找時間,而不是UIGestureRecognizerStateBegan,因此爲什麼我在用戶開始時看到一個初始的混亂滑動。 –

+0

也使用率暫停,這使得尋求更多的流動性。 – SeanLintern88