简体   繁体   English

如何使用AVAssetReader和AVAssetWriter创建AAC文件?

[英]How can I use AVAssetReader and AVAssetWriter to create a AAC file?

everyone! 大家! I'm dealing with an app.It can record audio file and mail to others.The audio file is saved as (.aac)file.Then I want to continue recording which I've already saved as .aac file.So I used AVAssetReader and AVAssetWriter to make it.but I failed! 我正在处理一个应用程序。它可以录制音频文件和邮件给其他人。音频文件保存为(.aac)文件。然后我想继续录制我已经保存为.aac文件。所以我用过AVAssetReader和AVAssetWriter使它成为现实。但我失败了! The following is my code: 以下是我的代码:

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;
        }
    }
} ];

I just want to record another file and then append the later to the previous,but there is an error:-[AVAssetWriterInput appendSampleBuffer:] Input buffer must be in linear PCM format when outputSettings is not nil' 我只想记录另一个文件,然后将后一个文件附加到上一个文件,但是有一个错误: - [AVAssetWriterInput appendSampleBuffer:]当outputSettings不是nil时,输入缓冲区必须是线性PCM格式

I want to ask the methord I take is right? 我想问一下我采取的方法是对的吗? If I make it to PCM format(the .wav)it dong well ,but the size of the recorded file is too big.How to solve the error mentioned.And how can I convert .wav to .aac file by code?Help! 如果我使它成为PCM格式(.wav)它很好,但记录文件的大小太大。如何解决提到的错误。如何通过代码将.wav转换为.aac文件?帮助!

Try init AVAssetReaderOutput with following custom settings: 尝试使用以下自定义设置初始化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];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM