本文共 7465 字,大约阅读时间需要 24 分钟。
#pragma mark 基本使用- (void)baseUse{ //1. 创建URL地址 NSURL *url = [[NSBundle mainBundle] URLForResource:@"buyao.wav" withExtension:nil]; //2. 系统音效文件 SystemSoundID = UInt32 SystemSoundID soundID; //3. 创建音效文件 AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundID); //4. 播放音效文件 //4.1 不带震动的播放 //AudioServicesPlaySystemSound(soundID); //4.2 带振动的播放 --> 真机才有效果 AudioServicesPlayAlertSound(soundID); //5. 如果不需要播放了, 需要释放音效所占用的内存 AudioServicesDisposeSystemSoundID(soundID);}
MTAudioTool.h
#import#import @interface MTAudioTools : NSObject/** 播放系统音效*/+ (void)playSystemSoundWithURL:(NSURL *)url;/** 播放震动音效*/+ (void)playAlertSoundWithURL:(NSURL *)url;/** 清空音效文件的内存*/+ (void)clearMemory;@end
MTAudioTool.m
#import "MTAudioTools.h"/** 缓存字典*/static NSMutableDictionary *_soundIDDict;@implementation MTAudioTools// 只要头文件参与了编译调用//+ (void)load/** 缓存字典初始化*/+ (void)initialize{ _soundIDDict = [NSMutableDictionary dictionary];}+ (void)playSystemSoundWithURL:(NSURL *)url{ // 不带震动的播放 AudioServicesPlaySystemSound([self loadSoundIDWithURL:url]);}/** 播放震动音效*/+ (void)playAlertSoundWithURL:(NSURL *)url{ // 带震动的播放 AudioServicesPlayAlertSound([self loadSoundIDWithURL:url]);}#pragma mark 播放音效的公用方法+ (SystemSoundID)loadSoundIDWithURL:(NSURL *)url{ // 思路思路 // soundID重复创建 --> soundID每次创建, 就会有对应的URL地址产生 // 可以将创建后的soundID 及 对应的URL 进行缓存处理 //1. 获取URL的字符串 NSString *urlStr = url.absoluteString; //2. 从缓存字典中根据URL来取soundID 系统音效文件 SystemSoundID soundID = [_soundIDDict[urlStr] intValue]; //需要在刚进入的时候, 判断缓存字典是否有url对应的soundID //3. 判断soundID是否为0, 如果为0, 说明没有找到, 需要创建 if (soundID == 0) { //3.1 创建音效文件 AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundID); //3.2 缓存字典的添加键值 _soundIDDict[urlStr] = @(soundID); } return soundID;}/** 清空音效文件的内存*/+ (void)clearMemory{ //1. 遍历字典 [_soundIDDict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { //2. 清空音效文件的内存 SystemSoundID soundID = [obj intValue]; AudioServicesDisposeSystemSoundID(soundID); }];}@end
ViewController.m
#import "ViewController.h"#import#import "MTAudioTools.h"/** 1. 导入AVFoundation框架 2. 创建音效文件 3. 播放音效文件 音效: 非常短的音乐, 一般来说30秒以内的声音, 都算作音效 */@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.}#pragma mark 点击播放音效- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ //1. 获取URL地址 NSURL *url = [[NSBundle mainBundle] URLForResource:@"buyao.wav" withExtension:nil]; //2. 调用工具类播放音效 //[MTAudioTools playSystemSoundWithURL:url]; [MTAudioTools playAlertSoundWithURL:url]; }#pragma mark 当前控制器收到内存警告时会调用的方法- (void)didReceiveMemoryWarning{ // 局部音效需要在这里进行释放 [MTAudioTools clearMemory]; NSLog(@"%s",__func__);}@end
#import "ViewController.h"#import/** 1. 需要使用AVFoundatiaon框架 2. 创建音乐播放器 3. 根据需求, 进行播放/暂停/停止 */@interface ViewController ()@property (nonatomic, strong) AVAudioPlayer *player;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // 创建音乐播放器 //1. 获取URL路径 NSURL *url = [[NSBundle mainBundle] URLForResource:@"我爱你你却爱着她.mp3" withExtension:nil]; //2. 创建一个error对象 NSError *error; //3. 创建音乐播放器 self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]; if (error) { NSLog(@"有错误产生"); } }- (IBAction)playClick:(id)sender { //1. 准备播放 --> 将音频文件加载到内存中 --> 这句话可以不写 --> play会隐式调用prepareToPlay方法. 但是规范来说, 还是会写上 [self.player prepareToPlay]; //2. 开始播放 [self.player play];}- (IBAction)pauseClick:(id)sender { // 暂停播放 [self.player pause];}- (IBAction)stopClick:(id)sender { // 停止播放 [self.player stop]; // 归零操作 / 时间重置 currentTime--> 秒为单位 self.player.currentTime = 0;}@end
#import "ViewController.h"#import/** 1. 需要使用AVFoundatiaon框架 2. 创建录音对象 3. 根据需求, 进行录音/暂停/停止 */@interface ViewController ()@property (nonatomic, strong) AVAudioRecorder *recorder;@property (nonatomic, strong) CADisplayLink *displayLink;@end@implementation ViewController/** //录音 // //settings 设置参数 录音相关参数 声道 速率 采样率 // NSMutableDictionary *setting = [NSMutableDictionary dictionary]; // // 音频格式 // setting[AVFormatIDKey] = @(kAudioFormatAppleIMA4); // // 音频采样率 // setting[AVSampleRateKey] = @(600.0); // // 音频通道数 // setting[AVNumberOfChannelsKey] = @(1); // // 线性音频的位深度 // setting[AVLinearPCMBitDepthKey] = @(8); */- (void)viewDidLoad { [super viewDidLoad]; // 创建录音对象 //1. 获取URL地址 --> 具体的文件名路径 //--> 注意之前是获取资源地址, 这里是指要将录音存放到哪里 NSString *path = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"recorde.wav"]; //2. 将path字符串转换成NSURL --> file:// NSURL *url = [NSURL fileURLWithPath:path]; //3. 配置设置字典 // 如果传空, 默认就是高质量 // 录音的参数值 NSMutableDictionary *setting = [NSMutableDictionary dictionary]; //4. 创建Error对象 __autoreleasing 可以不加, 加上之后是最标准写法 __autoreleasing NSError *error; //5. 创建录音对象 self.recorder = [[AVAudioRecorder alloc] initWithURL:url settings:setting error:&error]; // if (error) {// NSLog(@"error");// } //6. 打开分贝的检测 self.recorder.meteringEnabled = YES; //7. 如果要在真机运行, 还需要一个session类, 并且制定分类为录音 AVAudioSession *session = [AVAudioSession new]; [session setCategory:AVAudioSessionCategoryRecord error:nil];}- (IBAction)recordClick:(id)sender { //1. 准备录音 [self.recorder prepareToRecord]; //2. 开始录音 --> 如果同一路径再次录音, 则会覆盖之前的文件 [self.recorder record]; //3. 进行分贝的循环检测 --> 添加计时器 [self updateMetering];}- (IBAction)pauseClick:(id)sender { // 暂停录音 --> 如果用户只是暂停了, 应该提示用户进行保存操作 [self.recorder pause]; // 暂停循环 self.displayLink.paused = YES;}- (IBAction)stopClick:(id)sender { // 停止录音 --> 之后停止录音时, 最终的录音文件才会生产 [self.recorder stop]; // 暂停循环 self.displayLink.paused = YES; NSLog(@"停止录音");}#pragma mark 添加计时器- (void)updateMetering{ // 如果没有displayLink就创建 if (self.displayLink == nil) { //1. 创建displayLink self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateMeter)]; //2. 添加到运行循环中 [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; } // 判断如果暂停了循环, 就打开 if (self.displayLink.isPaused) { self.displayLink.paused = NO; }}#pragma mark 循环调用的方法- (void)updateMeter{ //需求: 自动停止录音 --> 根据分贝的大小来判断 //1. 我们需要获取分贝信息 //2. 设置分贝如果小于某个值, 一定时间后, 自动停止 //1. 更新分贝信息 [self.recorder updateMeters]; //2. 获取分贝信息 --> iOS直接传0 // 0 ~ -160 , 值最大是0, 最小是-160. 系统返回的是负值 CGFloat power = [self.recorder averagePowerForChannel:0]; //3. 实现2S自动停止 static NSInteger number; //displayLink,一秒默认是60次, 如果120此的调用都小于某个分贝值, 我们就可以认为要自动停止 //3.1 先判断用户是否小于某个分贝值 --> 用户是否没说话 if (power < -30) { //3.2 如果发现很安静, 我们就可以记录一下, number进行叠加 number++; //3.3 如果发现120次了, 都小于设定的分贝值 if (number / 60 >= 2) { //3.4 调用停止方法 [self stopClick:nil]; } } else { number = 0; } NSLog(@"power: %f",power);}@end
转载地址:http://iwuwa.baihongyu.com/