博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS Audio(音频)
阅读量:6084 次
发布时间:2019-06-20

本文共 7465 字,大约阅读时间需要 24 分钟。

1. 播放音效

#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);}

2. 简单封装

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

3. 音乐播放

#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

4. 录音

#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/

你可能感兴趣的文章
Java 8新特性:Stream API
查看>>
swing和java里嵌入浏览器
查看>>
android之SoundPool
查看>>
Python学习-反射相关函数
查看>>
ubuntu11.10安装五笔输入法
查看>>
我的友情链接
查看>>
解决zabbix_get 获取不到自定义key一例
查看>>
DBNULL和NULL
查看>>
Confluence 6 有关 AD 的一些特殊说明
查看>>
linux系统管理之五:开机、关机、服务状态及系统密码修改
查看>>
Windows环境下的NodeJS+NPM+Bower安装配置
查看>>
LeetCode:Valid Number - 判断字符串中内容是否为数字
查看>>
Android 4.0 硬件加速
查看>>
Windows XP与NTP服务器自动更新时间的调整
查看>>
我的友情链接
查看>>
ubuntu 主机ssh root solaris虚拟机时候,输入密码报错 public key解决
查看>>
Silverlight和服务器端通信
查看>>
cookie注入&中转注入笔记
查看>>
跟Howard学LESS之初见LESS
查看>>
wap网页图片适配解决方案
查看>>