一、音频

在iOS中,音频播放从形式上可以分为音效播放和音乐播放。
* 音效:
* 主要指一些短音频的播放,这类音频一般不需要进行进度、循环等控制。
* 在iOS中,音效我们是使用AudioToolbox.framework框架实现。
* 音乐:
* 主要指一些较长的音频,通常需要对播放进行精确控制。
* 在iOS中,音乐我们是使用AVFoundation.framework框架实现。

二、音效

AudioToolbox.framework框架是一套基于C语言的框架
它的实现原理是将短音频注册到系统声音服务(SystemSoundService)

系统声音服务的一些限制:
  1. 音频播放时间不能超过30s
  2. 数据必须是PCM或者IMA4格式,现在的基本都符合
  3. 音频文件必须是CAF、AIF、WAV的一种,实际上有些MP3格式也可以播放。
使用步骤:
  1. 导入AudioToolbox.framework框架,添加头文件:
#import <AudioToolbox/AudioToolbox.h>
  1. 获取音效文件的路径URL
  2. 添加进系统声音服务,获得系统声音ID,ID是区分不同音效的唯一标示
void AudioServicesCreateSystemSoundID(CFURLRef inFileURL,    /* 音效文件URL,需要把NSURL桥接成CGURLRef */SystemSoundID *outSystemSoundID /* 返回音效唯一标示ID */
);
  1. 如果需要监听音效播放完成,需要绑定回调函数
void AudioServicesAddSystemSoundCompletion(  SystemSoundID inSystemSoundID, /* 音效ID */CFRunLoopRef inRunLoop, /* 所在循环,一般为NULL */CFStringRef inRunLoopMode,/* 循环模式,一般为NULL */void (*)(SystemSoundID,void*) inCompletionRoutine,/* 回调C语言函数指针 */void *inClientData /* 回调函数的参数 */
);
  1. 开始播放,有两种播放模式:
/* 开始播放音效 */
void AudioServicesPlaySystemSound(SystemSoundID inSystemSoundID);
/* 开始播放音效并带震动 */
void AudioServicesPlayAlertSound(SystemSoundID inSystemSoundID);
下面是使用实例:
- (void)viewDidLoad{[super viewDidLoad];[self playSoundEffect:@"bellTone.wav"];
}
#pragma mark -音效
/* 音效播放完成的回调函数,这个是C语言函数,第一个参数是音效ID,第二个是万能参数 */
void soundCompleteCallBack(SystemSoundID soundID, void *clientData)
{NSLog(@"播放完成");
}
- (void)playSoundEffect:(NSString *)name {//获取音效文件路径NSString *filePath = [[NSBundle mainBundle] pathForResource:name ofType:nil];//创建音效文件URLNSURL *fileUrl = [NSURL URLWithString:filePath];//音效声音的唯一标示IDSystemSoundID soundID = 0;//将音效加入到系统音效服务中,NSURL需要桥接成CFURLRef,会返回一个长整形ID,用来做音效的唯一标示AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);//设置音效播放完成后的回调C语言函数AudioServicesAddSystemSoundCompletion(soundID,NULL,NULL,soundCompleteCallBack,NULL);//开始播放音效AudioServicesPlaySystemSound(soundID);
}

三、音乐

如果播放较大的音频,需要对其进行精确控制,我们需要使用到另外一个框架,即:
AVFoundation.framework框架,它支持多种音频格式,可以进行精确控制。
音乐播放功能我们使用到的是AVFoundation.frameworkAVAudioPlayer音乐播放器来实现。

下面有一些AVAudioPlayer类的常用属性:
@property (readonly, getter=isPlaying) BOOL playing;//是否正在播放
@property NSTimeInterval currentTime;//当前已经播放的时间
@property (readonly) NSTimeInterval duration;//播放的总时间
@property float volume;//音量大小
@property float rate;//播放速率,默认为1.0
@property (readonly) NSURL *url;//音乐文件的URL
下面是常用的对象方法:
/* 初始化方法 */
- (instancetype)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError;
- (BOOL)prepareToPlay;/* 把音乐文件加载到缓存区 */
- (BOOL)play;/* 开始播放音乐 */
- (BOOL)playAtTime:(NSTimeInterval)time;/* 在指定时间开始播放音乐 */
- (void)pause;/* 中断音乐,可以通过调用play方法继续播放 */
- (void)stop;/* 终止音乐,无法继续播放 */
常用的代理方法:
/* 播放完成时调用 */
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
/* 音频解码发生错误时调用 */
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error;
使用步骤:
  1. 导入AVFoundation.framework框架,添加头文件:
#import <AVFoundation/AVFoundation.h>
  1. 获取音乐文件的本地文件路径URL,不能使用网络URL
  2. 创建音乐播放器对象AVAudioPlayer,并设置属性和代理。
  3. 调用perpareToPlay方法加载音乐文件到缓冲区
  4. 调用play方法播放,调用pause中断播放
  5. 实现AVAudioPlayerDelegate方法,监听播放完成。
我们来做个简易的音乐播放器吧:
  1. 可以循环播放音乐
  2. 可以中断音乐
  3. 可以切换不同的音乐
  4. 可以知道播放进度
下面是具体的简易音乐播放器项目代码:
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>@interface ViewController () <AVAudioPlayerDelegate>@property (nonatomic, strong) NSArray *musicArray;/*< 音乐列表 */
@property (nonatomic, strong) IBOutlet UIProgressView *progress;/*< 进度条 */
@property (nonatomic, strong) AVAudioPlayer *audioPlayer;/*< 音乐播放器对象 */
@property (nonatomic, strong) NSTimer *timer;/* 定时器 */
@property (nonatomic, strong) IBOutlet UILabel *titleLabel;/* 显示标题 */
@property (nonatomic, assign) NSInteger selectMusic;/* 当前播放音乐的索引 */@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//音乐文件列表self.musicArray = @[@"大梦想家",@"江南",@"酒干倘卖无",@"泡沫",@"夏洛特烦恼",@"演员"];//创建定时器,用于不断更新进度条self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updataProgress) userInfo:nil repeats:YES];//创建播放器[self initAudioPlayerWithNumber:0];//播放器开始播放音乐[self.audioPlayer play];
}
/* 初始化播放器 */
- (void)initAudioPlayerWithNumber:(NSInteger)num{if (num >= self.musicArray.count) {return;}//获取音乐文件路径NSString *name = self.musicArray[num];NSString *filePath = [[NSBundle mainBundle] pathForResource:name ofType:@"mp3"];//创建音乐文件URL,必须是fileURLWithPath,AVAudioPlayer不支持HTTP的URLNSURL *fileUrl = [NSURL fileURLWithPath:filePath];//创建播放器NSError *error = nil;AVAudioPlayer *audioPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:&error];if (error) {NSLog(@"初始化播放器错误,错误:%@",error.localizedDescription);return;}audioPlayer.numberOfLoops = 0;//设置循环次数,0表示不循环audioPlayer.delegate = self;//设置代理[audioPlayer prepareToPlay];//加载音乐文件到缓存,还不会播放self.selectMusic = num;//保存当前的音乐索引self.audioPlayer = audioPlayer;//保存当前播放器self.titleLabel.text = name;//设置标题
}
/* 进度条更新方法,每0.5秒更新一次 */
- (void)updataProgress{//currentTime是当前播放时间,duration是播放总时长CGFloat progress = self.audioPlayer.currentTime / self.audioPlayer.duration;[self.progress setProgress:progress animated:YES];
}
/* 点击播放按钮 */
- (IBAction)musicPlay:(id)sender {//如果播放器没有在播放,才需要调用播放方法if (![self.audioPlayer isPlaying]) {[self.audioPlayer play];//恢复定时器self.timer.fireDate = [NSDate distantPast];}
}
/* 点击暂停按钮 */
- (IBAction)musicPause:(id)sender {//如果播放器在播放,才需要调用暂停方法if ([self.audioPlayer isPlaying]) {[self.audioPlayer pause];//停止定时器self.timer.fireDate = [NSDate distantFuture];}
}
/* 点击下一首歌按钮 */
- (IBAction)next:(id)sender {//音乐索引循环递增self.selectMusic = (self.selectMusic + 1)%self.musicArray.count;//重新设置播放器[self initAudioPlayerWithNumber:self.selectMusic];//播放器播放[self.audioPlayer play];
}
#pragma mark - AVAudioPlayerDelegate代理方法
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{//自动跳转播放下一首歌[self next:nil];
}


(⊙﹏⊙)b,也是够简陋的,你可以做精美一点,比如如果每首歌对应一个图片,到时候切歌的时候,图片显示在背景,一定赏心悦目多了,O(∩_∩)O~,我没有找到好的图片,就这样吧。

四、后台播放音乐

事实上上面的播放器有一点问题,那就是一旦进入后台,我们的音乐器就自动暂停了,不可以/(ㄒoㄒ)/~~!那该怎么办呢?

1. 设置后台运行模式

设置info.plist文件,添加字段Required background modes
并设置App plays audio or streams audio/video using AirPlay

2. 使用音频会话,设置后台运行类型
//获取音频会话单例对象
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
//设置会话为后台播放
[audioSession setCategory:AVAudioSessionCategoryPlayback error:NULL];
//激活修改,启动会话
[audioSession setActive:YES error:NULL];

音频会话除了后台播放外,还可以有以下的播放模式:

上面的代码只需修改初始化播放器方法即可实现后台播放:
/* 初始化播放器 */
- (void)initAudioPlayerWithNumber:(NSInteger)num{if (num >= self.musicArray.count) {return;}//获取音乐文件路径NSString *name = self.musicArray[num];NSString *filePath = [[NSBundle mainBundle] pathForResource:name ofType:@"mp3"];//创建音乐文件URL,必须是fileURLWithPath,AVAudioPlayer不支持HTTP的URLNSURL *fileUrl = [NSURL fileURLWithPath:filePath];//创建播放器NSError *error = nil;AVAudioPlayer *audioPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:&error];if (error) {NSLog(@"初始化播放器错误,错误:%@",error.localizedDescription);return;}audioPlayer.numberOfLoops = 0;//设置循环次数,0表示不循环audioPlayer.delegate = self;//设置代理[audioPlayer prepareToPlay];//加载音乐文件到缓存,还不会播放//获取音频会话单例对象AVAudioSession *audioSession = [AVAudioSession sharedInstance];//设置会话为后台播放[audioSession setCategory:AVAudioSessionCategoryPlayback error:NULL];//激活修改,启动会话[audioSession setActive:YES error:NULL];self.selectMusic = num;//保存当前的音乐索引self.audioPlayer = audioPlayer;//保存当前播放器self.titleLabel.text = name;//设置标题
}

这样,我们就可以后台播放了,(^o^)/~。

有什么问题可以在下方评论区出去,好意见我会采纳的,打造一个大家都满意的学习笔记,O(∩_∩)O哈!

iOS学习笔记23-音效与音乐相关推荐

  1. iOS学习笔记22 推送通知

    ###一.推送通知 推送通知就是向用户推送一条信息来通知用户某件事件,可以在应用退到后台后,或者关闭后,能够通过推送一条消息通知用户某件事情,比如版本更新等等. ######推送通知的常用应用场景: ...

  2. OpenCV for Ios 学习笔记(4)-标记检测1

    本文原始地址:OpenCV for Ios 学习笔记(4)-标记检测1 简单的标记经常是以白色块和黑色块构成的规则图形.因为我们预先知道这些因素,所以我们可以很容易检测标记. 如图: 首先,我们需要找 ...

  3. StatQuest学习笔记23——RNA-seq简介

    StatQuest学习笔记23--RNA-seq简介 前言--主要内容 这篇笔记是StatQuest系列笔记的第58节,主要内容是讲RNA-seq的原理.StatQuest系列教程的58到62节是协录 ...

  4. IOS学习笔记(九)之UIAlertView(警告视图)和UIActionSheet(操作表视图)基本概念和使用方法...

    IOS学习笔记(九)之UIAlertView(警告视图)和UIActionSheet(操作表视图)基本概念和使用方法 Author:hmjiangqq Email:jiangqqlmj@163.com ...

  5. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  6. iOS学习笔记-自己动手写RESideMenu

    代码地址如下: http://www.demodashi.com/demo/11683.html 很多app都实现了类似RESideMenu的效果,RESideMenu是Github上面一个stars ...

  7. iOS学习笔记-地图MapKit入门

    代码地址如下: http://www.demodashi.com/demo/11682.html 这篇文章还是翻译自raywenderlich,用Objective-C改写了代码.没有逐字翻译,如有错 ...

  8. iOS学习笔记-自定义过渡动画

    代码地址如下: http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swi ...

  9. IOS学习笔记07---C语言函数-scanf函数

    2013/8/7 IOS学习笔记07---C语言函数-scanf函数 ------------------------------ qq交流群:创梦技术交流群:251572072            ...

最新文章

  1. ASP.NET TricksTip:关于Tooltip(title)的换行问题
  2. python给图片添加字符
  3. 微服务架构 接口交互问题_架构师的故事:设计微服务架构
  4. 远程客户端连接MysqL数据库太慢解决方案
  5. 对称加密算法-DES以及DESede算法
  6. Flash和HTML5那点事:后者拿什么取代Flash?
  7. 【Openstack】实录手动部署Openstack Rocky 双节点(3)- Glance
  8. 单网卡配置多IP ×××
  9. linux界面三个图标,配置Ubuntu Enlightenment桌面环境之三:桌面图标和根菜单_Linux学院_风信网...
  10. element元素 取属性_js element类型的属性和方法整理
  11. Macbook pro新手入门
  12. Sequencher_v4.1.4 DNA 序列分析的工业标准软件
  13. Number of Triplets
  14. python3+selenium3+IE自动化遇IE11下载弹窗遇阻
  15. 配置opencv,丢失 opencv_world300d.dll
  16. word导出html乱码怎么办,Word文档文件变成乱码如何完全修复?-修复百科
  17. html 块元素 css,HTML和CSS - 内嵌块元素的问题
  18. BitComet Stable (build 1.66.4.13) 比特彗星-使用教程
  19. 利用python计算fasta文件中ATGC的含量
  20. C语言与java中函数传参比较

热门文章

  1. shiro反序列化漏洞工具的使用
  2. 今日早报要闻内容12条
  3. 解决「无法格式化USB移动盘」错误
  4. Ubuntu22.04:CP210X驱动频繁掉线的问题解决
  5. 黔西南职称计算机,黔西南州人力资源和社会保障网2016第一次职称计算机考试科目...
  6. 在金融行业工作有哪些必须熟练掌握的 Excel 公式?
  7. 从草根到百万年薪程序员的十年风雨之路,细节爆炸
  8. 看完八条你肯定趴下,如不趴下算你狠!!!
  9. 快速接头 数字温度传感器 整体热电偶套管 气温传感器 测温传感器 温度传感器 温度传感器生产厂家 温度变送器 温度感应器 温度测量 热电偶 热电偶传感器 热电偶套管 热电偶温度传感器 热电偶温度计
  10. php松下,看看体验松下hhlt0623和yeelight区别是?哪个好?深度剖析内幕