AVAudioPlayer initWithContentsOfURL returns nil for AAC/M4A files

RawMean picture RawMean · Nov 20, 2013 · Viewed 8.5k times · Source

I use the following code to play an audio file. It plays fine for MP3 files, but when I try to play an AAC file, the [[AVAudioPlayer alloc] initWithContentsOfURL:] returns nil and I get the following error:

Error Domain=NSOSStatusErrorDomain Code=1937337955 "The operation couldn’t be completed. (OSStatus error 1937337955.)"

The audio file plays fine on Mac and iPhone (when I email it to myself) and is here: https://dl.dropboxusercontent.com/u/2667666/song.aac

NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];

// Create audio player with background music
NSString *backgroundMusicPath = [[NSBundle mainBundle] pathForResource:@"song" ofType:@"aac"];
NSURL *backgroundMusicURL = [NSURL fileURLWithPath:backgroundMusicPath];
NSError *error;
_backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error];
if (!_backgroundMusicPlayer) {
    NSLog(@"_backgroundMusicPlayer pointer is null!!");
}
[_backgroundMusicPlayer setDelegate:self];  // We need this so we can restart after interruptions
[_backgroundMusicPlayer prepareToPlay];
[_backgroundMusicPlayer play];

Update: If I change the extension of the file from aac to m4a, the error code change to 1954115647 (whose four letter code is "tip?"). The four letter code for the error code that I get with the arc extension is "sync".

Answer

Nir Golan picture Nir Golan · Feb 12, 2014

Initializing the audio player with initWithData:error: solves this.
For example:

NSData* data = [NSData dataWithContentsOfURL:url] ;
AVAudioPlayer* audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:outError];

Disappointing that apple initializes their audio player based on extension, instead of looking at the binary data and trying to figure out which type of data they received.