3

I'm porting an app that works with aac audio files to iOS6 and I've found an strange behavior, when I try to get the duration of the (valid) aac audio file, it's always returns 0, in iOS4 and iOS5 it works fine.

¿Is there any bug on AvAudioPlayer class that affects duration property? I have read about some troubles with the currentTime property.

Here's the code:

NSURL* urlFichero = [NSURL fileURLWithPath:rutaFichero];
avaPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: urlFichero error:nil];
segundos = avaPlayer.duration;
NSLog(@"[ControladorFicheros] Fichero: '%@' Duración: '%f'", nombreFichero, segundos);
[avaPlayer stop];
[avaPlayer release];

Thanks ;)

PoOk
  • 645
  • 7
  • 17
  • Does "controlado ficheros" mean "file manager"? –  Nov 21 '12 at 16:28
  • Yes, but it's only the name of the class which contains the code, it's trivial, the code works fine on previous versions of iOS... – PoOk Nov 21 '12 at 16:36

2 Answers2

4

Finally the problem is that in newest versions of the API, AVAudioPlayer appears to only returns the correct duration of a file when it is ready for play it, that's why my solution was wrong, the correct way to get the duration of a file (in seconds) if you don't want to reproduce it is:

AVURLAsset *asset = [[[AVURLAsset alloc] initWithURL:anURI_ToResource 
                  options:[NSDictionary dictionaryWithObjectsAndKeys:
                  [NSNumber numberWithBool:YES], 
                  AVURLAssetPreferPreciseDurationAndTimingKey,
                  nil]] autorelease];

 NSTimeInterval durationInSeconds = 0.0;
if (asset) 
     durationInSeconds = CMTimeGetSeconds(asset.duration) ;

Swift

let asset = AVURLAsset(url: url, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
let durationInSeconds = CMTimeGetSeconds(asset.duration)
Tapas Pal
  • 7,073
  • 8
  • 39
  • 86
PoOk
  • 645
  • 7
  • 17
  • This code is runing in main thread,and cost too much time.Do you have a good treatment method? – wormlxd Dec 03 '13 at 03:38
  • @wormlxd you can determine the duration asynchronously using loadValuesAsynchronouslyForKeys:completionHandler: – Alec Jan 30 '14 at 20:58
1

I noticed the same problem. My solution is to use instead.

MPMoviePlayerController *testPlayer = [[MPMoviePlayerController alloc] initWithContentURL:filePath];
[testPlater prepareToPlay];
[testPlater play];
RawMean
  • 8,374
  • 6
  • 55
  • 82