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 ...
随机推荐
- BUPT复试专题—串查找(?)
https://www.nowcoder.com/practice/a988eda518f242c29009f8620f654ede?tpId=67&tqId=29642&rp=0&a ...
- (六)Unity5.0新特性------新动画功能
unity 5.0 中的新动画功能 这里是你能够期待的新动画功能高速概述 ! State Machine Behaviours状态机行为 在Unity 5 中,你会能够将StateMachine ...
- 【手势交互】4. Kinect for XBox
"You are the Controller",Kinect for Xbox的广告词.明白说明了Kinect体感的交互方式.作为一款集成了诸多先进视觉技术的自然交互设备,Kin ...
- python socket初探
先看一段代码 import socket import sys import re def getServerContent(url): host_ip = socket.gethostbyname( ...
- appium支持的版本
appium 支持4.2以上的版本 2.3-4.1的版本的支持通过Selendroid实现
- SenTestingKit.framework的报错!
本文转载至http://www.cocoachina.com/ask/questions/show/106912 ld: building for iOS Simulator, but linking ...
- uCos临界区保护
定义有三种method,stm32f4采用的是第三种:将当前中断的状态标志保存在一个局部变量cpu_sr中,然后再关闭中断.cpu_sr是一个局部变量,存在于所有需要关中断的函数中.注意到,在使用了该 ...
- Vue中 key keep-alive
keep-alive key <!DOCTYPE html> <html> <head> <title></title> <scrip ...
- RedisCluster集群原理
主从复制,数据值每个服务器都存了. 针对redis集群的解决方案, 连接这个集群,不用在乎Master了 6台redis 1.why use Redis? 减轻数据库访问压力 2.持久化 RDB(间隔 ...
- File.Copy的时候Could not find a part of the path
https://developercommunity.visualstudio.com/content/problem/378265/filecopy-did-not-throw-the-correc ...