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 ...
随机推荐
- C++ 宏定义与常量
原文: http://blog.csdn.net/t894690230/article/details/50605021 前言:突然想起很久之前上课时被问及C++ 宏定义与常量的区别,仔细了想了想,并 ...
- SODBASE CEP学习(四)续:类SQL语言EPL与Storm或jStorm集成-使用分布式缓存
流式计算在一些情况下会用到分布式缓存,从而实现(1)想把统计或计算结果保存在分布缓存中.供其他模块或其他系统调用. (2)某一滑动时间窗体上计数.比如实时统计1小时每一个Cookie的訪问量.实时统计 ...
- Android 最新控件 Toolbar
之前Android的ActionBar好像做项目从没用过.除了google自己,并没有多少人用,究其原因,主要是由于ActionBar不够灵活,不可以随心所欲的定制,后来Goole也发现了这一点,然后 ...
- 芯片史称:“长平之战”----Intel的东进与ARM的西征(3)--人生如戏,全靠演技
http://www.36kr.com/p/177143.html 从 2003 年到 2008 年,处理器双雄 Intel 和 AMD 在 64 位 CPU 领域展开了一场长达五年,极为惨烈的科技战 ...
- ditaa - 把ascii图形转成图片
ditaa ditaa是一个把ascii图形转成图片的工具. 在查看zguide时看到这个文档是用gitdown生成的.zguide文档格式排版非常不错,以后要抽时间好好学习一下. 每章写一个txt文 ...
- Jquery-easyui的默认图标的使用,以及如何添加自己想要的图标
easyui的默认图标有以下这些: .icon-blank{ background:url('icons/blank.gif') no-repeat; } .icon-add{ background: ...
- Android GUI系统学习1:Gralloc
Gralloc模块是从Android Eclair(android 2.1)開始增加的一个HAL模块,Gralloc的含义为是Graphics Alloc(图形分配).他对上为libui提供服务,为其 ...
- ios 短音效的使用
1.通用短音效ID的获取 #import <Foundation/Foundation.h> @interface MJAudioTool : NSObject /** * 播放音效 * ...
- Jmeter性能测试-GC相关
1.GC相关 HotSpot虚拟机将其物理上划分为两个–新生代(young generation)和老年代(old generation).新生代(Young generation): 绝大多数最新被 ...
- YTU 2453: 我想有套北京的房
2453: 我想有套北京的房 时间限制: 1 Sec 内存限制: 128 MB 提交: 796 解决: 289 题目描述 小原是一个软件工程师,名叫原黛玛,他在北京工作.现在有一套房子,价格200 ...