iOS中支持的音頻播放類型
播放音效System Sound Service
播放本地音頻AVFoundataion
播放流媒體音頻Audio Queue Service
簡單來說,音頻可以分為2種
音效
又稱短音頻
,通常在程序中的播放時(shí)長為1~2秒
在應(yīng)用程序中起到點(diǎn)綴效果,提升整體用戶體驗(yàn)
音樂
比如游戲中的背景音樂,一般播放時(shí)間較長
1.音效的播放
音效
又稱短音頻
,是一個(gè)聲音文件
,在應(yīng)用程序中起到點(diǎn)綴效果
,用于提升應(yīng)用程序的整體用戶體驗(yàn)
通常短音效在程序中的播放時(shí)長為1~2秒
,對于某些特殊動畫效果的點(diǎn)綴音效可以略長
由于音效的播放相對比較頻繁
,為了不影響應(yīng)用程序的性能
,在實(shí)際應(yīng)用中通常使用非壓縮的音頻格式(AIFF)或者CAF音頻格式
,從而減低系統(tǒng)在音頻解碼上的消耗
,達(dá)到省電
的目的
使用系統(tǒng)聲音服務(wù)播放音效
,需要導(dǎo)入AudioToolbox框架
系統(tǒng)聲音服務(wù)通過SystemSoundID
來播放聲音文件,對于同一個(gè)聲音文件,可以創(chuàng)建多個(gè)SystemSoundID
系統(tǒng)聲音服務(wù)是一套C語言的框架
為了提高應(yīng)用程序性能,避免聲音文件被重復(fù)加載,通常采用單例模式處理系統(tǒng)聲音的播放
// 1.獲得音效文件的路徑
NSURL *url = [[NSBundle mainBundle] URLForResource:@"m_03.wav" withExtension:nil];
// 2.加載音效文件,得到對應(yīng)的音效ID
SystemSoundID soundID = 0;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
// 3.播放音效
AudioServicesPlaySystemSound(soundID);
音效文件只需要加載1次
音效播放常見函數(shù)總結(jié)
加載音效文件
AudioServicesCreateSystemSoundID(CFURLRef inFileURL, SystemSoundID *outSystemSoundID)
釋放音效資源
AudioServicesDisposeSystemSoundID(SystemSoundID inSystemSoundID)
播放音效
AudioServicesPlaySystemSound(SystemSoundID inSystemSoundID)
播放音效同時(shí)振動(當(dāng)用戶靜音時(shí),可以通過振動提示用戶注意重要操作)
AudioServicesPlayAlertSound(SystemSoundID inSystemSoundID)
注意:硬件解碼器一次只能對一個(gè)音頻文件解碼。在實(shí)際應(yīng)用中通常使用非壓縮的音頻格式(AIFF)或者CAF音頻格式,從而減低系統(tǒng)在音頻解碼上的消耗,達(dá)到省電的目的
2.音頻轉(zhuǎn)換工具
轉(zhuǎn)換aiff格式
afconvert -f AIFF -d I8 filename
轉(zhuǎn)換caf格式
afconvert -f caff -d aac -b 32000 filename
批量轉(zhuǎn)換
find . -name '*.mp3' -exec afconvert -f caff -d aac -b 32000 {} \;
3.音樂的播放 AVAudioPlayer
使用AVAudioPlayer可以播放本地音樂,具備以下特點(diǎn):
能夠預(yù)先緩存,提高播放的流暢性prepareToPlay
播放起始時(shí)間playAtTime
播放控制play/pause/stop
循環(huán)播放次數(shù)numberOfLoops
播放音量volume
設(shè)置播放速度enableRate/rate
音量監(jiān)控meteringEnabled/peakPowerForChannel/averagePowerForChannel
還可以通過AVAudioPlayer的代理方法
監(jiān)控音樂的播放進(jìn)度
是否正在播放
@property(readonly, getter=isPlaying) BOOL playing;
時(shí)長
@property(readonly) NSTimeInterval duration;
當(dāng)前的播放位置
@property(readonly) NSTimeInterval currentTime;
播放次數(shù)(-1代表無限循環(huán)播放,其他代表播放numberOfLoops+1次)
@property NSInteger numberOfLoops;
音量
@property float volume;
是否允許更改速率
@property BOOL enableRate;
播放速率(1是正常速率,0.5是一般速率,2是雙倍速率)
@property float rate;
有多少個(gè)聲道
@property(readonly) NSUInteger numberOfChannels;
加載音樂文件
- (id)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError;
- (id)initWithData:(NSData *)data error:(NSError **)outError;
準(zhǔn)備播放(緩沖,提高播放的流暢性)
- (BOOL)prepareToPlay;
播放(異步播放)
- (BOOL)play;
暫停
- (void)pause;
停止
- (void)stop;
3.AVAudioSession單例
AVAudioSession是一個(gè)單例
,無需實(shí)例化即可直接使用。AVAudioSession在各種音頻環(huán)境中起著非常重要的作用
針對不同的音頻應(yīng)用場景,需要設(shè)置不同的音頻會話分類
AVAudioSessionCategoryAmbient
混音播放,例如雨聲、汽車引擎等,可與其他音樂一起播放
AVAudioSessionCategorySoloAmbient
后臺播放,其他音樂將被停止
AVAudioSessionCategoryPlayback
獨(dú)占音樂播放
AVAudioSessionCategoryRecord
錄制音頻
AVAudioSessionCategoryPlayAndRecord
播放和錄制音頻
AVAudioSessionCategoryAudioProcessing
使用硬件解碼器處理音頻,該音頻會話使用期間,不能播放或錄音
后臺播放音樂——設(shè)置后臺任務(wù)
+ (UIBackgroundTaskIdentifier)backgroundPlayerID:(UIBackgroundTaskIdentifier)backTaskId
{
// 1. 設(shè)置并激活音頻會話類別
AVAudioSession *session = [AVAudioSession sharedInstance];
[session AVAudioSessionCategoryPlayback error:nil];
[session setActive:YES error:nil];
// 2. 允許應(yīng)用程序接收遠(yuǎn)程控制
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
// 3. 設(shè)置后臺任務(wù)ID
UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;
newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
if (newTaskId != UIBackgroundTaskInvalid && backTaskId != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask:backTaskId];
}
return newTaskId;
}
// 后臺播放任務(wù)Id
UIBackgroundTaskIdentifier _bgTaskId;
// 設(shè)置音頻會話,允許后臺播放
_bgTaskId = [SoundTool backgroundPlayerID:_bgTaskId];
4.錄音
音頻錄音機(jī)參數(shù)字典
NSMutableDictionary *setting = [[NSMutableDictionary alloc] init];
// 音頻格式
[setting setValue:[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
// 音頻采樣率
[setting setValue:[NSNumber numberWithFloat:8000.0] forKey:AVSampleRateKey];
// 音頻通道數(shù)
[setting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
// 線性音頻的位深度
[setting setValue:[NSNumber numberWithInt:8]for Key:AVLinearPCMBitDepthKey];
return setting;
5.音頻隊(duì)列服務(wù)
在iOS
和Mac OS X
中,音頻隊(duì)列服務(wù)
提供了一種直接、低開銷
的方式來錄制
和播放音頻
。也是蘋果公司推薦
在iOS和Mac OS X程序中添加錄制和播放功能使用的技術(shù)
音頻隊(duì)列服務(wù)允許錄制和播放以下格式的音頻:
線性PCM(Linear PCM)
任何蘋果平臺原生支持的壓縮格式
任何用戶已經(jīng)安裝相應(yīng)編碼器的其他格式
音頻隊(duì)列服務(wù)是純C接口
的
音頻隊(duì)列的架構(gòu)
所有的音頻隊(duì)列都含有相同的基礎(chǔ)結(jié)構(gòu),其中包含:
一組音頻隊(duì)列緩沖區(qū)(audio queue buffers
),每個(gè)音頻隊(duì)列緩沖區(qū)都是一個(gè)存儲音頻數(shù)據(jù)的臨時(shí)倉庫,通常是3個(gè)
一個(gè)緩沖區(qū)隊(duì)列(buffer queue
),音頻隊(duì)列緩沖區(qū)的有序列表
一個(gè)自己編寫的音頻隊(duì)列回調(diào)函數(shù)(audio queue callback
)
在錄制音頻時(shí):回調(diào)函數(shù)負(fù)責(zé)將緩沖區(qū)中的數(shù)據(jù)寫入磁盤
在播放音頻時(shí):回調(diào)函數(shù)負(fù)責(zé)從磁盤加載音頻數(shù)據(jù)到緩沖區(qū)