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
resume the timer in playing state. Might solve the issue.