2017-01-25 3 views
0

私は過去2日間迷惑なグリッチをしていましたが、誰かが光を当てることを望んでいました。AVPlayerパンのジェスチャーで早送り/逆戻りする

基本設定:私はプレーヤーとAVPlayerLayer、ビューのパンジェスチャー認識を持っていると私は、ユーザーが前後に自分の指をスワイプすると、ビデオはそれに応じて求めてしまうことができるようにしたいです。

キャッチ:ユーザーは再び自分の指や場所、それを持ち上げる場合、私はそれがオフに左まったく同じフレームで再開してから進行して継続する前後に、高速のために画面上の任意の場所を、希望そこ。 Pan Gesture with AVPlayerと私はここに、Appleの提案を試してみた Pan 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; 
    } 
} 

normalizeメソッドはこれです:

- (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

OK、ちょうど明確にするために3.0で、前後にパン、スクラブを行い、次に.endに戻って3.0に戻りますか?しかし、スクラブ中のビデオはスムーズにパンに基づいて前後に移動しますか?もしそうなら、この問題は何か? – SeanLintern88

答えて

0

オンUIGestureRecognizerStateBegan保存CMTimeAVPlayerデルタ変更パンを実行してから、UIGestureRecognizerStateEndedに戻って元の保存時間に戻してください。

だけでスムーズなシークのためのノートは、ビデオを一時停止していないが、0

+0

あなたが本当に正しいです、私はあなたのコメントを読んだ後、私のサンプルコードを見て、私はUIGestureRecognizerStateBanganではなく、UIGestureRecognizerStateChangedでは、最初のシーク時間を設定していたので、ユーザーが始めたときに、スワイプ。 –

+0

また、一時停止しないで一時停止するレートを使用すると、より多くの流動性を求めることができます。 – SeanLintern88

関連する問題