音频相关
- iOS6界面和iOS7界面差别很大,需要大量自定义控件
- iOS6和iOS7的view会差20点.
音效:叮..叮..叮..
不能超过30秒
框架:AVFoundation
格式:AAC(iOS默认通过aac格式),MP3等
音效的基本使用:3个相关方法(基于C语言的方法)
- 关键词:(音频服务来播放音效:AudioServices)
- 关键方法:C语言方法
- 如果要使用一个音效,要先创建它
creat...
注意内存泄漏问题(OC转C,这个C需要第二种转换手动释放它的内存,意思是获取到管理内存的权限)
SystemSoundID需要标记音效ID - 播放已经存在的音效
playAlertSound(提醒音效,会震动)- 可以在不使用的时候可以销毁音效
dispose...
- 如果要使用一个音效,要先创建它
// 创建
NSURL *url = [[NSBundle mainBundle]URLForResource:@"RGBLBSYLSN.mp3" withExtension:nil];
CFURLRef cfURL = (__bridge CFURLRef)(url);
AudioServicesCreateSystemSoundID(cfURL, &(_soundID));
// 播放
AudioServicesPlaySystemSound(self.soundID);
// 停止
AudioServicesDisposeSystemSoundID(self.soundID);
音效的特性:
- 只需要创建一次,就可以无限播放
- 同一个音效不能同时播放,第二次会中断第一次
- 不同音效,可以同时
- 没有暂停和停止
- 音效的生命周期问题.从创建到被手动销毁.
实际开发:
- 需要先创建再播放
写一个工具类管理所有音效. - 单例
单例更简单和方便 - 类方法
- 创建工具类
- 实现类方法
- 做一个缓存(NSDictionary),来判断是否已经添加过.考虑这个类方法怎么做字典?加一个static静态变量.
录音的使用
目标:使用手机硬件来录制声音.
核心类:Reccorder录音器
- 开启
- 配置录音器
- 准备录音(获取硬件住别)|文件准别
- 开始录音.
- 暂停
- 停止
- 停止要做释放操作.(硬件释放|文件释放)
- 长按
- 思路:
- 按在上面都要录音
- 离开就删除录音(先停止后删除)
注意:
- 所有涉及到声音的功能都考虑加声明.
真机测试:发现有录音文件,但是不能播放.(怎么获取到真机的录音文件)
截图:
必须向系统声明, 本应用所使用到的音频服务的类型.
在viewDidLoad中通过AVAudioSeesion向系统声明,本应用的所使用到的音频服务类型.setCategory
- 实际开发中文件路径需要不唯一,加入当前时间.
- Document : 该目录中的文件, 默认是会被同步的icloud上
- 如果比较大的文件乱放在这里, 会导致iCloud爆, 会
导致拒绝上架
- Document目录的文件, 是可以通过iTunes与电脑进行数据分享
- 将电脑里的文件保存到该应用沙盒的Document目录当中
- 可以将应用沙盒中的Document目录中的文件导出到电脑当中
处理方案: 使用代码, 来指定Document目录中的某些文件, 不要进行同步
Cache : 缓存目录, 持续性, 通常会提供清除的方法 (可行)
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSMicrophoneUsageDescription key with a string value explaining to the user how the app uses this data.
iOS10开始, 要进行录音, 需要得到授权
// 向系统声明, 本应用所使用到的音频服务的类型
NSError *error;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:&error];
if (error) {
NSLog(@"向系统声明音频服务使用类型出错: %@", error);
}
- (IBAction)beginRecord:(id)sender
{
// ========== 拼接URL地址 ==========
// iOS系统默认推荐使用.aac来保存音频文件
NSString *docuPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
NSLog(@"%@", docuPath);
NSString *filePath = [docuPath stringByAppendingPathComponent:@"temp.aac"];
// NSURL *url = [NSURL URLWithString:filePath];
// 会添加fill:// 这种前缀, 确保这是本地路径
NSURL *url = [NSURL fileURLWithPath:filePath];
// 字典的配置当中, 如果value是枚举类型, 通常是包装成NSNumber, 或者它有一个对应的NSString的常量.
NSDictionary *para = @{
// 指定录音文件的格式
AVFormatIDKey : @(kAudioFormatMPEG4AAC),
};
/**
URL: 录音文件的存储路径
Settings: 录音的相关配置
*/
NSError *error;
_recorder = [[AVAudioRecorder alloc] initWithURL:url settings:para error:&error];
if (error) {
NSLog(@"录音器创建失败! %@", error);
}
// 准备录音 ( 获取硬件准备(如麦克风的使用) | 文件准备(创建保存录音数据的文件) )
[_recorder prepareToRecord];
// 开始录音 (开始录音时会检查当前的情况, 如果没有做好准备, 会隐式的调用prepareToRecord方法)
[_recorder record];
}
// 暂停
[_recorder pause];
// 停止
[_recorder stop];
/*
长按,需要用一些方法
UIControlEventTouchUpInside
UIControlEventTouchUpOutside
UIControlEventTouchDown
*/
- (IBAction)cancelRecord:(id)sender
{
// 先停止录音
[_recorder stop];
// 删除已经录制的文件
// The audio recorder must be stopped before you call this method. 必须先停止, 才能删除 (停止才会释放文件的使用权)
// 会将录制的文件删除掉
[_recorder deleteRecording];
}
音乐播放
目标:音频播放器基本使用
关键词:Player
关键类:AVAudioPlayer(音频播放器)
.mp3是针对音乐而涉及到饿数据压缩格式.
代码:
- 创建音频播放器对象
- 准备播放(硬件准备|数据准备(将歌曲的数据加载到内存中))
- 开始播放
- 暂停播放
- 停止播放(释放硬件准备|释放数据)
测试发现停止后未重新开始.而是继续停止点时.
常用属性:
- 引出currentTime属性.在stop中重置currentTime.
- rate播放速率(先要设置enableRate),还要移到准备之前.(进头文件开)
- volume音量(和系统音量无关)
目标:简单音乐播放器
- 核心功能
- 抽取独立的音乐模块,单例播放歌曲.
- 界面:横竖屏界面布局不一样,但是元素是一样的.
修改sizeClass,点横屏修改约束.
installed安装勾不勾上,能不能显示
前面有一个加号:在这里可以修改横屏的约束.勾选的是当前size下的约束.默认任意size下的控件约束.
* 纯代码版:当前的size发生改变了才能去更新约束
viewWillTransitionToSize方法(系统方法).下面有实例代码
然后在设备运行时,当你切换了设备的方向,SizeClasses也会做出相应的改变你可以通过代理方法来获取设备的SizeClasses,然后根据相应的设备信息重新定义约束
[objc] view plain copy
/**
* 当设备改变朝向时
* 返回当前屏幕sizeClaeese的尺寸信息的代理方法
*
* @param newCollection 包含了屏幕的sizeClasees的信息
* @param coordinator
*/
-(void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
[super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
if (isIphonePortrait) {
//写布局内容的改变 无改变就不用写
NSLog(@"iphone 竖屏");
}else if(isIpad){
//写布局内容的改变 无改变就不用写
NSLog(@"ipad");
}else if (isIphoneLandscape){
//写布局内容的改变 无改变就不用写
NSLog(@"iphone 横屏");
}else if (isIphone6PlusLandscape){
//写布局内容的改变 无改变就不用写
NSLog(@"iphone 6 plus 横屏");
}
} completion:nil];
}
2.连接属性字典转模型.
- 使用JsonModel框架.继承JsonModel,写好你需要的属性.内部全给你搞好了.
3.实现逻辑
模糊效果
- UIVisualEffect虚拟化效果类.直接添加给子视图.ImageView在IB中不能添加子视图,但是本质是UIView,代码是可以添加子视图的.
- UIToolBar实现,在以前,模糊效果也可以通过UIToolBar来实现.
barStyle属性给黑的就可以了.一样的用法
//利用toolbar
UIToolbar *toolbar = [[UIToolbar alloc] init];
toolbar.barStyle = UIBarStyleBlack;
[self.bgImgView addSubview:toolbar];
[toolbar mas_makeConstraints:^(MASConstraintMaker *make) {
// 表示它会与父视图进行缩进 (与父视图一样大)
make.edges.mas_equalTo(UIEdgeInsetsMake(0, 0, 0, 0));
}];
//自带的虚化的类
// UIBlurEffect 表示模糊效果
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
// UIVisualEffectView : 表示可视化的效果视图
UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
// ImageView在IB当中不能添加子视图, 但是它本质也是UIView, 通过代码是可以添加子视图
[self.bgImgView addSubview:effectView];
圆角.
直接layer
self.singerImgView.layer.masksToBounds = YES;
self.singerImgView.layer.cornerRadius = self.singerImgView.bounds.size.width * 0.5;
进度条
- 根据歌曲时长确认进度条
动画的最短时间0.25.
定时器的循环引用问题. - 根据歌曲大小确认进度条
时间格式转化为字符串
NSDate,NSDateFormatter
将90秒转换为NSDate对象,再来用NSDateFormatter转化字符串
注意进度条也有多种事件响应,三个事件.
歌词对应(.lrc)
- 加载
- 解析模型
- 根据时间显示(正则)
一个模型工具类,一个歌词模型.
LyricManager内部方法通过url获取每行的字符串.
利用正则匹配时间(格式清晰)
取出时间,取出歌词.
正则语法:加\代表是[]没有特殊含义,不加代表集合的意思.
[00:00.00]->[\d{2}:\d{2}.\d{2}]
OC语法:\代表不需要使用转义字符的意思
[\d{2}:\d{2}.\d{2}]->
\[\d{2}:\d{2}.\d{2}\]
文字渐变颜色.
混合模式?
- 创建继承UILable的子类,重写drawRect方法
类似滤镜效果
UIRectFillUsingBlendMode(CGRect,kCGBlendModeSourceIn).
演示真机相关的东西:
- 后台的音乐播放支持.(默认是不支持后台的)
- 在Capabilities打开后台音频模式
- 向系统声明申明音频类型,写在哪呢?
- 写在load中.声明后台播放.
setCategory(设置后台)
setActive(设置激活)
- 写在load中.声明后台播放.
- 实现锁屏界面
- 监听远程控制事件(应用没有处于前台依然能够控制它)
- 4种事件 - RemoteControlEvent
- 锁屏音乐,耳机线控制.
- UIApplication提供了相关方法(iOS7.0)
- MPRemoteCommandCenter.
- 锁屏界面.
- 监听远程控制事件(应用没有处于前台依然能够控制它)
远程控制
旧的方法:iOS7.0前
- 程序开始时,开启接收远程控制事件
[application beginReceivingRemoteControlEvent]; - 在willTerminate代理方法内结束接收远程控制事件.
stop - 重写remoteControlReceive..方法(任何控制器都可以处理事件,继承自UIResponder)
新的方法:
- 导入框架:MediaPlayer(MP)
发现和播放用户已经添加的媒体文件.
MPRemoteCommand远程命令中心:用来处理远程控制事件.- 启用对应的命令
- 为命令添加响应事件
- 更新歌曲信息到锁屏界面上.
NPNowPlayingInfoCenter:负责在锁屏界面和控制中心显示歌曲信息. - 锁屏界面信息.
- 来电中断.
在AVAudioSession定义了通知
,进文档,找通知.
NSCFString是个啥?NSPorty又是个啥??