I've tried to get an mp3 file played with Audio Toolbox and Audio Queues, but whatever I try, I don't get anything played (neither in the simulator nor on the device). When I run it in the simulator it tells me:
"Prime failed (-66674); will stop (0/0 frames)",
so I think there is a basic mistake somewhere, maybe in the AudioEnqueueBuffer function, because there seems to be nothing in the queue afterwards. When I ask for the status, I always get 0 back.
I'm sorry that I have posted so much code, but I'm just not sure where the mistake is.
Please help me.
- (void)startPlayback{
NSString *fileString = [[NSBundle mainBundle] pathForResource:@"musik" ofType:@"mp3"];
const char *filePathAsCString = [fileString UTF8String];
CFURLRef fileURL = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)filePathAsCString, strlen(filePathAsCString), false);
playState.currentPacket = 0;
playState.dataFormat->mSampleRate = kAudioStreamAnyRate;
playState.dataFormat->mFormatID = kAudioFormatMPEGLayer3;
playState.dataFormat->mFramesPerPacket = 0;
playState.dataFormat->mChannelsPerFrame = 2;
playState.dataFormat->mBytesPerFrame = 0;
playState.dataFormat->mBytesPerPacket = 0;
playState.dataFormat->mBitsPerChannel = 0;
playState.dataFormat->mReserved = 0;
playState.dataFormat->mFormatFlags = 0;;
OSStatus status;
status = AudioFileOpenURL(fileURL, kAudioFileReadPermission, kAudioFileMP3Type, &playState.audioFile);
if(status == 0)
{
status = AudioQueueNewOutput(
&playState.dataFormat,
MyAudioOutputCallback,
&playState,
CFRunLoopGetCurrent(),
0,
0,
&playState.queue);
if(status == 0)
{
playState.playing = true;
for(int i = 0; i < 3 && playState.playing; i++)
{
if(playState.playing)
{
AudioQueueAllocateBufferWithPacketDescriptions(playState.queue, 64000, sizeof(AudioStreamPacketDescription)*75, &playState.buffers[i]);
MyAudioOutputCallback(&playState, playState.queue, playState.buffers[i]);
}
}
if(playState.playing)
{
status = AudioQueueStart(playState.queue, NULL);
if(status == 0)
{
NSLog(@"Playing");
}
}
}
}
if(status != 0)
{
NSLog(@"Play failed");
}
}
And here the Callback function:
void MyAudioOutputCallback( void *inUserData,
AudioQueueRef outAQ,
AudioQueueBufferRef outBuffer)
{
PlayState *playState= (PlayState *)inUserData;
UInt32 bytesRead;
UInt32 numPackets = 75;
OSStatus status;
status = AudioFileReadPackets(playState->audioFile, false, &bytesRead, outBuffer->mPacketDescriptions, playState->currentPacket, &numPackets, outBuffer->mAudioData);
if(numPackets)
{
outBuffer->mAudioDataByteSize = bytesRead;
outBuffer->mPacketDescriptionCount = numPackets;
status = AudioQueueEnqueueBuffer(
playState->queue,
outBuffer,
0,
0);
NSLog(@"EnqueueStatus: %d", status);
playState->currentPacket += numPackets;
}
}
Oh yeah, that was 2010, the horrible days when you had to buffer samples yourself just to play a freaking audio file... Nowadays, if all you want to do is play an audio file, AVAudioPlayer is your friend.
NSError *error = nil;
AVAudioPlayer *myMP3File = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/MyFile.mp3",
[[NSBundle mainBundle] resourcePath]]] error:&error];
[myMP3File play];
if(error != nil) NSLog(@"Error mp3 file: %@",error);
Here's a decent tutorial for AVAudioPlayer .
Try this:
First import this framework to your file AVFoundation/AVFoundation.h
Then declare an instance of AVAudioPlayer. AVAudioPlayer *audioPlayer;
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:@"Name of your audio file"
ofType:@"type of your audio file example: mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
audioPlayer.numberOfLoops = -1;
[audioPlayer play];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.