123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- //
- // M4aToPcmHelper.m
- // TianyiProSwift
- //
- // Created by i2国际私塾 on 2017/3/21.
- // Copyright © 2017年 Chengdu Aitu Education Technology Ltd. All rights reserved.
- //
- #import "M4aToPcmHelper.h"
- #import <AudioToolbox/AudioToolbox.h>
- #import <AVFoundation/AVFoundation.h>
- #import <MediaPlayer/MediaPlayer.h>
- @implementation M4aToPcmHelper
- /**
- * 根据m4a音频转化成pcm格式的音频
- *
- * @param urlStr 音频路径
- *
- * @return pcm格式的[Int16]的Data
- */
- + (NSURL *) 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 = YES;
-
- [assetWriter startWriting];
- [assetReader startReading];
-
- AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];
- CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);
- [assetWriter startSessionAtSourceTime: kCMTimeZero];
-
- // while (assetWriterInput.readyForMoreMediaData == FALSE) {
- // NSDate *maxDate = [NSDate dateWithTimeIntervalSinceNow:0.1];
- // [[NSRunLoop currentRunLoop] runUntilDate:maxDate];
- // NSLog(@"等待几秒试试");
- // }
- // __block UInt64 convertedByteCount = 0;
- // BOOL isFinish = false;
-
- CMSampleBufferRef sample = [assetReaderOutput copyNextSampleBuffer];
- while(sample != NULL)
- {
- while (TRUE) {
- if ([assetWriterInput isReadyForMoreMediaData]) {
- [assetWriterInput appendSampleBuffer:sample];
- break;
- }
- }
- CFRelease( sample );
- sample = [assetReaderOutput copyNextSampleBuffer];
- }
-
- // while (assetWriterInput.readyForMoreMediaData) {
- // NSLog(@"ready for");
- // CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer];
- // if (nextBuffer) {
- // // append buffer
- // [assetWriterInput appendSampleBuffer: nextBuffer];
- // convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer);
- //
- // }
- // else{
- // // done!
- // [assetWriterInput markAsFinished];
- // [assetWriter finishWritingWithCompletionHandler:^{
- // }];
- // [assetReader cancelReading];
- // isFinish = true;
- //
- // return exportURL;
- // }
- // }
- [assetWriterInput markAsFinished];
- [assetWriter finishWritingWithCompletionHandler:^{
- }];
- [assetReader cancelReading];
- return exportURL;
- }
- @end
|