iOS中音频的录制与播放(本地音频文件的播放)

iOS功能开发涉及到音频处理时,最常见的时进行录音,以及音频文件的播放、停止播放等的操作。在开发中还要避免同一个音频文件,或不同音频文件之间的处理,比如说正在播放A音频时,可以停止播放A音频,也可以播放B音频时,停止播放A音频。在我的封装类中,已经对这方面做了处理。

Demo下载地址

音频开发注意事项

1、录音功能主要使用到"AVAudioRecorder"类

2、音频播放处理功能主要使用到"AVAudioPlayer"类

3、通过NSTimer处理音量显示

4、注意添加framework(AVFoundation.framework、AudioToolbox.framework)

5、只可以用来播放本地音频文件,即使是网络音频也是先下载到本地,然后再进行播放

1 主要代码

[objc] view plain copy
 
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface AudioRecorder : NSObject  
  4.   
  5. #pragma mark - 录音  
  6.   
  7. /// 实例化单例  
  8. + (AudioRecorder *)shareManager;  
  9.   
  10. #pragma mark - 音频处理-录音  
  11.   
  12. /// 开始录音  
  13. - (void)audioRecorderStartWithFilePath:(NSString *)filePath;  
  14.   
  15. /// 停止录音  
  16. - (void)audioRecorderStop;  
  17.   
  18. /// 录音时长  
  19. - (NSTimeInterval)durationAudioRecorderWithFilePath:(NSString *)filePath;  
  20.   
  21. #pragma mark - 音频处理-播放/停止  
  22.   
  23. /// 音频开始播放或停止  
  24. - (void)audioPlayWithFilePath:(NSString *)filePath;  
  25.   
  26. /// 音频播放停止  
  27. - (void)audioStop;  
  28.   
  29. @end  
      1. #import "AudioRecorder.h"  
      2.   
      3. // 导入录音头文件(注意添加framework:AVFoundation.framework、AudioToolbox.framework)  
      4. #import <AudioToolbox/AudioToolbox.h>  
      5. #import <AVFoundation/AVFoundation.h>  
      6. #import "AppDelegate.h"  
      7.   
      8. @interface AudioRecorder () <AVAudioRecorderDelegate>  
      9.   
      10. @property (nonatomic, strong) NSTimer *audioRecorderTimer;               // 录音音量计时器  
      11. @property (nonatomic, strong) NSMutableDictionary *audioRecorderSetting; // 录音设置  
      12. @property (nonatomic, strong) AVAudioRecorder *audioRecorder;            // 录音  
      13. @property (nonatomic, strong) AVAudioPlayer *audioPlayer;                // 播放  
      14. @property (nonatomic, assign) double audioRecorderTime;                  // 录音时长  
      15. @property (nonatomic, strong) UIView *imgView;                           // 录音音量图像父视图  
      16. @property (nonatomic, strong) UIImageView *audioRecorderVoiceImgView;    // 录音音量图像  
      17.   
      18. @end  
      19.   
      20. @implementation AudioRecorder  
      21.   
      22. #pragma mark - 实例化  
      23.   
      24. - (instancetype)init  
      25. {  
      26.     self = [super init];  
      27.       
      28.     if (self)  
      29.     {  
      30.         // 参数设置 格式、采样率、录音通道、线性采样位数、录音质量  
      31.         self.audioRecorderSetting = [NSMutableDictionary dictionary];  
      32.         [self.audioRecorderSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];  
      33.         [self.audioRecorderSetting setValue:[NSNumber numberWithInt:11025] forKey:AVSampleRateKey];  
      34.         [self.audioRecorderSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];  
      35.         [self.audioRecorderSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];  
      36.         [self.audioRecorderSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];  
      37.     }  
      38.       
      39.     return self;  
      40. }  
      41.   
      42. /// 录音单例  
      43. + (AudioRecorder *)shareManager  
      44. {  
      45.     static AudioRecorder *staticAudioRecorde;  
      46.     static dispatch_once_t once;  
      47.     dispatch_once(&once, ^{  
      48.         staticAudioRecorde = [[self alloc] init];  
      49.     });  
      50.       
      51.     return staticAudioRecorde;  
      52. }  
      53.   
      54. // 内存释放  
      55. - (void)dealloc  
      56. {  
      57.     // 内存释放前先停止录音,或音频播放  
      58.     [self audioStop];  
      59.     [self audioRecorderStop];  
      60.       
      61.     // 内存释放  
      62.     if (self.audioRecorderTime)  
      63.     {  
      64.         [self.audioRecorderTimer invalidate];  
      65.         self.audioRecorderTimer = nil;  
      66.     }  
      67.       
      68.     if (self.audioRecorderSetting)  
      69.     {  
      70.         self.audioRecorderSetting = nil;  
      71.     }  
      72.       
      73.     if (self.audioRecorder)  
      74.     {  
      75.         self.audioRecorder = nil;  
      76.     }  
      77.       
      78.     if (self.audioPlayer)  
      79.     {  
      80.         self.audioPlayer = nil;  
      81.     }  
      82.       
      83.     if (self.imgView)  
      84.     {  
      85.         self.imgView = nil;  
      86.     }  
      87.       
      88.     if (self.audioRecorderVoiceImgView)  
      89.     {  
      90.         self.audioRecorderVoiceImgView = nil;  
      91.     }  
      92. }  
      93.   
      94. #pragma mark - 音频处理-录音  
      95.   
      96. /// 开始录音  
      97. - (void)audioRecorderStartWithFilePath:(NSString *)filePath  
      98. {  
      99.     // 生成录音文件  
      100.     NSURL *urlAudioRecorder = [NSURL fileURLWithPath:filePath];  
      101.     self.audioRecorder = [[AVAudioRecorder alloc] initWithURL:urlAudioRecorder settings:self.audioRecorderSetting error:nil];  
      102.       
      103.     // 开启音量检测  
      104.     [self.audioRecorder setMeteringEnabled:YES];  
      105.     [self.audioRecorder setDelegate:self];  
      106.       
      107.     if (self.audioRecorder)  
      108.     {  
      109.         // 录音时设置audioSession属性,否则不兼容Ios7  
      110.         AVAudioSession *recordSession = [AVAudioSession sharedInstance];  
      111.         [recordSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];  
      112.         [recordSession setActive:YES error:nil];  
      113.           
      114.         if ([self.audioRecorder prepareToRecord])  
      115.         {  
      116.             [self.audioRecorder record];  
      117.               
      118.             //录音音量显示 75*111  
      119.             AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;  
      120.             UIView *view = [delegate window];  
      121.               
      122.             self.imgView = [[UIView alloc] initWithFrame:CGRectMake((view.frame.size.width - 120) / 2, (view.frame.size.height - 120) / 2, 120, 120)];  
      123.             [view addSubview:self.imgView];  
      124.             [self.imgView.layer setCornerRadius:10.0];  
      125.             [self.imgView.layer setBackgroundColor:[UIColor blackColor].CGColor];  
      126.             [self.imgView setAlpha:0.8];  
      127.               
      128.             self.audioRecorderVoiceImgView = [[UIImageView alloc] initWithFrame:CGRectMake((self.imgView.frame.size.width - 60) / 2, (self.imgView.frame.size.height - 660 * 111 / 75) / 2, 60, 660 * 111 / 75)];  
      129.             [self.imgView addSubview:self.audioRecorderVoiceImgView];  
      130.             [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_01.png"]];  
      131.             [self.audioRecorderVoiceImgView setBackgroundColor:[UIColor clearColor]];  
      132.   
      133.             // 设置定时检测  
      134.             self.audioRecorderTimer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(detectionVoice) userInfo:nil repeats:YES];  
      135.         }  
      136.     }  
      137. }  
      138.   
      139. /// 录音音量显示  
      140. - (void)detectionVoice  
      141. {  
      142.     // 刷新音量数据  
      143.     [self.audioRecorder updateMeters];  
      144.       
      145. //    // 获取音量的平均值  
      146. //    [self.audioRecorder averagePowerForChannel:0];  
      147. //    // 音量的最大值  
      148. //    [self.audioRecorder peakPowerForChannel:0];  
      149.       
      150.     double lowPassResults = pow(10, (0.05 * [self.audioRecorder peakPowerForChannel:0]));  
      151.      
      152.     if (0 < lowPassResults <= 0.06)  
      153.     {  
      154.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_01.png"]];  
      155.     }  
      156.     else if (0.06 < lowPassResults <= 0.13)  
      157.     {  
      158.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_02.png"]];  
      159.     }  
      160.     else if (0.13 < lowPassResults <= 0.20)  
      161.     {  
      162.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_03.png"]];  
      163.     }  
      164.     else if (0.20 < lowPassResults <= 0.27)  
      165.     {  
      166.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_04.png"]];  
      167.     }  
      168.     else if (0.27 < lowPassResults <= 0.34)  
      169.     {  
      170.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_05.png"]];  
      171.     }  
      172.     else if (0.34 < lowPassResults <= 0.41)  
      173.     {  
      174.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_06.png"]];  
      175.     }  
      176.     else if (0.41 < lowPassResults <= 0.48)  
      177.     {  
      178.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_07.png"]];  
      179.     }  
      180.     else if (0.48 < lowPassResults <= 0.55)  
      181.     {  
      182.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_08.png"]];  
      183.     }  
      184.     else if (0.55 < lowPassResults <= 0.62)  
      185.     {  
      186.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_09.png"]];  
      187.     }  
      188.     else if (0.62 < lowPassResults <= 0.69)  
      189.     {  
      190.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_10.png"]];  
      191.     }  
      192.     else if (0.69 < lowPassResults <= 0.76)  
      193.     {  
      194.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_11.png"]];  
      195.     }  
      196.     else if (0.76 < lowPassResults <= 0.83)  
      197.     {  
      198.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_12.png"]];  
      199.     }  
      200.     else if (0.83 < lowPassResults <= 0.9)  
      201.     {  
      202.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_13.png"]];  
      203.     }  
      204.     else  
      205.     {  
      206.         [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_14.png"]];  
      207.     }  
      208. }  
      209.   
      210. /// 停止录音  
      211. - (void)audioRecorderStop  
      212. {  
      213.     if (self.audioRecorder)  
      214.     {  
      215.         if ([self.audioRecorder isRecording])  
      216.         {  
      217.             // 获取录音时长  
      218.             self.audioRecorderTime = [self.audioRecorder currentTime];  
      219.             [self.audioRecorder stop];  
      220.          
      221.             // 停止录音后释放掉  
      222.             self.audioRecorder = nil;  
      223.         }  
      224.     }  
      225.       
      226.     // 移除音量图标  
      227.     if (self.audioRecorderVoiceImgView)  
      228.     {  
      229.         [self.audioRecorderVoiceImgView setHidden:YES];  
      230.         [self.audioRecorderVoiceImgView setImage:nil];  
      231.         [self.audioRecorderVoiceImgView removeFromSuperview];  
      232.         self.audioRecorderVoiceImgView = nil;  
      233.           
      234.         [self.imgView removeFromSuperview];  
      235.         self.imgView = nil;  
      236.     }  
      237.       
      238.     // 释放计时器  
      239.     [self.audioRecorderTimer invalidate];  
      240.     self.audioRecorderTimer = nil;  
      241. }  
      242.   
      243. /// 录音时长  
      244. - (NSTimeInterval)durationAudioRecorderWithFilePath:(NSString *)filePath  
      245. {  
      246.     NSURL *urlFile = [NSURL fileURLWithPath:filePath];  
      247.     self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:urlFile error:nil];  
      248.     NSTimeInterval time = self.audioPlayer.duration;  
      249.     self.audioPlayer = nil;  
      250.     return time;  
      251. }  
      252.   
      253. #pragma mark - 音频处理-播放/停止  
      254.   
      255. /// 音频开始播放或停止  
      256. - (void)audioPlayWithFilePath:(NSString *)filePath  
      257. {  
      258.     if (self.audioPlayer)  
      259.     {  
      260.         // 判断当前与下一个是否相同  
      261.         // 相同时,点击时要么播放,要么停止  
      262.         // 不相同时,点击时停止播放当前的,开始播放下一个  
      263.         NSString *currentStr = [self.audioPlayer.url relativeString];  
      264.           
      265.         /* 
      266.         NSString *currentName = [self getFileNameAndType:currentStr]; 
      267.         NSString *nextName = [self getFileNameAndType:filePath]; 
      268.          
      269.         if ([currentName isEqualToString:nextName]) 
      270.         { 
      271.             if ([self.audioPlayer isPlaying]) 
      272.             { 
      273.                 [self.audioPlayer stop]; 
      274.                 self.audioPlayer = nil; 
      275.             } 
      276.             else 
      277.             { 
      278.                 self.audioPlayer = nil; 
      279.                 [self audioPlayerPlay:filePath]; 
      280.             } 
      281.         } 
      282.         else 
      283.         { 
      284.             [self audioPlayerStop]; 
      285.             [self audioPlayerPlay:filePath]; 
      286.         } 
      287.          */  
      288.           
      289.         // currentStr包含字符"file://location/",通过判断filePath是否为currentPath的子串,是则相同,否则不同  
      290.         NSRange range = [currentStr rangeOfString:filePath];  
      291.         if (range.location != NSNotFound)  
      292.         {  
      293.             if ([self.audioPlayer isPlaying])  
      294.             {  
      295.                 [self.audioPlayer stop];  
      296.                 self.audioPlayer = nil;  
      297.             }  
      298.             else  
      299.             {  
      300.                 self.audioPlayer = nil;  
      301.                 [self audioPlayerPlay:filePath];  
      302.             }  
      303.         }  
      304.         else  
      305.         {  
      306.             [self audioPlayerStop];  
      307.             [self audioPlayerPlay:filePath];  
      308.         }  
      309.     }  
      310.     else  
      311.     {  
      312.         [self audioPlayerPlay:filePath];  
      313.     }  
      314.       
      315. }  
      316.   
      317. /// 音频播放停止  
      318. - (void)audioStop  
      319. {  
      320.     [self audioPlayerStop];  
      321. }  
      322.   
      323.   
      324. /// 音频播放器开始播放  
      325. - (void)audioPlayerPlay:(NSString *)filePath  
      326. {  
      327.     // 判断将要播放文件是否存在  
      328.     BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath];  
      329.     if (!isExist)  
      330.     {  
      331.         return;  
      332.     }  
      333.       
      334.     NSURL *urlFile = [NSURL fileURLWithPath:filePath];  
      335.     self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:urlFile error:nil];  
      336.     if (self.audioPlayer)  
      337.     {  
      338.         if ([self.audioPlayer prepareToPlay])  
      339.         {  
      340.             // 播放时,设置喇叭播放否则音量很小  
      341.             AVAudioSession *playSession = [AVAudioSession sharedInstance];  
      342.             [playSession setCategory:AVAudioSessionCategoryPlayback error:nil];  
      343.             [playSession setActive:YES error:nil];  
      344.               
      345.             [self.audioPlayer play];  
      346.         }  
      347.     }  
      348. }  
      349.   
      350. /// 音频播放器停止播放  
      351. - (void)audioPlayerStop  
      352. {  
      353.     if (self.audioPlayer)  
      354.     {  
      355.         if ([self.audioPlayer isPlaying])  
      356.         {  
      357.             [self.audioPlayer stop];  
      358.         }  
      359.           
      360.         self.audioPlayer = nil;  
      361.     }  
      362. }  
      363.   
      364. @end

      365. [objc] view plain copy
         
          1. 引入封装类头文件  
          2. #import "AudioRecorder.h"  
          3.   
          4. // 开始录音  
          5. - (void)startRecorder  
          6. {  
          7.     self.filePath = GetFilePathWithDate();  
          8.     [[AudioRecorder shareManager] audioRecorderStartWithFilePath:self.filePath];  
          9. }  
          10.   
          11. // 停止录音,并保存  
          12. - (void)saveRecorder  
          13. {  
          14.     [[AudioRecorder shareManager] audioRecorderStop];  
          15. }  
          16.   
          17. // 录音开始播放,或停止  
          18. - (void)playRecorder  
          19. {  
          20.     [[AudioRecorder shareManager] audioPlayWithFilePath:self.filePath];  
          21. }  
          22.   
          23. // 录音停止播放  
          24. - (void)stopRecorder  
          25. {  
          26.     [[AudioRecorder shareManager] audioStop];  
          27. }  
原文地址:https://www.cnblogs.com/edensyd/p/8483972.html