iOS处理音频过程中有时候需要不同格式的音频进行转换,最近需要将m4a格式的音频转换成wav,在网上搜索之后代码整理如下:

- (void)convetM4aToWav:(NSURL *)originalUrl  destUrl:(NSURL *)destUrl {    
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:originalUrl options:nil]; //读取原始文件信息
NSError *error = nil;
AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:songAsset error:&error];
if (error) {
NSLog (@"error: %@", error);
return;
}
AVAssetReaderOutput *assetReaderOutput = [AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks audioSettings: nil];
if (![assetReader canAddOutput:assetReaderOutput]) {
NSLog (@"can't add reader output... die!");
return;
}
[assetReader addOutput:assetReaderOutput];

AVAssetWriter *assetWriter = [AVAssetWriter assetWriterWithURL:destUrl fileType:AVFileTypeCoreAudioFormat error:&error];
if (error) {
NSLog (@"error: %@", error);
return;
}
AudioChannelLayout channelLayout;
memset(&channelLayout, 0, sizeof(AudioChannelLayout));
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;

NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey, [NSNumber numberWithFloat:16000.0], AVSampleRateKey, [NSNumber numberWithInt:2], AVNumberOfChannelsKey, [NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey, [NSNumber numberWithInt:16], AVLinearPCMBitDepthKey, [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved, [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey, [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey, nil]; AVAssetWriterInput *assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:outputSettings];
if ([assetWriter canAddInput:assetWriterInput]) {
[assetWriter addInput:assetWriterInput];
} else {
NSLog (@"can't add asset writer input... die!");
return;
}
assetWriterInput.expectsMediaDataInRealTime = NO;
[assetWriter startWriting];
[assetReader startReading];
AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];
CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);
[assetWriter startSessionAtSourceTime:startTime];
__block UInt64 convertedByteCount = 0;
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];

NSLog (@"appended a buffer (%zu bytes)", CMSampleBufferGetTotalSampleSize (nextBuffer));
convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer);
} else {
[assetWriterInput markAsFinished];
[assetWriter finishWritingWithCompletionHandler:^{
}];
[assetReader cancelReading];

NSDictionary *outputFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[destUrl path] error:nil];
NSLog (@"FlyElephant %lld",[outputFileAttributes fileSize]);

break;
}
}
}];
}