AVAudioSession类从AVFoundation框架中引入, 每个IOS应用都有一个音频会话, 这个会话可以被AVAudioSession的sharedInstance类方法访问.
AVAudioSessionCategoryPlayAndRecord 这个类别中允许你的应用同时进行声音的播放和录制.当你的声音播放和录制开始后, 其他应用的声音播放将会停止,主UI界面会照常工作, 这时即使屏幕被锁定或者设备为静音模式,音频的播放都会继续.
demo写的异常粗糙, 以后再重新写一个
#import "ViewController.h"
#import "UIImage+Extension.h"
#import <AVFoundation/AVFoundation.h>
#define WIDTH [[UIScreen mainScreen] bounds].size.width
#define HEIGHT [[UIScreen mainScreen] bounds].size.height
@interface ViewController ()
// 录音名字
@property (nonatomic,copy) NSString *playName;
// 录音器
@property (nonatomic,strong) AVAudioRecorder *recorder;
// 播放器
@property (nonatomic,strong) AVAudioPlayer *player;
// 属性设置
@property (nonatomic,copy) NSDictionary *recorderSettingsDict;
// 声音标识
@property (nonatomic,copy) NSMutableArray *volumImages;
// 定时器
@property (nonatomic,strong) NSTimer *timer;
//
@property (nonatomic,assign) double lowPassResults;
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
// 创建button
UIButton *button = [[UIButtonalloc] initWithFrame:CGRectMake(30,HEIGHT*0.6,WIDTH-60, 40)];
[self.viewaddSubview:button];
[button setBackgroundImage:[UIImageresizedImageWithName:@"VoiceBtn_Black"]forState:UIControlStateNormal];
[button setBackgroundImage:[UIImageresizedImageWithName:@"VoiceBtn_BlackHL"]forState:UIControlStateHighlighted];
[button setTitle:@"发送新消息"forState:UIControlStateNormal];
[button setTitle:@"按住说话"forState:UIControlStateHighlighted];
[button setTitleColor:[UIColordarkGrayColor] forState:UIControlStateNormal];
button.titleLabel.font = [UIFontsystemFontOfSize:14];
[button addTarget:selfaction:@selector(holdDownButtonTouchDown)forControlEvents:UIControlEventTouchDown];
[button addTarget:selfaction:@selector(holdDownButtonTouchUpInside)forControlEvents:UIControlEventTouchUpInside];
[button addTarget:selfaction:@selector(holdDownDragOutside)forControlEvents:UIControlEventTouchDragExit];
UIButton *buttonPlay = [[UIButtonalloc] initWithFrame:CGRectMake(30,HEIGHT*0.7,WIDTH-60, 40)];
[self.viewaddSubview:buttonPlay];
buttonPlay.backgroundColor = [UIColorredColor];
[buttonPlay addTarget:selfaction:@selector(buttonPlayMedia)forControlEvents:UIControlEventTouchDown];
// 创建语音控件
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *sessionError;
//AVAudioSessionCategoryPlayAndRecord用于录音和播放
[session setCategory:AVAudioSessionCategoryPlayAndRecorderror:&sessionError];
if(session == nil)
NSLog(@"Error creating session: %@", [sessionErrordescription]);
else
[session setActive:YESerror:nil];
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)objectAtIndex:0];
self.playName = [NSStringstringWithFormat:@"%@/play.aac",docDir];
//录音设置
self.recorderSettingsDict = [[NSDictionaryalloc] initWithObjectsAndKeys:
[NSNumber numberWithFloat: 8000.0],AVSampleRateKey,//采样率
[NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,
[NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,//采样位数默认 16
[NSNumber numberWithInt: 1], AVNumberOfChannelsKey,//通道的数目
// [NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,//大端还是小端是内存的组织方式
// [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,//采样信号是整数还是浮点数
// [NSNumber numberWithInt: AVAudioQualityMedium],AVEncoderAudioQualityKey,//音频编码质量
nil];
//音量图片数组
self.volumImages = [[NSMutableArrayalloc]initWithObjects:@"RecordingSignal001",@"RecordingSignal002",@"RecordingSignal003",
@"RecordingSignal004",@"RecordingSignal005",@"RecordingSignal006",
@"RecordingSignal007",@"RecordingSignal008", nil];
}
- (void)holdDownButtonTouchDown {
NSLog(@"holdDownButtonTouchDown");
//按下录音
if ([selfcanRecord]) {
NSError *error = nil;
//必须真机上测试,模拟器上可能会崩溃
self.recorder = [[AVAudioRecorderalloc] initWithURL:[NSURLURLWithString:self.playName]settings:self.recorderSettingsDicterror:&error];
if (self.recorder) {
self.recorder.meteringEnabled =YES;
[self.recorder prepareToRecord];
[self.recorder record];
//启动定时器
self.timer = [NSTimerscheduledTimerWithTimeInterval:0.1target:selfselector:@selector(levelTimer:)userInfo:nilrepeats:YES];
} else
{
int errorCode = CFSwapInt32HostToBig ([error code]);
NSLog(@"Error: %@ [%4.4s])" , [errorlocalizedDescription], (char*)&errorCode);
}
}
}
- (void)holdDownButtonTouchUpInside {
NSLog(@"holdDownButtonTouchUpInside");
//录音停止
[self.recorderstop];
self.recorder =nil;
//结束定时器
[self.timerinvalidate];
self.timer =nil;
//图片重置
// self.soundLodingImageView.image = [UIImage imageNamed:[self.volumImages objectAtIndex:0]];
}
- (void)holdDownDragOutside {
NSLog(@"holdDownDragOutside");
}
- (void)buttonPlayMedia {
NSError *playerError;
//播放
self.player =nil;
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURLURLWithString:self.playName]error:&playerError];
if (self.player ==nil)
{
NSLog(@"ERror creating player: %@", [playerErrordescription]);
}else{
[self.player play];
}
}
-(void)levelTimer:(NSTimer*)timer_ {
[self.recorder updateMeters];
const double ALPHA =0.05;
double peakPowerForChannel = pow(10, (0.05 * [self.recorderpeakPowerForChannel:0]));
self.lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) *self.lowPassResults;
NSLog(@"Average input: %f Peak input: %f Low pass results: %f", [self.recorderaveragePowerForChannel:0], [self.recorderpeakPowerForChannel:0],self.lowPassResults);
}
//判断是否允许使用麦克风7.0新增的方法requestRecordPermission
-(BOOL)canRecord
{
__block BOOL bCanRecord =YES;
if ([[[UIDevicecurrentDevice] systemVersion]compare:@"7.0"] !=NSOrderedAscending)
{
AVAudioSession *audioSession = [AVAudioSessionsharedInstance];
if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {
[audioSession performSelector:@selector(requestRecordPermission:)withObject:^(BOOLgranted) {
if (granted) {
bCanRecord = YES;
}
else {
bCanRecord = NO;
dispatch_async(dispatch_get_main_queue(), ^{
[[[UIAlertView alloc] initWithTitle:nil
message:@"app需要访问您的麦克风。\n请启用麦克风-设置/隐私/麦克风"
delegate:nil
cancelButtonTitle:@"关闭"
otherButtonTitles:nil]show];
});
}
}];
}
}
return bCanRecord;
}
AVAudioSession类从AVFoundation框架中引入, 每个IOS应用都有一个音频会话, 这个会话可以被AVAudioSession的sharedInstance类方法访问.
AVAudioSessionCategoryPlayAndRecord 这个类别中允许你的应用同时进行声音的播放和录制.当你的声音播放和录制开始后, 其他应用的声音播放将会停止,主UI界面会照常工作, 这时即使屏幕被锁定或者设备为静音模式,音频的播放都会继续.
demo写的异常粗糙, 以后再重新写一个
#import "ViewController.h"
#import "UIImage+Extension.h"
#import <AVFoundation/AVFoundation.h>
#define WIDTH [[UIScreen mainScreen] bounds].size.width
#define HEIGHT [[UIScreen mainScreen] bounds].size.height
@interface ViewController ()
// 录音名字
@property (nonatomic,copy) NSString *playName;
// 录音器
@property (nonatomic,strong) AVAudioRecorder *recorder;
// 播放器
@property (nonatomic,strong) AVAudioPlayer *player;
// 属性设置
@property (nonatomic,copy) NSDictionary *recorderSettingsDict;
// 声音标识
@property (nonatomic,copy) NSMutableArray *volumImages;
// 定时器
@property (nonatomic,strong) NSTimer *timer;
//
@property (nonatomic,assign) double lowPassResults;
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
// 创建button
UIButton *button = [[UIButtonalloc] initWithFrame:CGRectMake(30,HEIGHT*0.6,WIDTH-60, 40)];
[self.viewaddSubview:button];
[button setBackgroundImage:[UIImageresizedImageWithName:@"VoiceBtn_Black"]forState:UIControlStateNormal];
[button setBackgroundImage:[UIImageresizedImageWithName:@"VoiceBtn_BlackHL"]forState:UIControlStateHighlighted];
[button setTitle:@"发送新消息"forState:UIControlStateNormal];
[button setTitle:@"按住说话"forState:UIControlStateHighlighted];
[button setTitleColor:[UIColordarkGrayColor] forState:UIControlStateNormal];
button.titleLabel.font = [UIFontsystemFontOfSize:14];
[button addTarget:selfaction:@selector(holdDownButtonTouchDown)forControlEvents:UIControlEventTouchDown];
[button addTarget:selfaction:@selector(holdDownButtonTouchUpInside)forControlEvents:UIControlEventTouchUpInside];
[button addTarget:selfaction:@selector(holdDownDragOutside)forControlEvents:UIControlEventTouchDragExit];
UIButton *buttonPlay = [[UIButtonalloc] initWithFrame:CGRectMake(30,HEIGHT*0.7,WIDTH-60, 40)];
[self.viewaddSubview:buttonPlay];
buttonPlay.backgroundColor = [UIColorredColor];
[buttonPlay addTarget:selfaction:@selector(buttonPlayMedia)forControlEvents:UIControlEventTouchDown];
// 创建语音控件
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *sessionError;
//AVAudioSessionCategoryPlayAndRecord用于录音和播放
[session setCategory:AVAudioSessionCategoryPlayAndRecorderror:&sessionError];
if(session == nil)
NSLog(@"Error creating session: %@", [sessionErrordescription]);
else
[session setActive:YESerror:nil];
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)objectAtIndex:0];
self.playName = [NSStringstringWithFormat:@"%@/play.aac",docDir];
//录音设置
self.recorderSettingsDict = [[NSDictionaryalloc] initWithObjectsAndKeys:
[NSNumber numberWithFloat: 8000.0],AVSampleRateKey,//采样率
[NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,
[NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,//采样位数默认 16
[NSNumber numberWithInt: 1], AVNumberOfChannelsKey,//通道的数目
// [NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,//大端还是小端是内存的组织方式
// [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,//采样信号是整数还是浮点数
// [NSNumber numberWithInt: AVAudioQualityMedium],AVEncoderAudioQualityKey,//音频编码质量
nil];
//音量图片数组
self.volumImages = [[NSMutableArrayalloc]initWithObjects:@"RecordingSignal001",@"RecordingSignal002",@"RecordingSignal003",
@"RecordingSignal004",@"RecordingSignal005",@"RecordingSignal006",
@"RecordingSignal007",@"RecordingSignal008", nil];
}
- (void)holdDownButtonTouchDown {
NSLog(@"holdDownButtonTouchDown");
//按下录音
if ([selfcanRecord]) {
NSError *error = nil;
//必须真机上测试,模拟器上可能会崩溃
self.recorder = [[AVAudioRecorderalloc] initWithURL:[NSURLURLWithString:self.playName]settings:self.recorderSettingsDicterror:&error];
if (self.recorder) {
self.recorder.meteringEnabled =YES;
[self.recorder prepareToRecord];
[self.recorder record];
//启动定时器
self.timer = [NSTimerscheduledTimerWithTimeInterval:0.1target:selfselector:@selector(levelTimer:)userInfo:nilrepeats:YES];
} else
{
int errorCode = CFSwapInt32HostToBig ([error code]);
NSLog(@"Error: %@ [%4.4s])" , [errorlocalizedDescription], (char*)&errorCode);
}
}
}
- (void)holdDownButtonTouchUpInside {
NSLog(@"holdDownButtonTouchUpInside");
//录音停止
[self.recorderstop];
self.recorder =nil;
//结束定时器
[self.timerinvalidate];
self.timer =nil;
//图片重置
// self.soundLodingImageView.image = [UIImage imageNamed:[self.volumImages objectAtIndex:0]];
}
- (void)holdDownDragOutside {
NSLog(@"holdDownDragOutside");
}
- (void)buttonPlayMedia {
NSError *playerError;
//播放
self.player =nil;
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURLURLWithString:self.playName]error:&playerError];
if (self.player ==nil)
{
NSLog(@"ERror creating player: %@", [playerErrordescription]);
}else{
[self.player play];
}
}
-(void)levelTimer:(NSTimer*)timer_ {
[self.recorder updateMeters];
const double ALPHA =0.05;
double peakPowerForChannel = pow(10, (0.05 * [self.recorderpeakPowerForChannel:0]));
self.lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) *self.lowPassResults;
NSLog(@"Average input: %f Peak input: %f Low pass results: %f", [self.recorderaveragePowerForChannel:0], [self.recorderpeakPowerForChannel:0],self.lowPassResults);
}
//判断是否允许使用麦克风7.0新增的方法requestRecordPermission
-(BOOL)canRecord
{
__block BOOL bCanRecord =YES;
if ([[[UIDevicecurrentDevice] systemVersion]compare:@"7.0"] !=NSOrderedAscending)
{
AVAudioSession *audioSession = [AVAudioSessionsharedInstance];
if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {
[audioSession performSelector:@selector(requestRecordPermission:)withObject:^(BOOLgranted) {
if (granted) {
bCanRecord = YES;
}
else {
bCanRecord = NO;
dispatch_async(dispatch_get_main_queue(), ^{
[[[UIAlertView alloc] initWithTitle:nil
message:@"app需要访问您的麦克风。\n请启用麦克风-设置/隐私/麦克风"
delegate:nil
cancelButtonTitle:@"关闭"
otherButtonTitles:nil]show];
});
}
}];
}
}
return bCanRecord;
}