使用平移手势快速前进/后退跳过

时间:2017-01-25 14:05:19

标签: ios avplayer uipangesturerecognizer avplayerlayer

过去两天,我一直在用一个恼人的小故障抨击我的脑袋,并希望有人能说清楚。

基本设置:我有一个带播放器的AVPlayerLayer,视图中的平移手势识别器,我希望用户能够来回滑动手指,视频会相应地搜索。

抓住:我想如果用户抬起手指并再次放置屏幕上的任何地方,快进或快退将在完全恢复它离开的框架并从那里继续前进。

我看过这两个问题: Pan Gesture with AVPlayerPan to seek AVPlayer

我在这里尝试过Apple的建议: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;

}

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

SELECT totC1 = COUNT(CASE WHEN column1 > 0 THEN 1 ELSE NULL END) , totC2 = COUNT(CASE WHEN column2 > 0 THEN 1 ELSE NULL END) , totC3 = COUNT(CASE WHEN column3 > 0 THEN 1 ELSE NULL END) , totC4 = COUNT(CASE WHEN column4 > 0 OR YourCondition = 1 THEN 1 ELSE NULL) FROM YOUR_TABLE 保存UIGestureRecognizerStateBegan后,从CMTime开始,然后执行delta更改平移,然后在AVPlayer上查找原始保存时间?

只是为了让搜索更顺畅,不要暂停视频,将速率设置为0。