我从RTMPPacket获取音频数据,我使用AudioQueue在IPAD中播放 首先,声音很好。但大约15分钟后,没有声音 然后数据正常,队列正在播放 我不知道为什么。谁能帮我?谢谢。
这是我用来播放音频的课程。
AudioPlayer.h
#import <Foundation/Foundation.h>
#import <CoreAudio/CoreAudioTypes.h>
#import <CoreFoundation/CoreFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
#include <unistd.h>
#define kNumberBuffers 3
@interface AudioPlayer : NSObject
{
AudioQueueRef mQueue;
AudioQueueBufferRef mBuffers[kNumberBuffers];
AudioStreamBasicDescription mPlayFormat;
int mIndex;
@public
Boolean mIsRunning;
Boolean mIsInitialized;
int mBufferByteSize;
int pip_fd[2];
UInt32 mNumPacketsToRead;
}
@property AudioQueueRef mQueue;
-(id)init;
-(id)initWithSampleRate:(int)sampleRate;
-(void)startPlayWithBufferByteSize:(int)bufferByteSize;
-(void)stopPlay;
-(void)putAudioData:(short*)pcmData;
@end
AudioPlayer.m
#import "AudioPlayer.h"
@implementation AudioPlayer
@synthesize mQueue;
void AQBufferCallback(void * inUserData ,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer)
{
AudioPlayer *THIS = (__bridge AudioPlayer *)(inUserData);
if(THIS->mIsRunning)
{
inBuffer->mPacketDescriptionCount = THIS->mBufferByteSize/2;
inBuffer->mAudioDataByteSize =THIS->mBufferByteSize;
if(read(THIS->pip_fd[0], inBuffer->mAudioData, THIS->mBufferByteSize) > 0 ){
AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
}
}
}
-(id)init
{
return [self initWithSampleRate:16000];
}
-(id)initWithSampleRate:(int)sampleRate
{
self = [super init];
if(self)
{
memset(&mPlayFormat, 0, sizeof(mPlayFormat));
mPlayFormat.mFormatID = kAudioFormatLinearPCM;
mPlayFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
mPlayFormat.mBitsPerChannel = 16;
mPlayFormat.mChannelsPerFrame = 1;
mPlayFormat.mBytesPerPacket = mPlayFormat.mBytesPerFrame = (mPlayFormat.mBitsPerChannel / 8) * mPlayFormat.mChannelsPerFrame;
mPlayFormat.mFramesPerPacket = 1;
mPlayFormat.mSampleRate = sampleRate;
mIsRunning = false;
mIsInitialized = false;
}
return self;
}
-(void)startPlayWithBufferByteSize:(int)bufferByteSize
{
if (mIsInitialized) return;
mBufferByteSize = bufferByteSize;
AudioQueueNewOutput(&mPlayFormat, AQBufferCallback, (__bridge void *)(self), nil, nil, 0, &mQueue);
for (int i=0; i<kNumberBuffers; i++) {
AudioQueueAllocateBuffer(mQueue, mBufferByteSize, &mBuffers[i]);
}
AudioQueueSetParameter(mQueue, kAudioQueueParam_Volume, 1.0);
mIsInitialized = true;
int ret = pipe(pip_fd);
if (ret == -1) {
NSLog(@"create pipe failed");
}
}
-(void)stopPlay
{
close(pip_fd[0]);
close(pip_fd[1]);
AudioQueueStop(mQueue, false);
if (mQueue){
AudioQueueDispose(mQueue, true);
mQueue = NULL;
mIsRunning = false;
}
mIsInitialized = false;
NSLog(@"stop play queue");
}
-(void)putAudioData:(short*)pcmData
{
if (!mIsRunning) {
memcpy(mBuffers[mIndex]->mAudioData, pcmData, mBufferByteSize);
mBuffers[mIndex]->mAudioDataByteSize = mBufferByteSize;
mBuffers[mIndex]->mPacketDescriptionCount = mBufferByteSize/2;
AudioQueueEnqueueBuffer(mQueue, mBuffers[mIndex], 0, NULL);
NSLog(@"fill audio queue buffer[%d]",mIndex);
if(mIndex == kNumberBuffers - 1) {
mIsRunning = true;
mIndex = 0;
AudioQueueStart(mQueue, NULL);
}else {
mIndex++;
}
}else {
if(write(pip_fd[1], pcmData, mBufferByteSize) < 0){
NSLog(@"write to the pipe failed!");
}
}
}
@end