Why does my time UILabels skip 2 seconds when it r

2019-07-24 00:15发布

I'm having a weird issue using MPMoviePlayerController. I have a currentTimeLabel representing the current playback time and an endTimeLabel representing the remaining playback time. The function to update the labels is fired off every 1 second using an NSTimer.

This coincides with a UISlider that increments every second as the video plays. However, the problem is, as the video is playing, and I tap the Pause button, when I tap the play button again, my currentTimeLabel and endTimeLabel jumps by 2 seconds from wherever it last stopped.

Here's the provided code:

override func viewDidLoad()
{
    super.viewDidLoad()

    print("viewDidLoad")
    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: "moviePlayerPlaybackStateDidChangeNotification:",
        name: MPMoviePlayerPlaybackStateDidChangeNotification,
        object: nil)

    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: "moviePlayerLoadStateDidChangeNotification:",
        name: MPMoviePlayerLoadStateDidChangeNotification,
        object: nil)

    setUpVideoPlayer()

    isPlaybackSliderTouched = false

    isPauseButtonTouched = false
}

override func viewDidAppear(animated: Bool)
{
    super.viewDidAppear(true)

    print("viewDidAppear")

    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updatePlaybackSlider", userInfo: nil, repeats: true)

    playPauseButton.addTarget(self, action: "onClick:", forControlEvents: .TouchUpInside)
}

func convertSecondsToHHMMSS(seconds: Double) -> String
{
    let time: Int = Int( floor(seconds) )

    print("time = \(time)")

    // Convert to hours
    let hh: Int = time / 3600

    // Convert to minutes
    let mm: Int = (time / 60) % 60

    // Convert to seconds
    let ss: Int = time % 60

    print("seconds = \(ss)")

    if hh > 0
    {
        return String(format: "%02d:%02d:%02d", hh, mm, ss)
    }
    else
    {
        return String(format: "%02d:%02d", mm, ss )
    }
}

func updatePlaybackSlider()
{
    if isPlaybackSliderTouched == false
    {
        print("PLAYBACKSLIDER IS NOT TOUCHED!")

        print("youtubeVideoPlayer.moviePlayer.currentPlaybackTime = \(youtubeVideoPlayer.moviePlayer.currentPlaybackTime)")
        print("youtubeVideoPlayer.moviePlayer.duration = \(youtubeVideoPlayer.moviePlayer.duration)")

        let sliderValue: Float = Float(youtubeVideoPlayer.moviePlayer.currentPlaybackTime / youtubeVideoPlayer.moviePlayer.duration)

        print("sliderValue = \(sliderValue)")
        if !sliderValue.isNaN
        {
            self.playbackSlider.setValue(sliderValue, animated: true)

            self.currentTimeLabel.text = self.convertSecondsToHHMMSS(self.youtubeVideoPlayer.moviePlayer.currentPlaybackTime)
            self.endTimeLabel.text = "-" + self.convertSecondsToHHMMSS(self.youtubeVideoPlayer.moviePlayer.duration - self.youtubeVideoPlayer.moviePlayer.currentPlaybackTime)

            print("currentTimeLabel.text = \(currentTimeLabel.text)")
            print("endTimeLabel.text = \(endTimeLabel.text)")
        }
    }
}

func onClick(sender: UIButton)
{
    print("onClick")
    if sender == playPauseButton
    {
        print("playPauseButton touched")

        if sender.selected
        {
            print("player play")
            timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updatePlaybackSlider", userInfo: nil, repeats: true)

            isPauseButtonTouched = false
            youtubeVideoPlayer.moviePlayer.play()

            sender.selected = false
        }
        else
        {
            print("player paused")
            isPauseButtonTouched = true
            timer.invalidate()
            timer = nil

            youtubeVideoPlayer.moviePlayer.pause()

            sender.selected = true
        }
    }
}

func moviePlayerPlaybackStateDidChangeNotification(notification: NSNotification)
{
    print("moviePlayerPlaybackStateDidChangeNotification")

    let state: MPMoviePlaybackState = youtubeVideoPlayer.moviePlayer.playbackState

    switch state
    {
    case MPMoviePlaybackState.Stopped:
        print("stopped")
        break

    case MPMoviePlaybackState.Interrupted:
        print("interrupted")
        break

    case MPMoviePlaybackState.SeekingForward:
        print("forward")
        break

    case MPMoviePlaybackState.SeekingBackward:
        print("backward")
        break

    case MPMoviePlaybackState.Paused:
        print("paused")
        break

    case MPMoviePlaybackState.Playing:
        print("playing")
        break
    }
}

    func moviePlayerLoadStateDidChangeNotification(notification: NSNotification)
{
    print("moviePlayerLoadStateDidChangeNotification")

    let state: MPMovieLoadState = youtubeVideoPlayer.moviePlayer.loadState

    switch state
    {
    case MPMovieLoadState.Playable:
        print("playing")
        break

    case MPMovieLoadState.PlaythroughOK:
        print("PlaythroughOK")
        break

    case MPMovieLoadState.Stalled:
        print("stalled")
        break

    case MPMovieLoadState.Unknown:
        print("unknown")
        break

    default:
        break
    }
}

Here's an output from a couple seconds of video playback:

viewDidLoad
setUpVideoPlayer
viewDidAppear
moviePlayerLoadStateDidChangeNotification
time = 0
seconds = 0
time = 29
seconds = 29
playing
moviePlayerLoadStateDidChangeNotification
moviePlayerPlaybackStateDidChangeNotification
playing
PLAYBACKSLIDER IS NOT TOUCHED!
youtubeVideoPlayer.moviePlayer.currentPlaybackTime = 0.0
youtubeVideoPlayer.moviePlayer.duration = 29.8833333333333
sliderValue = 0.0
time = 0
seconds = 0
time = 29
seconds = 29
currentTimeLabel.text = Optional("00:00")
endTimeLabel.text = Optional("-00:29")
PLAYBACKSLIDER IS NOT TOUCHED!
youtubeVideoPlayer.moviePlayer.currentPlaybackTime = 0.484628237
youtubeVideoPlayer.moviePlayer.duration = 29.8833333333333
sliderValue = 0.016255
time = 0
seconds = 0
time = 29
seconds = 29
currentTimeLabel.text = Optional("00:00")
endTimeLabel.text = Optional("-00:29")
PLAYBACKSLIDER IS NOT TOUCHED!
youtubeVideoPlayer.moviePlayer.currentPlaybackTime = 1.484112736
youtubeVideoPlayer.moviePlayer.duration = 29.8833333333333
sliderValue = 0.0496863
time = 1
seconds = 1
time = 28
seconds = 28
currentTimeLabel.text = Optional("00:01")
endTimeLabel.text = Optional("-00:28")
onClick
playPauseButton touched
player paused
moviePlayerPlaybackStateDidChangeNotification
paused
isPauseButtonTouched = true
onClick
playPauseButton touched
player play
moviePlayerPlaybackStateDidChangeNotification
playing
PLAYBACKSLIDER IS NOT TOUCHED!
youtubeVideoPlayer.moviePlayer.currentPlaybackTime = 3.34555252
youtubeVideoPlayer.moviePlayer.duration = 29.8833333333333
sliderValue = 0.111982
time = 3
seconds = 3
time = 26
seconds = 26
currentTimeLabel.text = Optional("00:03")
endTimeLabel.text = Optional("-00:26")
moviePlayerPlaybackStateDidChangeNotification
paused

As you can see in the output, currentTimeLabel.text = Optional("00:01") is the time when I tapped pause. When I tap play, the output should be currentTimeLabel.text = Optional("00:02"), but it shows currentTimeLabel.text = Optional("00:03"). My endTimeLabel also skips by 2 seconds.

Why is this happening and how can I resolve it?

Thanks

1条回答
可以哭但决不认输i
2楼-- · 2019-07-24 01:06

resume the timer in playing state. Might solve the issue.

case MPMoviePlaybackState.Playing:{
                print("playing")
         timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updatePlaybackSlider", userInfo: nil, repeats: true)
                break
    }
查看更多
登录 后发表回答