AVPlayer中的Scrubber(UISlider)?

时间:2013-11-18 15:03:08

标签: ios avfoundation avplayer

当你通过AVPlayer播放远程视频并开始倒带时,擦洗器就会出现问题。

我正在根据此Apple example.

做一名玩家

如何顺利实施?

我项目的代码如下 - https://github.com/nullproduction/Player

- (void)initScrubberTimer
{
    double interval = .1f;

    CMTime playerDuration = [self playerItemDuration];
    if (CMTIME_IS_INVALID(playerDuration))
    {
        return;
    }
    double duration = CMTimeGetSeconds(playerDuration);
    if (isfinite(duration))
    {
        CGFloat width = CGRectGetWidth([scrubberSlider bounds]);
        interval = 0.5f * duration / width;
    }

    __weak id weakSelf = self;
    CMTime intervalSeconds = CMTimeMakeWithSeconds(interval, NSEC_PER_SEC);
    mTimeObserver = [self.player addPeriodicTimeObserverForInterval:intervalSeconds
                                                              queue:dispatch_get_main_queue()
                                                         usingBlock:^(CMTime time) {
                                                             [weakSelf syncScrubber];
                                                         }];

}


- (void)syncScrubber
{
    CMTime playerDuration = [self playerItemDuration];
    if (CMTIME_IS_INVALID(playerDuration))
    {
        scrubberSlider.minimumValue = 0.0;
        return;
    }

    double duration = CMTimeGetSeconds(playerDuration);
    if (isfinite(duration))
    {
        float minValue = [scrubberSlider minimumValue];
        float maxValue = [scrubberSlider maximumValue];
        double time = CMTimeGetSeconds([self.player currentTime]);

        [scrubberSlider setValue:(maxValue - minValue) * time / duration + minValue];
    }
}

- (IBAction)beginScrubbing:(id)sender
{
    mRestoreAfterScrubbingRate = [self.player rate];
    [self.player setRate:0.f];

    [self removePlayerTimeObserver];
}


- (IBAction)scrub:(id)sender
{
    if ([sender isKindOfClass:[UISlider class]])
    {
        UISlider* slider = sender;

        CMTime playerDuration = [self playerItemDuration];
        if (CMTIME_IS_INVALID(playerDuration))
        {
            return;
        }

        double duration = CMTimeGetSeconds(playerDuration);
        if (isfinite(duration))
        {
            float minValue = [slider minimumValue];
            float maxValue = [slider maximumValue];
            float value = [slider value];

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

            [self.player seekToTime:CMTimeMakeWithSeconds(time, NSEC_PER_SEC)];
        }
    }
}

- (IBAction)endScrubbing:(id)sender
{
    if (!mTimeObserver)
    {
        CMTime playerDuration = [self playerItemDuration];
        if (CMTIME_IS_INVALID(playerDuration))
        {
            return;
        }

        double duration = CMTimeGetSeconds(playerDuration);
        if (isfinite(duration))
        {
            CGFloat width = CGRectGetWidth([scrubberSlider bounds]);
            double tolerance = 0.5f * duration / width;

            __weak id weakSelf = self;
            CMTime intervalSeconds = CMTimeMakeWithSeconds(tolerance, NSEC_PER_SEC);
            mTimeObserver = [self.player addPeriodicTimeObserverForInterval:intervalSeconds
                                                                      queue:dispatch_get_main_queue()
                                                                 usingBlock: ^(CMTime time) {
                                                                     [weakSelf syncScrubber];
                                                                 }];
        }
    }

    if (mRestoreAfterScrubbingRate)
    {
        [self.player setRate:mRestoreAfterScrubbingRate];
        mRestoreAfterScrubbingRate = 0.f;
    }
}

1 个答案:

答案 0 :(得分:8)

我想问题是,当您使用搜索栏时,您的滑块仍在从视频更新。以某种方式实现它,在擦洗过程中暂停播放器,你不再有这个bug。查看我的解决方案:

更新播放器的功能:

- (IBAction)seekbarAction:(UISlider *)sender {
    CMTime videoLength = playerItem1.duration;  //gets the video duration
    float videoLengthInSeconds = videoLength.value/videoLength.timescale; //transfers the CMTime duration into seconds

    [player1 seekToTime:CMTimeMakeWithSeconds(videoLengthInSeconds*sender.value, 1)];
}

另一个搜索栏动作与"触及"为了暂停视频:

- (IBAction)pauseSeek:(id)sender {
    [player1 pause];
}

另一个搜索栏动作与"触摸"在释放洗涤器时恢复视频。希望这会有所帮助。