M4aToPcmHelper.m 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //
  2. // M4aToPcmHelper.m
  3. // TianyiProSwift
  4. //
  5. // Created by i2国际私塾 on 2017/3/21.
  6. // Copyright © 2017年 Chengdu Aitu Education Technology Ltd. All rights reserved.
  7. //
  8. #import "M4aToPcmHelper.h"
  9. #import <AudioToolbox/AudioToolbox.h>
  10. #import <AVFoundation/AVFoundation.h>
  11. #import <MediaPlayer/MediaPlayer.h>
  12. @implementation M4aToPcmHelper
  13. /**
  14. * 根据m4a音频转化成pcm格式的音频
  15. *
  16. * @param urlStr 音频路径
  17. *
  18. * @return pcm格式的[Int16]的Data
  19. */
  20. + (NSData *) M4aToPcmWithUrl:(NSURL *)url {
  21. NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  22. NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
  23. NSString *exportPath = [documentsDirectoryPath stringByAppendingPathComponent:@"pcmData.pcm"];
  24. if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {
  25. [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
  26. }
  27. NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
  28. AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:url options:nil];
  29. NSError *assetError = nil;
  30. AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:songAsset
  31. error:&assetError];
  32. if (assetError) {
  33. NSLog (@"error: %@", assetError);
  34. return nil;
  35. }
  36. AVAssetWriter *assetWriter = [AVAssetWriter assetWriterWithURL:exportURL
  37. fileType:AVFileTypeCoreAudioFormat
  38. error:&assetError];
  39. AVAssetReaderOutput *assetReaderOutput = [AVAssetReaderAudioMixOutput
  40. assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks
  41. audioSettings: nil];
  42. [assetReader addOutput: assetReaderOutput];
  43. if (assetError) {
  44. NSLog (@"error: %@", assetError);
  45. return nil;
  46. }
  47. AudioChannelLayout channelLayout;
  48. memset(&channelLayout, 0, sizeof(AudioChannelLayout));
  49. channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
  50. NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
  51. [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
  52. [NSNumber numberWithFloat:8000.0], AVSampleRateKey,
  53. [NSNumber numberWithInt:2], AVNumberOfChannelsKey,
  54. [NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey,
  55. [NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
  56. [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
  57. [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
  58. [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
  59. nil];
  60. AVAssetWriterInput *assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
  61. outputSettings:outputSettings];
  62. if ([assetWriter canAddInput:assetWriterInput]) {
  63. [assetWriter addInput:assetWriterInput];
  64. } else {
  65. NSLog (@"can't add asset writer input... die!");
  66. return nil;
  67. }
  68. assetWriterInput.expectsMediaDataInRealTime = NO;
  69. [assetWriter startWriting];
  70. [assetReader startReading];
  71. AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];
  72. CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);
  73. [assetWriter startSessionAtSourceTime: startTime];
  74. __block UInt64 convertedByteCount = 0;
  75. while (assetWriterInput.readyForMoreMediaData) {
  76. CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer];
  77. if (nextBuffer) {
  78. // append buffer
  79. [assetWriterInput appendSampleBuffer: nextBuffer];
  80. convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer);
  81. } else {
  82. // done!
  83. [assetWriterInput markAsFinished];
  84. [assetWriter finishWritingWithCompletionHandler:^{
  85. }];
  86. [assetReader cancelReading];
  87. return [NSData dataWithContentsOfURL:exportURL];
  88. break;
  89. }
  90. }
  91. return [NSData dataWithContentsOfURL:exportURL];
  92. }
  93. @end