Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pan to seek AVPlayer

Tags:

ios

avplayer

seek

I am trying to pan and seek forwards and backwards in my AVPlayer. It is kind of working but the basic math of determining where the pan is translated to the length of the asset is wrong. Can any one offer assistance?

- (void) handlePanGesture:(UIPanGestureRecognizer*)pan{

    CGPoint translate = [pan translationInView:self.view];
    CGFloat xCoord = translate.x;
    double diff = (xCoord);
    //NSLog(@"%F",diff);

    CMTime duration = self.avPlayer.currentItem.asset.duration;
    float seconds = CMTimeGetSeconds(duration);
    NSLog(@"duration: %.2f", seconds);

    CGFloat gh = 0;

    if (diff>=0) {
        //If the difference is positive
        NSLog(@"%f",diff);
        gh = diff;
    } else {
        //If the difference is negative
        NSLog(@"%f",diff*-1);
        gh = diff*-1;
    }

    float minValue = 0;
    float maxValue = 1024;
    float value = gh;

    double time = seconds * (value - minValue) / (maxValue - minValue);

    [_avPlayer seekToTime:CMTimeMakeWithSeconds(time, 10) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
    //[_avPlayer seekToTime:CMTimeMakeWithSeconds(seconds*(Float64)diff , 1024) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];

}
like image 952
malaki1974 Avatar asked Sep 25 '14 19:09

malaki1974


1 Answers

You are not normalizing the touch location and the corresponding time values. Is there a 1:1 relationship between the two? That's not possible.

Take the minimum and maximum touch location values of the pan gesture and the minimum and maximum values of the asset's duration (obviously, from zero to the length of the video), and then apply the following formula to translate the touch location to the seek time:

// Map
#define map(x, in_min, in_max, out_min, out_max) ((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)

Here's the code I wrote that uses that formula:

- (IBAction)handlePanGesture:(UIPanGestureRecognizer *)sender {
        if (sender.state == UIGestureRecognizerStateChanged){
            CGPoint location = [sender locationInView:self];
            float nlx = ((location.x / ((CGRectGetMidX(self.frame) / (self.frame.size.width / 2.0)))) / (self.frame.size.width / 2.0)) - 1.0;
            //float nly = ((location.y / ((CGRectGetMidY(self.view.frame) / (self.view.frame.size.width / 2.0)))) / (self.view.frame.size.width / 2.0)) - 1.0;
            nlx = nlx * 2.0;
            [self.delegate setRate:nlx];
        }
}

I culled the label that displays the rate, and the Play icon that appears while you're scrubbing, and which changes sizes depending on how fast or slow you are panning the video. Although you didn't ask for that, if you want it, just ask.

Oh, the "times-two" factor is intended to add an acceleration curve to the pan gesture value sent to the delegate's setRate method. You can use any formula for that, even an actual curve, like pow(nlx, 2.0) or whatever...

like image 162
James Bush Avatar answered Nov 15 '22 15:11

James Bush