1

Using an AVPlayer I would like to play a mov file for exactly 1 second then pause it.

Currently I'm playing the mov then setting a timer to pause it after 1 second as below. Unfortunately, this does not appear to be exactly accurate and the mov is sometimes playing for slightly shorter or longer than 1 second. Is there a more accurate way of doing this please?

[self.player4 play];
[self performSelector:@selector(pausePlayer4:) withObject:nil afterDelay:1.0];

- (void)pausePlayer4:(NSTimer *)timer
{
    [self.player4 pause];
}
Simon
  • 344
  • 4
  • 20
  • tried to put `performSelector` in main thread? – Mohammad Zaid Pathan Mar 17 '16 at 12:33
  • 1
    How precise is your latency requirement? miliseconds? miscroseconds?... You can use `dispatch_after` with pretty high level of precision, note that there is a `leeway` value when using `dispatch_after` that is set default to +/- 10% of the time interval. @matt has a great easy to use function that he wrote for this purpose, [you can find it here](http://stackoverflow.com/questions/24034544/dispatch-after-gcd-in-swift/24318861#24318861). – MikeG Mar 18 '16 at 04:27

2 Answers2

1

Even if you can get an event to fire precisely enough, media playback on iOS devices happens in an entirely different process (a daemon) and there's always latency when doing IPC.

Depending on your needs it might be best to build an AVMutableComposition that plays exactly one second of content from your AVURLAsset, and then assign the composition to your player.

damian
  • 3,534
  • 1
  • 23
  • 44
  • Thanks, if this is the case my best option may be to create several individual 1 second movs in the first place? The animation only lasts for 1 second. The reason for bundling the animations into a longer mov was purely for convenience and based upon the assumption that I could accurately control the playback – Simon Mar 18 '16 at 19:03
  • 1
    Yes, you'd be best to make 1 second movies. Time accurate real-time playback of video is just hard, due to the amount of data that has to get pushed around. Do some math with pixel counts, bytes per pixel and frames per second and you'll start to see what I mean :) – damian Mar 20 '16 at 11:03
0

The best way wold be to add a boundary observer to trigger after a second

    NSValue *endBoundary = [NSValue valueWithCMTime:CMTimeMakeWithSeconds(1.0, 300)];

    [self.player4 addBoundaryTimeObserverForTimes:@[endBoundary]
                                            queue:NULL
                                       usingBlock:^{
                                        [self.player4 stop];
                                        }];

    [self.player4 play];
amergin
  • 2,926
  • 28
  • 41