AVPlayer的时间轴进度条

San*_*Rao 22 iphone avfoundation uiprogressview ios avplayer

AVPlayer是完全可定制的,遗憾的是有方便的方法AVPlayer来显示时间线进度条.

AVPlayer *player = [AVPlayer playerWithURL:URL];
AVPlayerLayer *playerLayer = [[AVPlayerLayer playerLayerWithPlayer:avPlayer] retain];[self.view.layer addSubLayer:playerLayer];
Run Code Online (Sandbox Code Playgroud)

我有一个进度条,指示视频的播放方式,以及剩余的数量MPMoviePlayer.

那么如何获取视频的时间轴AVPlayer以及如何更新进度条

建议我.

iOS*_*wan 25

请使用以下代码,该代码来自苹果示例代码"AVPlayerDemo".

    double interval = .1f;  

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

    /* Update the scrubber during normal playback. */
    timeObserver = [[player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(interval, NSEC_PER_SEC) 
                                                          queue:NULL 
                                                     usingBlock:
                                                      ^(CMTime time) 
                                                      {
                                                          [self syncScrubber];
                                                      }] retain];


- (CMTime)playerItemDuration
{
    AVPlayerItem *thePlayerItem = [player currentItem];
    if (thePlayerItem.status == AVPlayerItemStatusReadyToPlay)
    {        

        return([playerItem duration]);
    }

    return(kCMTimeInvalid);
}
Run Code Online (Sandbox Code Playgroud)

并在syncScrubber方法中更新UISlider或UIProgressBar值.

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

    double duration = CMTimeGetSeconds(playerDuration);
    if (isfinite(duration) && (duration > 0))
    {
        float minValue = [ yourSlider minimumValue];
        float maxValue = [ yourSlider maximumValue];
        double time = CMTimeGetSeconds([player currentTime]);
        [yourSlider setValue:(maxValue - minValue) * time / duration + minValue];
    }
} 
Run Code Online (Sandbox Code Playgroud)


Rap*_*ael 22

感谢iOSPawan的代码!我将代码简化为必要的行.理解这个概念可能更清楚.基本上我已经像这样实现它,它工作正常.

在开始播放视频之前:

__weak NSObject *weakSelf = self;    
[_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1.0 / 60.0, NSEC_PER_SEC)
                                      queue:NULL
                                 usingBlock:^(CMTime time){
                                                [weakSelf updateProgressBar];
                                             }];

[_player play];
Run Code Online (Sandbox Code Playgroud)

然后你需要一个方法来更新你的进度条:

- (void)updateProgressBar
{
    double duration = CMTimeGetSeconds(_playerItem.duration);
    double time = CMTimeGetSeconds(_player.currentTime);
    _progressView.progress = (CGFloat) (time / duration);
}
Run Code Online (Sandbox Code Playgroud)


aml*_*szk 9

    let progressView = UIProgressView(progressViewStyle: UIProgressViewStyle.Bar)
    self.view.addSubview(progressView)
    progressView.constrainHeight("\(1.0/UIScreen.mainScreen().scale)")
    progressView.alignLeading("", trailing: "", toView: self.view)
    progressView.alignBottomEdgeWithView(self.view, predicate: "")
    player.addPeriodicTimeObserverForInterval(CMTimeMakeWithSeconds(1/30.0, Int32(NSEC_PER_SEC)), queue: nil) { time in
        let duration = CMTimeGetSeconds(playerItem.duration)
        progressView.progress = Float((CMTimeGetSeconds(time) / duration))
    }
Run Code Online (Sandbox Code Playgroud)


小智 7

我知道这是一个老问题,但有人可能会发现它有用。这只是 Swift 版本:

 //set the timer, which will update your progress bar. You can use whatever time interval you want

 private func setupProgressTimer() {
    timer = Timer.scheduledTimer(withTimeInterval: 0.02, repeats: true, block: { [weak self] (completion) in
        guard let self = self else { return }
        self.updateProgress()
    })
}

//update progression of video, based on it's own data

private func updateProgress() {
    guard let duration = player?.currentItem?.duration.seconds,
        let currentMoment = player?.currentItem?.currentTime().seconds else { return }

    progressBar.progress = Float(currentMoment / duration)
}
Run Code Online (Sandbox Code Playgroud)


Zai*_*han 5

迅速回答以获得进展:

private func addPeriodicTimeObserver() {
        // Invoke callback every half second
        let interval = CMTime(seconds: 0.5,
                              preferredTimescale: CMTimeScale(NSEC_PER_SEC))
        // Queue on which to invoke the callback
        let mainQueue = DispatchQueue.main
        // Add time observer
        self.playerController?.player?.addPeriodicTimeObserver(forInterval: interval, queue: mainQueue) { [weak self] time in
            let currentSeconds = CMTimeGetSeconds(time)
            guard let duration = self?.playerController?.player?.currentItem?.duration else { return }
            let totalSeconds = CMTimeGetSeconds(duration)
            let progress: Float = Float(currentSeconds/totalSeconds)
            print(progress)
        }
    }
Run Code Online (Sandbox Code Playgroud)

参考号