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 ...
随机推荐
- 【HDOJ 5399】Too Simple
pid=5399">[HDOJ 5399]Too Simple 函数映射问题 给出m函数 里面有0~m个函数未知(-1) 问要求最后1~n分别相应仍映射1~n 有几种函数写法(已给定的 ...
- redux 及 相关插件 项目实战
目录结构 +-- app | +-- actions | +-- index.js | +-- components | +-- content.js | +-- footer.js | +-- se ...
- C#中使用byte[]数据,生成Bitmap
/// <summary> /// 使用byte[]数据,生成256色灰度 BMP 位图 /// </summary> /// <param name="ori ...
- hdu3076ssworld VS DDD 概率dp
//ssworld VS DDD 两个人有血量值 hp1 , hp2 //两人掷骰子得到每一点的概率已知 //ssword赢的概率 //dp[i][j] 表示有第一个人血量为i.第二个人的血量为j ...
- jQuery操作得到DOM元素
jQuery再DOM操作方面提供了一些函数及其用法,这里就对DOM元素的包装简单说明一下,怎样使用会了,对其它方法也能灵活的使用.以下是一个小样例及其效果图. 代码例如以下: <html xml ...
- CustomView
https://github.com/eltld/CustomView
- 6. IO复用:select 和 poll
select #include <sys/select.h> #include <sys/time.h> int select(int maxfdp1, fd_set *rea ...
- bootstrap-Table服务端分页,获取到的数据怎么再页面的表格里显示
<table class="table table-hover" id="userTable" > <thead> <tr> ...
- POJ 1183 反正切函数的应用(数学代换,基本不等式)
题目链接:http://poj.org/problem?id=1183 这道题关键在于数学式子的推导,由题目有1/a=(1/b+1/c)/(1-1/(b*c))---------->a=(b*c ...
- 模板方法模式-TemplateMethod
模板方法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的机构即可以重定义算法的某些特定步骤. 模板方法模式是通过吧不变形为搬移到超类,去除子类中的重复代码 ...