2011-12-18 2 views
3

모두! 저는 앱을 다루고 있습니다. 오디오 파일을 다른 사람에게 녹음 할 수 있습니다. 오디오 파일은 (.aac) 파일로 저장됩니다. 그런 다음 .aac 파일로 이미 저장 한 녹음을 계속하고 싶습니다. 그것을 만들기 위해 AVAssetReader와 AVAssetWriter를 사용했습니다.하지만 실패했습니다! 난 그냥 다른 파일을 녹음 한 후 이전에 이상을 추가 할AVAssetReader 및 AVAssetWriter를 사용하여 AAC 파일을 만드는 방법은 무엇입니까?

AVMutableComposition *mixComposition = [AVMutableComposition composition]; 
NSURL *url = [NSURL fileURLWithPath:[DOCUMENTS_FOLDER stringByAppendingPathComponent:buttonTitle]]; 
NSURL *anotherUrl = [NSURL fileURLWithPath:[DOCUMENTS_FOLDER stringByAppendingPathComponent:[fileList objectAtIndex:0]]]; 


CMTime nextClipStartTime = kCMTimeZero; 
AVURLAsset *preAudioAsset = [[AVURLAsset alloc]initWithURL:url options:nil]; 
CMTimeRange preTimeRange = CMTimeRangeMake(kCMTimeZero, preAudioAsset.duration); 
AVMutableCompositionTrack *preCompositonTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
[preCompositonTrack insertTimeRange:preTimeRange ofTrack:[[preAudioAsset tracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0] atTime:nextClipStartTime error:nil]; 

nextClipStartTime = CMTimeAdd(nextClipStartTime, preAudioAsset.duration); 
AVURLAsset *cruAudioAsset = [[AVURLAsset alloc]initWithURL:anotherUrl options:nil]; 
CMTimeRange cruTimeRange = CMTimeRangeMake(kCMTimeZero, cruAudioAsset.duration); 
[preCompositonTrack insertTimeRange:cruTimeRange ofTrack:[[cruAudioAsset tracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0] atTime:nextClipStartTime error:nil]; 

//AVAssetReader part 
NSError *error; 
AVAssetReader *assetReader = [[AVAssetReader assetReaderWithAsset:mixComposition error:&error]retain]; 
if(error) 
{ 
    NSLog(@"error:%@",error); 

} 
AVAssetTrack *audioTrack = [[mixComposition.tracks objectAtIndex:0]retain]; 
AVAssetReaderOutput *assetReaderOutput =[[AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:audioTrack outputSettings:nil]retain]; 
if(![assetReader canAddOutput:assetReaderOutput]) 
{ 
    NSLog(@"Can't add output!"); 
    return; 
} 
[assetReader addOutput:assetReaderOutput]; 

NSURL *exportUrl = [NSURL fileURLWithPath:[DOCUMENTS_FOLDER stringByAppendingPathComponent:@"combine.aac"]]; 

//AVAssetWriter part 
AVAssetWriter *assetWriter = [[AVAssetWriter assetWriterWithURL:exportUrl fileType:AVFileTypeMPEG4 error:&error]retain]; 
if(error) 
{ 
    NSLog(@"error:%@",error); 
    return; 
} 
AudioChannelLayout channelLayout; 
memset(&channelLayout, 0, sizeof(AudioChannelLayout)); 
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; 
NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
           [ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey, 
           [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey, 
           [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey, 
           [ NSData dataWithBytes: &channelLayout length: sizeof(AudioChannelLayout) ], AVChannelLayoutKey, 
           [ NSNumber numberWithInt: 64000 ], AVEncoderBitRateKey, 
           nil]; 
AVAssetWriterInput *assetWriterInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:outputSettings]retain]; 
if([assetWriter canAddInput:assetWriterInput]) 
{ 
    [assetWriter addInput:assetWriterInput]; 
} 
else 
{ 
    NSLog(@"can't add asset writer input ....."); 
    return; 
} 
assetWriterInput.expectsMediaDataInRealTime = NO; 
[assetWriter startWriting]; 
[assetReader startReading]; 
CMTime startTime = CMTimeMake(0, audioTrack.naturalTimeScale); 
[assetWriter startSessionAtSourceTime:startTime]; 

dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue",NULL); 
[assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue usingBlock:^ { 
    while(assetWriterInput.readyForMoreMediaData) 
    { 
     CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer]; 
     if(nextBuffer) 
     { 
      //append buffer 
      [assetWriterInput appendSampleBuffer:nextBuffer]; 

     } 
     else 
     { 
      [assetWriterInput markAsFinished]; 
      [assetWriter finishWriting]; 
      [assetReader cancelReading]; 
      [assetReader release]; 
      [assetReaderOutput release]; 
      [assetWriter release]; 
      [assetWriterInput release]; 
      break; 
     } 
    } 
} ]; 

하지만 오류가 있습니다 : 다음은 내 코드입니다 - [AVAssetWriterInput appendSampleBuffer이 :] 입력 버퍼는 리니어 PCM 포맷시에 있어야합니다 outputSettings가 '030이 아님'

나는 걸릴 methord를 물어보고 싶은가? PCM 형식 (.wav)으로 만들면 잘되지만 크기가 너무 큽니다. 오류를 해결하는 방법은 무엇입니까? .wav를 코드로 .aac 파일로 변환하는 방법은 무엇입니까? ! 다음 사용자 지정 설정을

+1

는이에 대한 해결책을 찾았나요? – Baza207

답변

1

시도 초기화 AVAssetReaderOutput :

NSDictionary *settings = 
    [NSDictionary dictionaryWithObjectsAndKeys: 
    [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey, 
    [NSNumber numberWithFloat:44100.0], AVSampleRateKey, 
    [NSNumber numberWithInt:16], AVLinearPCMBitDepthKey, 
    [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved, 
    [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey, 
    [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey, 
    nil]; 
관련 문제