在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對應的音頻,將無法找到。