iOS音频

iOS中支持的音频播放类型
播放音效System Sound Service
播放本地音频AVFoundataion
播放流媒体音频Audio Queue Service

简单来说,音频可以分为2种
音效
又称短音频,通常在程序中的播放时长为1~2秒
在应用程序中起到点缀效果,提升整体用户体验

音乐
比如游戏中的背景音乐,一般播放时间较长

1.音效的播放

音效又称短音频,是一个声音文件,在应用程序中起到点缀效果,用于提升应用程序的整体用户体验
通常短音效在程序中的播放时长为1~2秒,对于某些特殊动画效果的点缀音效可以略长
由于音效的播放相对比较频繁,为了不影响应用程序的性能,在实际应用中通常使用非压缩的音频格式(AIFF)或者CAF音频格式,从而减低系统在音频解码上的消耗,达到省电的目的
使用系统声音服务播放音效,需要导入AudioToolbox框架
系统声音服务通过SystemSoundID来播放声音文件,对于同一个声音文件,可以创建多个SystemSoundID
系统声音服务是一套C语言的框架
为了提高应用程序性能,避免声音文件被重复加载,通常采用单例模式处理系统声音的播放

// 1.获得音效文件的路径
NSURL *url = [[NSBundle mainBundle] URLForResource:@"m_03.wav" withExtension:nil];

// 2.加载音效文件,得到对应的音效ID
SystemSoundID soundID = 0;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);

// 3.播放音效
AudioServicesPlaySystemSound(soundID);

音效文件只需要加载1次

音效播放常见函数总结

加载音效文件
AudioServicesCreateSystemSoundID(CFURLRef inFileURL, SystemSoundID *outSystemSoundID)

释放音效资源
AudioServicesDisposeSystemSoundID(SystemSoundID inSystemSoundID)

播放音效
AudioServicesPlaySystemSound(SystemSoundID inSystemSoundID)

播放音效同时振动(当用户静音时,可以通过振动提示用户注意重要操作)
AudioServicesPlayAlertSound(SystemSoundID inSystemSoundID)
1-音效格式.png

注意:硬件解码器一次只能对一个音频文件解码。在实际应用中通常使用非压缩的音频格式(AIFF)或者CAF音频格式,从而减低系统在音频解码上的消耗,达到省电的目的

2.音频转换工具

转换aiff格式

afconvert -f AIFF -d I8 filename

转换caf格式

afconvert -f caff -d aac -b 32000 filename

批量转换

find . -name '*.mp3' -exec afconvert -f caff -d aac -b 32000 {} \;

3.音乐的播放 AVAudioPlayer

使用AVAudioPlayer可以播放本地音乐,具备以下特点:

能够预先缓存,提高播放的流畅性prepareToPlay
播放起始时间playAtTime
播放控制play/pause/stop
循环播放次数numberOfLoops
播放音量volume
设置播放速度enableRate/rate
音量监控meteringEnabled/peakPowerForChannel/averagePowerForChannel

还可以通过AVAudioPlayer的代理方法监控音乐的播放进度

是否正在播放
@property(readonly, getter=isPlaying) BOOL playing;

时长
@property(readonly) NSTimeInterval duration;

当前的播放位置
@property(readonly) NSTimeInterval currentTime;

播放次数(-1代表无限循环播放,其他代表播放numberOfLoops+1次)
@property NSInteger numberOfLoops;

音量
@property float volume;

是否允许更改速率
@property BOOL enableRate;

播放速率(1是正常速率,0.5是一般速率,2是双倍速率)
@property float rate;

有多少个声道
@property(readonly) NSUInteger numberOfChannels;

加载音乐文件
- (id)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError;
- (id)initWithData:(NSData *)data error:(NSError **)outError;

准备播放(缓冲,提高播放的流畅性)
- (BOOL)prepareToPlay;

播放(异步播放)
- (BOOL)play;

暂停
- (void)pause;

停止
- (void)stop;

3.AVAudioSession单例

AVAudioSession是一个单例,无需实例化即可直接使用。AVAudioSession在各种音频环境中起着非常重要的作用
针对不同的音频应用场景,需要设置不同的音频会话分类

AVAudioSessionCategoryAmbient
混音播放,例如雨声、汽车引擎等,可与其他音乐一起播放

AVAudioSessionCategorySoloAmbient
后台播放,其他音乐将被停止

AVAudioSessionCategoryPlayback
独占音乐播放

AVAudioSessionCategoryRecord
录制音频

AVAudioSessionCategoryPlayAndRecord
播放和录制音频

AVAudioSessionCategoryAudioProcessing
使用硬件解码器处理音频,该音频会话使用期间,不能播放或录音
2-AVAudioSessionCategory音频会话分类.png

后台播放音乐——设置后台任务

+ (UIBackgroundTaskIdentifier)backgroundPlayerID:(UIBackgroundTaskIdentifier)backTaskId
{
    // 1. 设置并激活音频会话类别
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session AVAudioSessionCategoryPlayback error:nil];
    [session setActive:YES error:nil];
    // 2. 允许应用程序接收远程控制
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    // 3. 设置后台任务ID
    UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;
    newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
    if (newTaskId != UIBackgroundTaskInvalid && backTaskId != UIBackgroundTaskInvalid) {
        [[UIApplication sharedApplication] endBackgroundTask:backTaskId];
    }
    return newTaskId;
}
3-AirPlay.png
// 后台播放任务Id
UIBackgroundTaskIdentifier  _bgTaskId;

// 设置音频会话,允许后台播放
_bgTaskId = [SoundTool backgroundPlayerID:_bgTaskId];

4.录音

音频录音机参数字典

NSMutableDictionary *setting = [[NSMutableDictionary alloc] init];

// 音频格式
[setting setValue:[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
// 音频采样率
[setting setValue:[NSNumber numberWithFloat:8000.0] forKey:AVSampleRateKey];
// 音频通道数
[setting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
// 线性音频的位深度
[setting setValue:[NSNumber numberWithInt:8]for Key:AVLinearPCMBitDepthKey];

return setting;
4-AVAudioRecorder录音.png

5.音频队列服务

iOSMac OS X中,音频队列服务提供了一种直接、低开销的方式来录制播放音频。也是苹果公司推荐在iOS和Mac OS X程序中添加录制和播放功能使用的技术

音频队列服务允许录制和播放以下格式的音频:
线性PCM(Linear PCM)
任何苹果平台原生支持的压缩格式
任何用户已经安装相应编码器的其他格式

音频队列服务是纯C接口

音频队列的架构

所有的音频队列都含有相同的基础结构,其中包含:

一组音频队列缓冲区(audio queue buffers),每个音频队列缓冲区都是一个存储音频数据的临时仓库,通常是3个
一个缓冲区队列(buffer queue),音频队列缓冲区的有序列表
一个自己编写的音频队列回调函数(audio queue callback

在录制音频时:回调函数负责将缓冲区中的数据写入磁盘
在播放音频时:回调函数负责从磁盘加载音频数据到缓冲区

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

推荐阅读更多精彩内容