0

首先,我使用 AVCaptureSession 从摄像头和麦克风捕获视频和音频。然后委托下面的方法代码:

 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{

     // if is Vedio data ,append to vedioInputWriter
    if (mediaType == kCMMediaType_Vedio){
        // ...
        // ...
        // ...
        // write the video data
        if (_assetWriterVideoInput.readyForMoreMediaData){
           [_assetWriterInputPixelBufferAdaptor appendPixelBuffer:renderedOutputPixelBuffer withPresentationTime:timestamp];
        }
        return;
    }


    size_t bufferListSizeNeededOut;
    CMBlockBufferRef blockBufferOut = nil;

    // get AudioBufferList
    err = CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer,
                                                                  &bufferListSizeNeededOut,
                                                                  currentInputAudioBufferList,
                                                                  CAAudioBufferList::CalculateByteSize(currentInputASBD.mChannelsPerFrame),
                                                                  kCFAllocatorSystemDefault,
                                                                  kCFAllocatorSystemDefault,
                                                                  kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
                                                                  &blockBufferOut); 

    // mix recorded audio with background music 
    [self mixAudioBufferListwithBackgroundMusic:currentInputAudioBufferList];

    if (!self.audioInputAssetWriter.readyForMoreMediaData) {
        if (self.assetWriter.status == AVAssetWriterStatusFailed) {
            NSLog(@"assetWrite error=%@",self.viewController.assetWriter.error);
        }
        return;
    }

    // tranfer `AudioBufferList` to `CMSampleBuffer`
    CMSampleBuffer newSampleBuffer = [self processAudioData:outputBufferList->ABL() framesNumber:numberOfFrames format:&mClientFormat];

    // append samplebuffer to assetInputWriter
    if ([self.audioInputAssetWriter appendSampleBuffer:newSampleBuffer]) {
        NSLog(@" append sample buffer success");
    }else{
         NSLog(@"append sample buffer failed");
    }
}

转入AudioBufferList以下CMSampleBuffer代码:

- (CMSampleBufferRef)processAudioData:(AudioBufferList *)audioData framesNumber:(UInt32 )num format:(AudioStreamBasicDescription *)asbd
{
    CMSampleBufferRef sbuf;
    OSStatus status;
    // 1.audio foramt description
    CMAudioFormatDescriptionRef format;
    status = CMAudioFormatDescriptionCreate(kCFAllocatorDefault,&(bufferToSampleFormat), 0, NULL, 0, NULL, NULL, &format); 

    // 2.sample timing info
    CMSampleTimingInfo timing;
    timing.duration = CMTimeMake(1,44100);
    timing.presentationTimeStamp = kCMTimeZero;
    timing.decodeTimeStamp = kCMTimeInvalid;

    size_t sampleSizeArray[1] = {4};

    // 3.create sample buffer
    status = CMSampleBufferCreate(kCFAllocatorDefault,NULL,false, NULL,NULL,format,(CMItemCount)num,1,&timing,0,NULL, &sbuf);

    // 4.sample buffer set data buffer from audio buffer list
    status = CMSampleBufferSetDataBufferFromAudioBufferList(sbuf, kCFAllocatorDefault, kCFAllocatorDefault, 0, audioData);
    if (status != noErr) {
        NSLog(@"sample buffer set data buffer from audio buffer list failed -- %d",(int)status);
        return nil;
    }
    return sbuf;
}

最后,将视频和音频数据保存为test.mov文件。问题是用 Quicktime 播放文件,但没有声音。用VLC播放文件,有声音。并且可以用ffmpeg剥离出aac格式的音频文件。

我想问题是AudioBufferList转移到CMSampleBuffer,缺少一些信息导致 Quicktime 无法正确播放。

4

0 回答 0