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

Demo下载地址

音频开发注意事项

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

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

3、通过NSTimer处理音量显示

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

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

1 主要代码

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

iOS中音频的录制与播放(本地音频文件的播放)的更多相关文章

  1. iOS从零开始学习直播之音频1.播放本地音频文件

      现在直播越来越火,俨然已经成为了下一个红海.作为一个资深码农(我只喜欢这样称呼自己,不喜欢别人这样称呼我),我必须赶上时代的潮流,开始研究视频直播.发现视屏直播类的文章上来就讲拉流.推流.采集.美 ...

  2. iOS Dev (20) 用 AVAudioPlayer 播放一个本地音频文件

    iOS Dev (20) 用 AVAudioPlayer 播放一个本地音频文件 作者:CSDN 大锐哥 博客:http://blog.csdn.net/prevention 步骤 第一步:在 Proj ...

  3. iOS Dev (21) 用 AVPlayer 播放一个本地音频文件

    iOS Dev (21) 用 AVPlayer 播放一个本地音频文件 作者:CSDN 大锐哥 博客:http://blog.csdn.net/prevention 前言 这篇文章与上一篇极其相似,要注 ...

  4. AVAudioPlayer播放本地音频

    AVAudioPlayer苹果官方上说一般用于播放本地音频,不能用于播放网络上的音频. 具体的代码:先导入 #import <AVFoundation/AVFoundation.h> // ...

  5. 用 Qt 的 QAudioOutput 类播放 WAV 音频文件

    用 Qt 的 QAudioOutput 类播放 WAV 音频文件 最近有一个项目,需要同时控制 4 个声卡播放不同的声音,声音文件很简单就是没有任何压缩的 wav 文件. 如果只是播放 wav 文件, ...

  6. AVAudioPlayer播放在线音频文件

    AVAudioPlayer播放在线音频文件 一:原里: AVAudioPlayer是不支持播放在线音频的,但是AVAudioPlayer有一个 initWithData的方法:我们可以把在线音频转换为 ...

  7. iOS 设置铃声---加载音乐和音频然后进行播放

    在有些应用中需要用到背景音乐和音效,那在程序中是这么实现的. 1.首先加载背景音乐需要用到AVFoundation框架 2.音乐资源都是在包里的,所以需要获得包路径,涉及方法- (id)initWit ...

  8. Android MediaPlayer播放一般音频与SoundPool播放短促的音效

    [1]使用MediaPlayer实现一般的音频播放 MediaPlayer播放通常的音频文件 MediaPlayer mediaPlayer = new MediaPlayer(); if (medi ...

  9. 使用WaveOut API播放WAV音频文件(解决卡顿)

    虽然waveout已经过时,但是其api简单,有些时候也还是需要用到. 其实还是自己上msdn查阅相应api最靠谱,waveout也有提供暂停.设置音量等接口的,这里给个链接,需要的可以自己查找: h ...

随机推荐

  1. BUPT复试专题—串查找(?)

    https://www.nowcoder.com/practice/a988eda518f242c29009f8620f654ede?tpId=67&tqId=29642&rp=0&a ...

  2. (六)Unity5.0新特性------新动画功能

     unity 5.0 中的新动画功能 这里是你能够期待的新动画功能高速概述 ! State Machine Behaviours状态机行为 在Unity 5 中,你会能够将StateMachine ...

  3. 【手势交互】4. Kinect for XBox

    "You are the Controller",Kinect for Xbox的广告词.明白说明了Kinect体感的交互方式.作为一款集成了诸多先进视觉技术的自然交互设备,Kin ...

  4. python socket初探

    先看一段代码 import socket import sys import re def getServerContent(url): host_ip = socket.gethostbyname( ...

  5. appium支持的版本

    appium 支持4.2以上的版本 2.3-4.1的版本的支持通过Selendroid实现

  6. SenTestingKit.framework的报错!

    本文转载至http://www.cocoachina.com/ask/questions/show/106912 ld: building for iOS Simulator, but linking ...

  7. uCos临界区保护

    定义有三种method,stm32f4采用的是第三种:将当前中断的状态标志保存在一个局部变量cpu_sr中,然后再关闭中断.cpu_sr是一个局部变量,存在于所有需要关中断的函数中.注意到,在使用了该 ...

  8. Vue中 key keep-alive

    keep-alive key <!DOCTYPE html> <html> <head> <title></title> <scrip ...

  9. RedisCluster集群原理

    主从复制,数据值每个服务器都存了. 针对redis集群的解决方案, 连接这个集群,不用在乎Master了 6台redis 1.why use Redis? 减轻数据库访问压力 2.持久化 RDB(间隔 ...

  10. File.Copy的时候Could not find a part of the path

    https://developercommunity.visualstudio.com/content/problem/378265/filecopy-did-not-throw-the-correc ...