AudioqueuePlayer icon indicating copy to clipboard operation
AudioqueuePlayer copied to clipboard

去掉录制部分,优化播放直播流部分

Open zj381652512 opened this issue 5 years ago • 0 comments

**#define QUEUE_BUFFER_SIZE 10 // 队列缓冲个数(设置3时,播放不连续) #define MIN_SIZE_PER_FRAME 2048 // 每帧最小数据长度

BOOL audioQueueUsed[QUEUE_BUFFER_SIZE]; AudioQueueBufferRef pBuffer[QUEUE_BUFFER_SIZE];

@interface QueuePlayer () { AudioQueueRef _playQueue; } // config是外界传入参数的集合 *@property (nonatomic, strong) CCAudioConfig config; // 所有缓存位是否空闲 @property (nonatomic, assign) BOOL empty;

@end

@implementation QueuePlayer

*- (instancetype)initWithConfig:(CCAudioConfig )config { self = [super init]; if (self) { _empty = YES; _config = config;

    AudioStreamBasicDescription ASBD;
    **ASBD.mSampleRate  = config.sampleRate;**
    ASBD.mFormatID    = kAudioFormatLinearPCM;
    ASBD.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
    **ASBD.mChannelsPerFrame = (int32_t)config.channelCount;**
    ASBD.mFramesPerPacket  = 1;
    ASBD.mBitsPerChannel   = 16;
    ASBD.mBytesPerFrame    = (ASBD.mBitsPerChannel / 8) * ASBD.mChannelsPerFrame;
    ASBD.mBytesPerPacket   = ASBD.mBytesPerFrame * ASBD.mFramesPerPacket;

    OSStatus status = AudioQueueNewOutput(&ASBD, queueOutputCallback, (__bridge void *_Nullable)(self), nil, nil, 0, &_playQueue);
    if (status != noErr) {
        NSLog(@"AudioQueueNewOutput error = %d", (int)status);
    }
    AudioQueueSetParameter(_playQueue, kAudioQueueParam_Volume, 1.0);
    for (int i = 0; i < QUEUE_BUFFER_SIZE; i++) {
        AudioQueueAllocateBuffer(_playQueue, MIN_SIZE_PER_FRAME, pBuffer + i);
    }
}
return self;

}

  • (void)dealloc { if (_playQueue != NULL) { AudioQueueStop(_playQueue, YES); AudioQueueDispose(_playQueue, YES); _playQueue = NULL; } }

  • (void)start { NSLog(@"%s", func); AudioQueueStart(_playQueue, 0); AudioQueueSetParameter(_playQueue, kAudioQueueParam_Volume, 1.0); }

  • (void)stop { NSLog(@"%s", func); AudioQueueStop(_playQueue, 0); }

*- (void)playPCMData:(NSData )data { AudioQueueBufferRef theBuffer = NULL; for (int i = 0; i < QUEUE_BUFFER_SIZE; i++) { if (audioQueueUsed[i]) { continue; } theBuffer = pBuffer[i]; @synchronized (self) { audioQueueUsed[i] = YES; } memcpy(theBuffer->mAudioData, data.bytes, data.length); theBuffer->mAudioDataByteSize = (UInt32)data.length; AudioQueueEnqueueBuffer(_playQueue, theBuffer, 0, nil);

    // 每次充填后都调start,避免填充失败,导致没有callback
    **[self start];**
    break;
}

}

**- (void)setEmpty:(BOOL)empty { if (_empty == empty) return; _empty = empty;

NSLog(@"%s empty=%d", __func__, empty);
if (empty) {
    // 所有缓存位空闲时,就停止播放,适用于退到后台无流情况
    [self stop];
}

}**

static void queueOutputCallback(void *__nullable inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) { QueuePlayer *player = (__bridge QueuePlayer *)inUserData;

NSMutableString *str = [NSMutableString string];
BOOL empty = YES;
for (int i = 0; i < QUEUE_BUFFER_SIZE; i++) {
    if (inBuffer == pBuffer[i]) {
        @synchronized (player) {
            audioQueueUsed[i] = NO;
            NSLog(@"-[QueuePlayer %s] buff(%d)使用完成", __func__, i);
        }
    }
   // 检查流缓存使用情况
    **if (audioQueueUsed[i] == YES) {
        empty = NO;
        [str appendFormat:@"1"];
    } else {
        [str appendFormat:@"0"];
    }
}
NSLog(@"-[QueuePlayer %s] buff使用情况:%@", __func__, str);
player.empty = empty;**

}

@end

zj381652512 avatar Mar 13 '20 02:03 zj381652512