ios 视频直播之蓝牙接入并转码成AAC

来源:互联网 发布:深入浅出数据分析阅读 编辑:程序博客网 时间:2024/04/30 15:40
 

ios 视频直播之蓝牙接入并转码成AAC 

 93人阅读 评论(0) 收藏 举报


最近项目需求,使用蓝牙传输语音,并且集成到已有的直播SDK中。

汗本人对蓝牙一知半解,加油研究吧。
先将手机连上蓝牙音箱,然后开启手机本地的录制视频,发现蓝牙的声音并不能被录到视频中,汗,看来苹果自带的摄像机并没有把蓝牙集成进来,好吧我们能做的只有,从苹果相机获取视频,从可识别蓝牙的麦克风中,获取蓝牙音频。

废话有点多直接上代码了。
AVAudioSession中很好的集成了蓝牙获取
使用AVAudioSession可以获取蓝牙音频。

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionAllowBluetooth  error:&error];

使用AudioQueue可以获取音频流。

这里做下解释,AVAudioSession 只是将音频的输入设备指向了蓝牙而已,AudioQueue 用于从麦克风获取声音。

typedef struct AQCallbackStruct
{
    AudioStreamBasicDescription mDataFormat;
    AudioQueueRef               queue;
    AudioQueueBufferRef         mBuffers[kNumberBuffers];
    AudioFileID                 outputFile;
    
    unsigned long               frameSize;
    long long                   recPtr;
    int                         run;
    
} AQCallbackStruct;

// Audio Settings
#define kNumberBuffers      3
#define kSamplingRate       44100

#define t_sample             SInt16
#define kNumberChannels     1
#define kBitsPerChannels    (sizeof(t_sample) * 8)
#define kBytesPerFrame      (kNumberChannels * sizeof(t_sample))
//#define kFrameSize          (kSamplingRate * sizeof(t_sample))
#define kFrameSize          4096


#define QUEUE_BUFFER_SIZE  2//队列缓冲个数
#define EVERY_READ_LENGTH  10240 //每次从文件读取的长度
#define MIN_SIZE_PER_FRAME 10240 //每侦最小数据长度

@property (nonatomic, assign) AQCallbackStruct aqc;


- (void) startGetAudio
{

    aqc.mDataFormat.mSampleRate = kSamplingRate;
    aqc.mDataFormat.mFormatID = kAudioFormatLinearPCM;
    aqc.mDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger |kLinearPCMFormatFlagIsPacked;
    aqc.mDataFormat.mFramesPerPacket = 1;
    aqc.mDataFormat.mChannelsPerFrame = kNumberChannels;
    aqc.mDataFormat.mBitsPerChannel = kBitsPerChannels;
    aqc.mDataFormat.mBytesPerPacket = kBytesPerFrame;
    aqc.mDataFormat.mBytesPerFrame = kBytesPerFrame;
    aqc.frameSize = kFrameSize;
    AudioQueueNewInput(&aqc.mDataFormat, AQInputCallback, (__bridge void *)(self), NULL, kCFRunLoopCommonModes, 0,  &aqc.queue);
    //        AudioQueueNewInput(&aqc.mDataFormat, AQInputCallback, (__bridge void *)(self), NULL, kCFRunLoopCommonModes,0, &aqc.queue);
    //        AudioQueueNewInput(&aqc.mDataFormat, AQInputCallback, (__bridge void *)(self), NULL, kCFRunLoopCommonModes, 0,  &aqc.queue);
    for (int i=0;i<kNumberBuffers;i++)
    {
        AudioQueueAllocateBuffer(aqc.queue, aqc.frameSize, &aqc.mBuffers);
        AudioQueueEnqueueBuffer(aqc.queue, aqc.mBuffers, 0, NULL);
    }
    aqc.recPtr = 0;
    aqc.run = 1;
    
    audioDataIndex = 0;
    
    AudioQueueStart(aqc.queue, NULL);
}


回调方法AQInputCallback中可以获取到音频数据 inBuffer
static void AQInputCallback (void                   * inUserData,
                             AudioQueueRef          inAudioQueue,
                             AudioQueueBufferRef    inBuffer,
                             const AudioTimeStamp   * inStartTime,
                             unsigned long          inNumPackets,
                             const AudioStreamPacketDescription * inPacketDesc)
{
    NSLog(@"AQInputCallback");

    Record * engine = (__bridge Record *) inUserData;
    if (inNumPackets > 0)
    {
        [engine processAudioBuffer:inBuffer withQueue:inAudioQueue];
    }
    
    if (engine.aqc.run)
    {
        AudioQueueEnqueueBuffer(engine.aqc.queue, inBuffer, 0, NULL);
    }

}


参考了【iOS录音与播放】实现利用音频队列,通过缓存进行对声音的采集与播放

下载地址  http://download.csdn.net/detail/yp2049858/9550554
0 0
原创粉丝点击