音频播放

音频相关

最爱的宝贝.png
  1. iOS6界面和iOS7界面差别很大,需要大量自定义控件
  2. iOS6和iOS7的view会差20点.

音效:叮..叮..叮..
不能超过30秒

框架:AVFoundation

格式:AAC(iOS默认通过aac格式),MP3等

音效的基本使用:3个相关方法(基于C语言的方法)

  • 关键词:(音频服务来播放音效:AudioServices)
  • 关键方法:C语言方法
    1. 如果要使用一个音效,要先创建它
      creat...
      注意内存泄漏问题(OC转C,这个C需要第二种转换手动释放它的内存,意思是获取到管理内存的权限)
      SystemSoundID需要标记音效ID
    2. 播放已经存在的音效
    playSystemSound(会播放音效但是不会震动)
    playAlertSound(提醒音效,会震动)
    1. 可以在不使用的时候可以销毁音效
      dispose...
// 创建
 NSURL *url = [[NSBundle mainBundle]URLForResource:@"RGBLBSYLSN.mp3" withExtension:nil];
    CFURLRef cfURL = (__bridge CFURLRef)(url);
    AudioServicesCreateSystemSoundID(cfURL, &(_soundID));
// 播放
AudioServicesPlaySystemSound(self.soundID);
// 停止
AudioServicesDisposeSystemSoundID(self.soundID);

音效的特性:

  1. 只需要创建一次,就可以无限播放
  2. 同一个音效不能同时播放,第二次会中断第一次
  3. 不同音效,可以同时
  4. 没有暂停和停止
  5. 音效的生命周期问题.从创建到被手动销毁.

实际开发:

  1. 需要先创建再播放
    写一个工具类管理所有音效.
  2. 单例
    单例更简单和方便
  3. 类方法
    1. 创建工具类
    2. 实现类方法
    • 做一个缓存(NSDictionary),来判断是否已经添加过.考虑这个类方法怎么做字典?加一个static静态变量.

录音的使用

目标:使用手机硬件来录制声音.
核心类:Reccorder录音器

  1. 开启
    1. 配置录音器
    2. 准备录音(获取硬件住别)|文件准别
    3. 开始录音.
  2. 暂停
  3. 停止
    1. 停止要做释放操作.(硬件释放|文件释放)
  4. 长按
    • 思路:
    1. 按在上面都要录音
    2. 离开就删除录音(先停止后删除)

注意:

  1. 所有涉及到声音的功能都考虑加声明.
    真机测试:发现有录音文件,但是不能播放.(怎么获取到真机的录音文件)
    截图:
Snip20161105_1.png

必须向系统声明, 本应用所使用到的音频服务的类型.
在viewDidLoad中通过AVAudioSeesion向系统声明,本应用的所使用到的音频服务类型.setCategory

  1. 实际开发中文件路径需要不唯一,加入当前时间.
  • 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是针对音乐而涉及到饿数据压缩格式.

代码:

  1. 创建音频播放器对象
  2. 准备播放(硬件准备|数据准备(将歌曲的数据加载到内存中))
  3. 开始播放
  4. 暂停播放
  5. 停止播放(释放硬件准备|释放数据)

测试发现停止后未重新开始.而是继续停止点时.
常用属性:

  1. 引出currentTime属性.在stop中重置currentTime.
  2. rate播放速率(先要设置enableRate),还要移到准备之前.(进头文件开)
  3. volume音量(和系统音量无关)

目标:简单音乐播放器

  1. 核心功能
    • 抽取独立的音乐模块,单例播放歌曲.
    • 界面:横竖屏界面布局不一样,但是元素是一样的.
      修改sizeClass,点横屏修改约束.
      installed安装勾不勾上,能不能显示
Snip20161105_5.png

前面有一个加号:在这里可以修改横屏的约束.勾选的是当前size下的约束.默认任意size下的控件约束.
* 纯代码版:当前的size发生改变了才能去更新约束
viewWillTransitionToSize方法(系统方法).下面有实例代码

    然后在设备运行时,当你切换了设备的方向,SizeClasses也会做出相应的改变你可以通过代理方法来获取设备的SizeClasses,然后根据相应的设备信息重新定义约束

[objc] view plain copy
/** 
 *  当设备改变朝向时 
 *  返回当前屏幕sizeClaeese的尺寸信息的代理方法 
 * 
 *  @param newCollection 包含了屏幕的sizeClasees的信息 
 *  @param coordinator    
 */  
-(void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id)coordinator{  
  
  
    [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];  
      
    [coordinator animateAlongsideTransition:^(id 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.实现逻辑

模糊效果

  1. UIVisualEffect虚拟化效果类.直接添加给子视图.ImageView在IB中不能添加子视图,但是本质是UIView,代码是可以添加子视图的.
  2. 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;

进度条

  1. 根据歌曲时长确认进度条
    动画的最短时间0.25.
    定时器的循环引用问题.
  2. 根据歌曲大小确认进度条

时间格式转化为字符串
NSDate,NSDateFormatter
将90秒转换为NSDate对象,再来用NSDateFormatter转化字符串

注意进度条也有多种事件响应,三个事件.

歌词对应(.lrc)
  1. 加载
  2. 解析模型
  3. 根据时间显示(正则)

一个模型工具类,一个歌词模型.
LyricManager内部方法通过url获取每行的字符串.
利用正则匹配时间(格式清晰)
取出时间,取出歌词.

正则语法:加\代表是[]没有特殊含义,不加代表集合的意思.
[00:00.00]->[\d{2}:\d{2}.\d{2}]

OC语法:\代表不需要使用转义字符的意思
[\d{2}:\d{2}.\d{2}]->
\[\d{2}:\d{2}.\d{2}\]

文字渐变颜色.

混合模式?

  1. 创建继承UILable的子类,重写drawRect方法

类似滤镜效果
UIRectFillUsingBlendMode(CGRect,kCGBlendModeSourceIn).

演示真机相关的东西:

  1. 后台的音乐播放支持.(默认是不支持后台的)
    1. 在Capabilities打开后台音频模式
    2. 向系统声明申明音频类型,写在哪呢?
      • 写在load中.声明后台播放.
        setCategory(设置后台)
        setActive(设置激活)
  2. 实现锁屏界面
    1. 监听远程控制事件(应用没有处于前台依然能够控制它)
      • 4种事件 - RemoteControlEvent
      1. 锁屏音乐,耳机线控制.
      • UIApplication提供了相关方法(iOS7.0)
      • MPRemoteCommandCenter.
    2. 锁屏界面.

远程控制
旧的方法:iOS7.0前

  1. 程序开始时,开启接收远程控制事件
    [application beginReceivingRemoteControlEvent];
  2. 在willTerminate代理方法内结束接收远程控制事件.
    stop
  3. 重写remoteControlReceive..方法(任何控制器都可以处理事件,继承自UIResponder)

新的方法:

  1. 导入框架:MediaPlayer(MP)
    发现和播放用户已经添加的媒体文件.
    MPRemoteCommand远程命令中心:用来处理远程控制事件.
    1. 启用对应的命令
    2. 为命令添加响应事件
  2. 更新歌曲信息到锁屏界面上.
    NPNowPlayingInfoCenter:负责在锁屏界面和控制中心显示歌曲信息.
  3. 锁屏界面信息.
  4. 来电中断.
    在AVAudioSession定义了通知
    ,进文档,找通知.

NSCFString是个啥?NSPorty又是个啥??

你可能感兴趣的:(音频播放)