2011-10-04 9 views
10

Estoy usando una sesión AVCaptureSession para capturar muestras de audio y video desde el micrófono y la cámara del dispositivo.¿Cómo uso AVAssetWriter para escribir audio AAC en ios?

entonces yo estoy tratando de escribir las CMSampleBuffers (usando AVAssetWriter y AVAssetWriterInputs) devueltos por el método de AVCaptureSessions delegado

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

Esto funciona bien cuando mi AVAssetWriterInput de audio está configurado para escribir los datos en el formato Apple Lossless (kAudioFormatAppleLossless), pero si trato y configurar el AVAssetWriterInput de audio para utilizar AAC (kAudioFormatMPEG4AAC) se escribe con éxito muestras de vídeo y audio por alrededor de 500 ms a continuación, se produce el siguiente error

writer has failed with Error Domain=AVFoundationErrorDomain Code=-11821 "Cannot Decode" UserInfo=0x4b2630 {NSLocalizedFailureReason=The media data could not be decoded. It may be damaged., NSUnderlyingError=0x4ad0f0 "The operation couldn’t be completed. (OSStatus error 560226676.)", NSLocalizedDescription=Cannot Decode} 

Este es el código que utilizo para crear mi AVAssetWriter y AVAssetWriterInputs

NSError *error = nil; 
m_VideoCaputurePath = [[NSString stringWithFormat:@"%@/%@.mp4",[UserData getSavePath],[UserData getUniqueFilename]] retain]; 

if(USE_AAC_AUDIO) 
{ 
    m_audioAndVideoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:m_VideoCaputurePath] fileType:AVFileTypeMPEG4 error:&error]; 
} 
else 
{ 
    m_audioAndVideoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:m_VideoCaputurePath] fileType:AVFileTypeQuickTimeMovie error:&error]; 
} 

//\Configure Video Writer Input 
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
           AVVideoCodecH264, AVVideoCodecKey, 
           [NSNumber numberWithInt:640], AVVideoWidthKey, 
           [NSNumber numberWithInt:480], AVVideoHeightKey, 
           nil]; 

m_videoWriterInput = [[AVAssetWriterInput 
         assetWriterInputWithMediaType:AVMediaTypeVideo 
         outputSettings:videoSettings] retain]; 

m_videoWriterInput.expectsMediaDataInRealTime = YES; 

//\Configure Audio Writer Input 

AudioChannelLayout acl; 
bzero(&acl, sizeof(acl)); 
acl.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; 

NSDictionary* audioOutputSettings; 
if(USE_AAC_AUDIO) 
{ 
    audioOutputSettings = [ NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kAudioFormatMPEG4AAC], AVFormatIDKey, 
              [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey, 
              [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey, 
              [ NSData dataWithBytes: &acl length: sizeof(acl) ], AVChannelLayoutKey, 
              [ NSNumber numberWithInt: 96 ], AVEncoderBitRateKey, 
              nil]; 
} 
else 
{ 
    audioOutputSettings = [ NSDictionary dictionaryWithObjectsAndKeys:      
              [ NSNumber numberWithInt: kAudioFormatAppleLossless ], AVFormatIDKey, 
              [ NSNumber numberWithInt: 16 ], AVEncoderBitDepthHintKey, 
              [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey, 
              [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey,          
              [ NSData dataWithBytes: &acl length: sizeof(acl) ], AVChannelLayoutKey, nil ]; 
} 

m_audioWriterInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioOutputSettings] retain]; 

m_audioWriterInput.expectsMediaDataInRealTime = YES; 

//\Add inputs to Write 
NSAssert([m_audioAndVideoWriter canAddInput:m_audioWriterInput], @"Cannot write to this type of audio input"); 
NSAssert([m_audioAndVideoWriter canAddInput:m_videoWriterInput], @"Cannot write to this type of video input"); 

[m_audioAndVideoWriter addInput:m_videoWriterInput]; 
[m_audioAndVideoWriter addInput:m_audioWriterInput]; 

¿Alguien sabe cómo escribir correctamente las muestras de audio de regresar de AVCaptureSession utilizando un AVAssetWriterInput configurado para escribir AAC?

Respuesta

12

me las arreglé para conseguir que funcione cambiando el parámetro AVEncoderBitRateKey pasado como los ajustes de salida deseados de 96 a 64000.

Mis ajustes de audio para inicializar un AVAssetWriterInput capaz de audio AAC escritura ahora se ve como

NSDictionary* audioOutputSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
            [ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey, 
            [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey, 
            [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey, 
            [ NSData dataWithBytes: &acl length: sizeof(AudioChannelLayout) ], AVChannelLayoutKey, 
            [ NSNumber numberWithInt: 64000 ], AVEncoderBitRateKey, 
            nil] 
+0

Con el nuevo iPhone 4s también tuve que cambiar AVNumberOfChannelsKey por 2 – RyanSullivan

+0

¡No podía entender esto! Sabía que tenía algo que ver con las opciones, pero no sabía exactamente qué. ¡Gracias por esto! –

Cuestiones relacionadas