// // M4aToPcmHelper.m // TianyiProSwift // // Created by i2国际私塾 on 2017/3/21. // Copyright © 2017年 Chengdu Aitu Education Technology Ltd. All rights reserved. // #import "M4aToPcmHelper.h" #import #import #import @implementation M4aToPcmHelper /** * 根据m4a音频转化成pcm格式的音频 * * @param urlStr 音频路径 * * @return pcm格式的[Int16]的Data */ + (NSData *) M4aToPcmWithUrl:(NSURL *)url { NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectoryPath = [dirs objectAtIndex:0]; NSString *exportPath = [documentsDirectoryPath stringByAppendingPathComponent:@"pcmData.pcm"]; if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) { [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil]; } NSURL *exportURL = [NSURL fileURLWithPath:exportPath]; AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:url options:nil]; NSError *assetError = nil; AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:songAsset error:&assetError]; if (assetError) { NSLog (@"error: %@", assetError); return nil; } AVAssetWriter *assetWriter = [AVAssetWriter assetWriterWithURL:exportURL fileType:AVFileTypeCoreAudioFormat error:&assetError]; AVAssetReaderOutput *assetReaderOutput = [AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks audioSettings: nil]; [assetReader addOutput: assetReaderOutput]; if (assetError) { NSLog (@"error: %@", assetError); return nil; } AudioChannelLayout channelLayout; memset(&channelLayout, 0, sizeof(AudioChannelLayout)); channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey, [NSNumber numberWithFloat:8000.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 nil; } 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; while (assetWriterInput.readyForMoreMediaData) { CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer]; if (nextBuffer) { // append buffer [assetWriterInput appendSampleBuffer: nextBuffer]; convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer); } else { // done! [assetWriterInput markAsFinished]; [assetWriter finishWritingWithCompletionHandler:^{ }]; [assetReader cancelReading]; return [NSData dataWithContentsOfURL:exportURL]; break; } } return [NSData dataWithContentsOfURL:exportURL]; } @end