title: How to play mp3 from & to specific time in milliseconds on iOS?
body: <p>I have a requirement to play mp3 from and to specific time [given in milliseconds].
  After some research my bet went on AVPlayer, which seems to be the choice for everyone with similar requirement.
  Unfortunately for me it doesn't work [code included at the end].
  I am wondering if there's anything else I could use to play any iOS supported file format with start &amp; stop specified using milliseconds timescale?</p>
  
  <p>Here's my code using AVPlayer. I have created an mp3 which at 4.3 seconds has silence for around 600ms and then noise for around a second.
  I have 3 options of creating CMTime for use with seekToTime:</p>
  
  <ul>
  <li>4300 value with 1000 timescale</li>
  <li>4.3 * 60000 with 60000 timescale</li>
  <li>4.3 * timescale of the mp3 file with timescale of the mp3 file.</li>
  </ul>
  
  <p>Unfortunately none of the options worked for me, it was always set to somewhere inside the noise.</p>
  
  <p>I've tried to use lower values, just for the sake of it.
  I got to 3.7 seconds, which when set, starts a little bit BEFORE the silence.
  Funny thing: if I use 3.75 it will start to play in the middle of the noise.</p>
  
  <p><strong>Crucial parts of the code:</strong></p>
  
  <p>Declaration of CMTime:</p>
  
  <pre><code>mediaAudioStart = CMTimeMake((int64_t) (floatValue * 60000), 60000);
  </code></pre>
  
  <p>or</p>
  
  <pre><code>int32_t timeScale = _mediaAudioPlayer.currentItem.asset.duration.timescale;
  mediaAudioStart = CMTimeMake((int64_t) (floatValue * timeScale), timeScale);
  </code></pre>
  
  <p>or</p>
  
  <pre><code>mediaAudioStart = CMTimeMake(4300, 1000);
  </code></pre>
  
  <p><strong>Full code</strong></p>
  
  <p>Usage of seekToTime:</p>
  
  <pre><code>[_mediaAudioPlayer seekToTime:mediaAudioStart toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
          if (finished) {
              [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mediaAudioPlaybackFinished) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
              NSLog(@"CURRENT TIME: %lld", _mediaAudioPlayer.currentTime.value);
              [_mediaAudioPlayer play];
  
          } else {
              NSLog(@"Could not seek media overlay file.");
          }
      }];
  </code></pre>
  
  <p>ViewController.m</p>
  
  <pre><code>- (void)prepareMediaAudio {
      NSLog(@"prepareMediaAudio");
      NSString *mediaAudioPath = [[NSBundle mainBundle] pathForResource:@"boostmiddle" ofType:@"mp3"];
      NSURL *mediaAudioURL = [[NSURL alloc] initFileURLWithPath:mediaAudioPath];
      if (!_mediaAudioPlayer) {
          AVPlayer *player = [AVPlayer playerWithURL:mediaAudioURL];
          [self setMediaAudioPlayer:player];
          [_mediaAudioPlayer addObserver:self forKeyPath:@"status" options:0 context:nil];
      } else {
          [self mediaAudioSeek];
      }
  }
  
  - (void)stopMediaAudio {
      NSLog(@"stopMediaAudio");
      if (_mediaAudioPlayer) {
          [_mediaAudioPlayer removeObserver:self forKeyPath:@"status"];
          [_mediaAudioPlayer pause];
          _mediaAudioPlayer = nil;
      }
  }
  
  - (void)mediaAudioSeek {
      NSLog(@"mediaAudioSeek %lld %d", mediaAudioStart.value, mediaAudioStart.timescale);
  
      [_mediaAudioPlayer seekToTime:mediaAudioStart toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
          if (finished) {
              [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mediaAudioPlaybackFinished) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
              NSLog(@"CURRENT TIME: %lld", _mediaAudioPlayer.currentTime.value);
              [_mediaAudioPlayer play];
  
          } else {
              NSLog(@"Could not seek media overlay file.");
          }
      }];
  }
  
  - (void)mediaAudioPlaybackFinished {
      NSLog(@"mediaAudioPlaybackFinished");
      [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
      [self stopMediaAudio];
  }
  
  
  - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                          change:(NSDictionary *)change context:(void *)context {
      NSLog(@"observeValueForKeyPath");
      if (object == _mediaAudioPlayer &amp;&amp; [keyPath isEqualToString:@"status"]) {
          if (_mediaAudioPlayer.status == AVPlayerStatusReadyToPlay) {
              NSLog(@"READY TO PLAY");
          } else if (_mediaAudioPlayer.status == AVPlayerStatusFailed) {
              NSLog(@"Could not load Media Overlay audio");
          }
      }
  }
  
  - (IBAction)button1Action:(id)sender {
      NSString *value = valueText.text;
      float floatValue = [value floatValue];
      NSLog(@"button1Action %f", floatValue);
      mediaAudioStart = CMTimeMake((int64_t) (floatValue * 60000), 60000);
      [self mediaAudioSeek];
  }
  
  - (IBAction)button2Action:(id)sender {
      NSString *value = valueText.text;
      float floatValue = [value floatValue];
      NSLog(@"button2Action %f", floatValue);
      int32_t timeScale = _mediaAudioPlayer.currentItem.asset.duration.timescale;
      mediaAudioStart = CMTimeMake((int64_t) (floatValue * timeScale), timeScale);
      [self prepareMediaAudio];
  }
  
  - (IBAction)button3Action:(id)sender {
      NSLog(@"button3Action [4300, 1000]");
      mediaAudioStart = CMTimeMake(4300, 1000);
      [self prepareMediaAudio];
  }
  
  - (IBAction)stopAction:(id)sender {
      [self stopMediaAudio];
  }
  
  - (IBAction)prepareAction:(id)sender {
      [self prepareMediaAudio];
  }
  </code></pre>
  
  <p><strong>Example project</strong></p>
  
  <p>You can get my project from here, including the mp3 file I use for testing. Just type 4.3 in the text field.</p>
  
  <p><a href="https://www.dropbox.com/s/7q2xmuhdu1xih75/iosAudioTest.zip?dl=0" rel="nofollow">https://www.dropbox.com/s/7q2xmuhdu1xih75/iosAudioTest.zip?dl=0</a></p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>After updating the mp3 file - making it shorter - the values used to get to the same spot changed. Now 4.3 points to somewhere else :/ Now I'm totally clueless regarding operation of the seekToTime method.</p>