在ios開發中,有時候我們需要頻繁播放某種提示聲音,比如微博刷新提示音、QQ消息提示音等,對於這些短小且需要頻繁播放的音頻,最好將其加入到系統聲音(system sound)里。
注意:
- 需要播放的音頻文件不能超過30秒
- 必須是IMA/ADPCM格式[in linear PCM or IMA4(IMA/ADPCM) format]
- 必須是.caf .aif .wav文件
1、自定義系統聲音
// 要播放的音頻文件地址 NSString *urlPath = [[NSBundle mainBundle] pathForResource:@"end_refreshing" ofType:@"wav"]; NSURL *url = [NSURL fileURLWithPath:urlPath]; // 聲明需要播放的音頻文件ID[unsigned long] SystemSoundID ID; // 創建系統聲音,同時返回一個ID AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &ID);
2、根據自定義系統聲音時傳入的ID,播放自定義系統聲音
// 根據ID播放自定義系統聲音 AudioServicesPlaySystemSound(ID);
3、有時候我們需要在完成播放的時候做一些事情,比如繼續播放下一個音頻或者提示用戶,或者決定以后都不再使用該音頻ID了,可以在下面的函數中移除該音頻ID
// 播放完成后執行的操作 /* *參數說明: * 1、剛剛播放完成自定義系統聲音的ID * 2、回調函數(playFinished)執行的run Loop,NULL表示main run loop * 3、回調函數執行所在run loop的模式,NULL表示默認的run loop mode * 4、需要回調的函數 * 5、傳入的參數, 此參數會被傳入回調函數里 */ AudioServicesAddSystemSoundCompletion(ID, NULL, NULL, &playFinished, (__bridge void *)(self)); }
@implementation與@interface外部自定義一個函數,然后傳入這個函數名的地址
void playFinished(SystemSoundID ssID, void* clientData) { unsigned long ID = ssID; // ssID 不能直接作為參數打印出來,需要中轉一次 NSLog(@"播放完成-傳入ID為-%lu,傳入的參數為%@", ID, clientData); // 移除完成后執行的函數 AudioServicesRemoveSystemSoundCompletion(ID); // 根據ID釋放自定義系統聲音 AudioServicesDisposeSystemSoundID(ID); }
這樣就可以實現播放完成后調用預先定義好的函數playfinished(),繼續做一些你希望的事情,但是別忘了,ARC中C語言函數需要自己管理內存,所以這里,我們需要回調完成后移除剛剛添加的操作 ,並且確認當你以后不再需要播放該ID的音頻時,清理該ID音頻對應的所有資源
4、完成以上步驟就可以進行簡單的通過自定義系統聲音來播放簡單且頻繁的音頻文件了。
注意:
1 > 必須等到播放完成才能清理該ID對應的所有資源,也就是說,如果我們打算不再使用該音頻,可以在完成后調用的函數(playFinished)里清理資源,如上例所示。 不過一般情況下,既然加到系統聲音里的多是頻繁使用的,可以在程序結束或者某個控制器銷毀的時候再清理。
2 > 如果在AudioServicesPlaySystemSound(ID)之后馬上調用AudioServicesDisposeSystemSoundID(ID),你將聽不到任何聲音,並且也不會調用播放完成后的函數, 這是因為,系統音頻播放的所有操作都是放到主線程之外執行的,當主線程執行到清理的時候,該音頻如果試圖播放ID對應的音頻,將無法找到。
5、哦,還有震動~ 一句話
// 播放系統預定義的音效,kSystemSoundID_Vibrate代表震動,如果有其它需求可以點進頭文件里去找相應的提示音類型 AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
以上內容純屬個人理解,如有不當之處歡迎留言。