14

I am experience some weirdness with MPMoviePlayerController.

I am trying to set the currentPlaybackTime of a video whilst it is playing (file source). Here is an example of what happens

  1. Play video
  2. hit button to jump to 9.3 seconds into the video
  3. Play state changes as follows:

a) Play state = 5 (MPMoviePlaybackStateSeekingBackward). currentPlaybackTime = 15.74 (this is the time I had got to when I pressed the button)

b) Play state = 1 (MPMoviePlaybackStatePlaying). currentPlaybackTime = 7.32

It doesn't seem to matter what I try and set currentPlaybackTime to it ends up as 7.32.

Some extra info: I get this behaviour even using the built in controls on MPMoviePlayerController. e.g. If I scroll it forward to 15 seconds it jumps back to 7.32

Any ideas? Is it something to do with the media file?

DShah
  • 9,768
  • 11
  • 71
  • 127
Ian1971
  • 3,666
  • 7
  • 33
  • 61
  • 1
    Exact seeking is depending on the content encoding. You may reencode the video and force more i-Frames. This will reduce the compression rate but increase the chances of exact seeking. – Till Sep 12 '11 at 07:17
  • It doesn't seem to be specific to the content. How come quicktime can jump to the exact spot? – Ian1971 Sep 12 '11 at 10:53
  • See below. It turns out if you use AVPlayer you can be more specific about accuracy by using the seekTo:toleranceBefore:toleranceAfter method – Ian1971 Sep 12 '11 at 13:15
  • MPMoviePlayerController is a buggy nightmare. See my comment under [Chris Danielson](http://stackoverflow.com/users/333821/chris-danielson)'s answer. – n8tr Jul 03 '14 at 00:48

4 Answers4

7

You should seek using seekToTime or seekToTimeWithSeconds.

 CMTime npt = CMTimeMake(9,1);
 [self.player seekToTime:npt];

or

  CMTime npt = CMTimeMakeWithSeconds(9.3, 600);
   [self.player seekToTime:npt toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
cdasher
  • 3,083
  • 1
  • 19
  • 20
  • 1
    This should not make any difference - currentPlaybackTime is fine. – Till Sep 12 '11 at 07:15
  • I can confirm if I switch to AVPlayer instead I have the same problem with seekToTime as I do with currentPlaybackTime – Ian1971 Sep 12 '11 at 11:22
  • on further investigation there is another seekToTime method that seems to do the job. seekToTime:toleranceBefore:toleranceAfter: . If you pass kCMTimeZero to that as tolerance it then seems to be accurate. – Ian1971 Sep 12 '11 at 12:25
  • @cdasher - Thanks for your help. Your answer pointed me in the right direction and I was stumped. A few things need adding/changing in your answer (I'll accept it if you can update it). Specifically, CMTimeMake takes integer inputs. I ended up using CMTimeMakeWithSeconds(float, integer) instead with the timescale parameter set to 600. then I used seekToTime:npt toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero to force it to do sample accurate seeking. – Ian1971 Sep 12 '11 at 15:00
  • This method is available for the AVPlayer but not MPMoviePlayerController. – YSR fan Sep 23 '13 at 05:55
  • seekToTime is not a function for MPMoviePlayerController – jose920405 Jun 24 '15 at 16:40
3

This is a late response, but I found a solution to my issue which was similar. You can modify the playback as follows:

#define START_TIME 50.0f
#define END_TIME   START_TIME + 20.0f  //play for 20 seconds

MPMoviePlayerController *player = [self moviePlayerController];
[player stop];
[player setInitialPlaybackTime:START_TIME];
[player setEndPlaybackTime:END_TIME];
[player play];
Chris Danielson
  • 159
  • 1
  • 4
  • 1
    it wont work, It is same as stting currentPlaybackTime property – rakeshNS Mar 05 '12 at 05:45
  • Yes it no longer works... you are right. This did work when it was originally published on Oct 5, 2011. – Chris Danielson Apr 27 '12 at 20:40
  • 4
    MPMoviePlayerController is the worst Apple API. It is so horribly buggy. Setting the initial playback time and end playback time works only the first time after init'ing it. Once it starts playing, if I want to stop it and start it again from the same point, I have to alloc/init a new instance to get it to work. I've lost countless hours on its menagerie of bugs. – n8tr Jul 03 '14 at 00:45
1

I want to share my experience for MPMoviePlayerController mediaPlayer to play MP3.

[mediaPlayer setCurrentPlaybackTime:currentPlayBackTime]; // it is not working for MP3 file. This is work only for video.

i used for MP3 and it is working for IOS 11 and later.

[mediaPlayer setInitialPlaybackTime:currentPlayBackTime]; // play MP3 file from last position

ethemsulan
  • 2,241
  • 27
  • 19
1

cdasher pointed me in the right direction but this is what you should do:

Seek using seekToTime:toleranceBefore:toleranceAfter for sample accurate seeks. For this you must use AVPlayer not MPMediaPlayerController

CMTime npt = CMTimeMakeWithSeconds(9.3, 600);
[self.player seekToTime:npt toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
Ian1971
  • 3,666
  • 7
  • 33
  • 61