iOS中音频的录制与播放(本地音频文件的播放)
iOS功能开发涉及到音频处理时,最常见的时进行录音,以及音频文件的播放、停止播放等的操作。在开发中还要避免同一个音频文件,或不同音频文件之间的处理,比如说正在播放A音频时,可以停止播放A音频,也可以播放B音频时,停止播放A音频。在我的封装类中,已经对这方面做了处理。
音频开发注意事项
1、录音功能主要使用到"AVAudioRecorder"类
2、音频播放处理功能主要使用到"AVAudioPlayer"类
3、通过NSTimer处理音量显示
4、注意添加framework(AVFoundation.framework、AudioToolbox.framework)
5、只可以用来播放本地音频文件,即使是网络音频也是先下载到本地,然后再进行播放
1 主要代码
- #import <Foundation/Foundation.h>
- @interface AudioRecorder : NSObject
- #pragma mark - 录音
- /// 实例化单例
- + (AudioRecorder *)shareManager;
- #pragma mark - 音频处理-录音
- /// 开始录音
- - (void)audioRecorderStartWithFilePath:(NSString *)filePath;
- /// 停止录音
- - (void)audioRecorderStop;
- /// 录音时长
- - (NSTimeInterval)durationAudioRecorderWithFilePath:(NSString *)filePath;
- #pragma mark - 音频处理-播放/停止
- /// 音频开始播放或停止
- - (void)audioPlayWithFilePath:(NSString *)filePath;
- /// 音频播放停止
- - (void)audioStop;
- @end
- #import "AudioRecorder.h"
- // 导入录音头文件(注意添加framework:AVFoundation.framework、AudioToolbox.framework)
- #import <AudioToolbox/AudioToolbox.h>
- #import <AVFoundation/AVFoundation.h>
- #import "AppDelegate.h"
- @interface AudioRecorder () <AVAudioRecorderDelegate>
- @property (nonatomic, strong) NSTimer *audioRecorderTimer; // 录音音量计时器
- @property (nonatomic, strong) NSMutableDictionary *audioRecorderSetting; // 录音设置
- @property (nonatomic, strong) AVAudioRecorder *audioRecorder; // 录音
- @property (nonatomic, strong) AVAudioPlayer *audioPlayer; // 播放
- @property (nonatomic, assign) double audioRecorderTime; // 录音时长
- @property (nonatomic, strong) UIView *imgView; // 录音音量图像父视图
- @property (nonatomic, strong) UIImageView *audioRecorderVoiceImgView; // 录音音量图像
- @end
- @implementation AudioRecorder
- #pragma mark - 实例化
- - (instancetype)init
- {
- self = [super init];
- if (self)
- {
- // 参数设置 格式、采样率、录音通道、线性采样位数、录音质量
- self.audioRecorderSetting = [NSMutableDictionary dictionary];
- [self.audioRecorderSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
- [self.audioRecorderSetting setValue:[NSNumber numberWithInt:11025] forKey:AVSampleRateKey];
- [self.audioRecorderSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
- [self.audioRecorderSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
- [self.audioRecorderSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
- }
- return self;
- }
- /// 录音单例
- + (AudioRecorder *)shareManager
- {
- static AudioRecorder *staticAudioRecorde;
- static dispatch_once_t once;
- dispatch_once(&once, ^{
- staticAudioRecorde = [[self alloc] init];
- });
- return staticAudioRecorde;
- }
- // 内存释放
- - (void)dealloc
- {
- // 内存释放前先停止录音,或音频播放
- [self audioStop];
- [self audioRecorderStop];
- // 内存释放
- if (self.audioRecorderTime)
- {
- [self.audioRecorderTimer invalidate];
- self.audioRecorderTimer = nil;
- }
- if (self.audioRecorderSetting)
- {
- self.audioRecorderSetting = nil;
- }
- if (self.audioRecorder)
- {
- self.audioRecorder = nil;
- }
- if (self.audioPlayer)
- {
- self.audioPlayer = nil;
- }
- if (self.imgView)
- {
- self.imgView = nil;
- }
- if (self.audioRecorderVoiceImgView)
- {
- self.audioRecorderVoiceImgView = nil;
- }
- }
- #pragma mark - 音频处理-录音
- /// 开始录音
- - (void)audioRecorderStartWithFilePath:(NSString *)filePath
- {
- // 生成录音文件
- NSURL *urlAudioRecorder = [NSURL fileURLWithPath:filePath];
- self.audioRecorder = [[AVAudioRecorder alloc] initWithURL:urlAudioRecorder settings:self.audioRecorderSetting error:nil];
- // 开启音量检测
- [self.audioRecorder setMeteringEnabled:YES];
- [self.audioRecorder setDelegate:self];
- if (self.audioRecorder)
- {
- // 录音时设置audioSession属性,否则不兼容Ios7
- AVAudioSession *recordSession = [AVAudioSession sharedInstance];
- [recordSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
- [recordSession setActive:YES error:nil];
- if ([self.audioRecorder prepareToRecord])
- {
- [self.audioRecorder record];
- //录音音量显示 75*111
- AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
- UIView *view = [delegate window];
- self.imgView = [[UIView alloc] initWithFrame:CGRectMake((view.frame.size.width - 120) / 2, (view.frame.size.height - 120) / 2, 120, 120)];
- [view addSubview:self.imgView];
- [self.imgView.layer setCornerRadius:10.0];
- [self.imgView.layer setBackgroundColor:[UIColor blackColor].CGColor];
- [self.imgView setAlpha:0.8];
- 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)];
- [self.imgView addSubview:self.audioRecorderVoiceImgView];
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_01.png"]];
- [self.audioRecorderVoiceImgView setBackgroundColor:[UIColor clearColor]];
- // 设置定时检测
- self.audioRecorderTimer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(detectionVoice) userInfo:nil repeats:YES];
- }
- }
- }
- /// 录音音量显示
- - (void)detectionVoice
- {
- // 刷新音量数据
- [self.audioRecorder updateMeters];
- // // 获取音量的平均值
- // [self.audioRecorder averagePowerForChannel:0];
- // // 音量的最大值
- // [self.audioRecorder peakPowerForChannel:0];
- double lowPassResults = pow(10, (0.05 * [self.audioRecorder peakPowerForChannel:0]));
- if (0 < lowPassResults <= 0.06)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_01.png"]];
- }
- else if (0.06 < lowPassResults <= 0.13)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_02.png"]];
- }
- else if (0.13 < lowPassResults <= 0.20)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_03.png"]];
- }
- else if (0.20 < lowPassResults <= 0.27)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_04.png"]];
- }
- else if (0.27 < lowPassResults <= 0.34)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_05.png"]];
- }
- else if (0.34 < lowPassResults <= 0.41)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_06.png"]];
- }
- else if (0.41 < lowPassResults <= 0.48)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_07.png"]];
- }
- else if (0.48 < lowPassResults <= 0.55)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_08.png"]];
- }
- else if (0.55 < lowPassResults <= 0.62)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_09.png"]];
- }
- else if (0.62 < lowPassResults <= 0.69)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_10.png"]];
- }
- else if (0.69 < lowPassResults <= 0.76)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_11.png"]];
- }
- else if (0.76 < lowPassResults <= 0.83)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_12.png"]];
- }
- else if (0.83 < lowPassResults <= 0.9)
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_13.png"]];
- }
- else
- {
- [self.audioRecorderVoiceImgView setImage:[UIImage imageNamed:@"record_animate_14.png"]];
- }
- }
- /// 停止录音
- - (void)audioRecorderStop
- {
- if (self.audioRecorder)
- {
- if ([self.audioRecorder isRecording])
- {
- // 获取录音时长
- self.audioRecorderTime = [self.audioRecorder currentTime];
- [self.audioRecorder stop];
- // 停止录音后释放掉
- self.audioRecorder = nil;
- }
- }
- // 移除音量图标
- if (self.audioRecorderVoiceImgView)
- {
- [self.audioRecorderVoiceImgView setHidden:YES];
- [self.audioRecorderVoiceImgView setImage:nil];
- [self.audioRecorderVoiceImgView removeFromSuperview];
- self.audioRecorderVoiceImgView = nil;
- [self.imgView removeFromSuperview];
- self.imgView = nil;
- }
- // 释放计时器
- [self.audioRecorderTimer invalidate];
- self.audioRecorderTimer = nil;
- }
- /// 录音时长
- - (NSTimeInterval)durationAudioRecorderWithFilePath:(NSString *)filePath
- {
- NSURL *urlFile = [NSURL fileURLWithPath:filePath];
- self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:urlFile error:nil];
- NSTimeInterval time = self.audioPlayer.duration;
- self.audioPlayer = nil;
- return time;
- }
- #pragma mark - 音频处理-播放/停止
- /// 音频开始播放或停止
- - (void)audioPlayWithFilePath:(NSString *)filePath
- {
- if (self.audioPlayer)
- {
- // 判断当前与下一个是否相同
- // 相同时,点击时要么播放,要么停止
- // 不相同时,点击时停止播放当前的,开始播放下一个
- NSString *currentStr = [self.audioPlayer.url relativeString];
- /*
- NSString *currentName = [self getFileNameAndType:currentStr];
- NSString *nextName = [self getFileNameAndType:filePath];
- if ([currentName isEqualToString:nextName])
- {
- if ([self.audioPlayer isPlaying])
- {
- [self.audioPlayer stop];
- self.audioPlayer = nil;
- }
- else
- {
- self.audioPlayer = nil;
- [self audioPlayerPlay:filePath];
- }
- }
- else
- {
- [self audioPlayerStop];
- [self audioPlayerPlay:filePath];
- }
- */
- // currentStr包含字符"file://location/",通过判断filePath是否为currentPath的子串,是则相同,否则不同
- NSRange range = [currentStr rangeOfString:filePath];
- if (range.location != NSNotFound)
- {
- if ([self.audioPlayer isPlaying])
- {
- [self.audioPlayer stop];
- self.audioPlayer = nil;
- }
- else
- {
- self.audioPlayer = nil;
- [self audioPlayerPlay:filePath];
- }
- }
- else
- {
- [self audioPlayerStop];
- [self audioPlayerPlay:filePath];
- }
- }
- else
- {
- [self audioPlayerPlay:filePath];
- }
- }
- /// 音频播放停止
- - (void)audioStop
- {
- [self audioPlayerStop];
- }
- /// 音频播放器开始播放
- - (void)audioPlayerPlay:(NSString *)filePath
- {
- // 判断将要播放文件是否存在
- BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
- if (!isExist)
- {
- return;
- }
- NSURL *urlFile = [NSURL fileURLWithPath:filePath];
- self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:urlFile error:nil];
- if (self.audioPlayer)
- {
- if ([self.audioPlayer prepareToPlay])
- {
- // 播放时,设置喇叭播放否则音量很小
- AVAudioSession *playSession = [AVAudioSession sharedInstance];
- [playSession setCategory:AVAudioSessionCategoryPlayback error:nil];
- [playSession setActive:YES error:nil];
- [self.audioPlayer play];
- }
- }
- }
- /// 音频播放器停止播放
- - (void)audioPlayerStop
- {
- if (self.audioPlayer)
- {
- if ([self.audioPlayer isPlaying])
- {
- [self.audioPlayer stop];
- }
- self.audioPlayer = nil;
- }
- }
- @end
- 引入封装类头文件
- #import "AudioRecorder.h"
- // 开始录音
- - (void)startRecorder
- {
- self.filePath = GetFilePathWithDate();
- [[AudioRecorder shareManager] audioRecorderStartWithFilePath:self.filePath];
- }
- // 停止录音,并保存
- - (void)saveRecorder
- {
- [[AudioRecorder shareManager] audioRecorderStop];
- }
- // 录音开始播放,或停止
- - (void)playRecorder
- {
- [[AudioRecorder shareManager] audioPlayWithFilePath:self.filePath];
- }
- // 录音停止播放
- - (void)stopRecorder
- {
- [[AudioRecorder shareManager] audioStop];
- }
iOS中音频的录制与播放(本地音频文件的播放)的更多相关文章
- iOS从零开始学习直播之音频1.播放本地音频文件
现在直播越来越火,俨然已经成为了下一个红海.作为一个资深码农(我只喜欢这样称呼自己,不喜欢别人这样称呼我),我必须赶上时代的潮流,开始研究视频直播.发现视屏直播类的文章上来就讲拉流.推流.采集.美 ...
- iOS Dev (20) 用 AVAudioPlayer 播放一个本地音频文件
iOS Dev (20) 用 AVAudioPlayer 播放一个本地音频文件 作者:CSDN 大锐哥 博客:http://blog.csdn.net/prevention 步骤 第一步:在 Proj ...
- iOS Dev (21) 用 AVPlayer 播放一个本地音频文件
iOS Dev (21) 用 AVPlayer 播放一个本地音频文件 作者:CSDN 大锐哥 博客:http://blog.csdn.net/prevention 前言 这篇文章与上一篇极其相似,要注 ...
- AVAudioPlayer播放本地音频
AVAudioPlayer苹果官方上说一般用于播放本地音频,不能用于播放网络上的音频. 具体的代码:先导入 #import <AVFoundation/AVFoundation.h> // ...
- 用 Qt 的 QAudioOutput 类播放 WAV 音频文件
用 Qt 的 QAudioOutput 类播放 WAV 音频文件 最近有一个项目,需要同时控制 4 个声卡播放不同的声音,声音文件很简单就是没有任何压缩的 wav 文件. 如果只是播放 wav 文件, ...
- AVAudioPlayer播放在线音频文件
AVAudioPlayer播放在线音频文件 一:原里: AVAudioPlayer是不支持播放在线音频的,但是AVAudioPlayer有一个 initWithData的方法:我们可以把在线音频转换为 ...
- iOS 设置铃声---加载音乐和音频然后进行播放
在有些应用中需要用到背景音乐和音效,那在程序中是这么实现的. 1.首先加载背景音乐需要用到AVFoundation框架 2.音乐资源都是在包里的,所以需要获得包路径,涉及方法- (id)initWit ...
- Android MediaPlayer播放一般音频与SoundPool播放短促的音效
[1]使用MediaPlayer实现一般的音频播放 MediaPlayer播放通常的音频文件 MediaPlayer mediaPlayer = new MediaPlayer(); if (medi ...
- 使用WaveOut API播放WAV音频文件(解决卡顿)
虽然waveout已经过时,但是其api简单,有些时候也还是需要用到. 其实还是自己上msdn查阅相应api最靠谱,waveout也有提供暂停.设置音量等接口的,这里给个链接,需要的可以自己查找: h ...
随机推荐
- BZOJ 题目1036: [ZJOI2008]树的统计Count(Link Cut Tree,改动点权求两个最大值和最大值)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 8421 Solved: 3439 [Submi ...
- 基于 orange(nginx+openresty) + docker 实现微服务 网关功能
摘要 基于 orange(nginx+openresty) + docker 实现微服务 网关功能 ;以实现 docker 独立容器 来跑 独立语言独立环境 在 同一个授权下 运行相关组合程序..年初 ...
- struts开发<在eclipse中配置struts. 一>
1.获取struts的jar包 1.1首先在http://struts.apache.org/download.cgi#struts23163这里下载 struts的文件包(选择struts-2.3. ...
- vc常用类总结(转载)
常用类 CRect:用来表示矩形的类,拥有四个成员变量:top left bottom right.分别表是左上角和右下角的坐标.可以通过以下的方法构造: CRect( int l, int t, i ...
- android学习笔记三--Activity 布局
1.线性布局 标签 :<LinearLayout></LinearLayout> 方向:android:orientation, 垂直:vertical 水平:Horizont ...
- 【转载】.NET Remoting学习笔记(三)信道
目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 参考:♂风车车.Net .NET Framework ...
- CSP:使用CryptoAPI解码X509证书内容
微软的CryptoAPI提供了一套解码X509证书的函数,一个X509证书解码之后,得到一个PCCERT_CONTEXT类型的结构体指针. 通过该结构体,我们就能够获取想要的证书项和属性等. X509 ...
- 用python编写的简易端口扫描器
#coding = utf-8 ''' python 3.4 通过简单的TCP端口连接来判断指定IP是否开放了指定端口. ''' import socket import optparse impor ...
- jquery easyui:EasyUI Treegrid 树形网格
用jquery easyui 的 Treegrid 树形网格 进行数据展示,不过官网的API 和 demo 让我愣了好久,摸索后整理出来供大家详细参看. jquery easyui 官网:http:/ ...
- CString转换成char *字符串问题
buf = (LPSTR)(LPCTSTR)str; ==> buf 显示的是第一个字符 strcpy(pNumber,strNumber); ==> e ...