音频播放

音频相关

最爱的宝贝.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<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.实现逻辑

模糊效果

  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又是个啥??

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容