1.關於音效
音效又稱短音頻,是一個聲音文件,在應用程序中起到點綴效果,用於提升應用程序的整體用戶體驗。
我們手機裡常見的APP幾乎都少不了音效的點綴。
顯示實現音效並不復雜,但對我們App很重要!
2.音效播放
2.1.首先實現我們需要導入框架AudioToolbox.framework
2.2.為了優化效播放,減少每次重復加載音效播放,我們將加載音效設為單例
實現單例 —— 將我在前幾篇文章說過封裝好的的單例宏 直接引用 Singleton.h
創建
Singleton.h
復制代碼
#import <Foundation/Foundation.h>
#import "Singleton.h"
@interface SoundTools : NSObject
//單例宏
singleton_interface(SoundTools)
//要播放的音效名
- (void)playSoundWithName:(NSString *)name;
@end
復制代碼
將APP要用到的音效添加到新建的bound裡去
如圖:
創建
Singleton.m
復制代碼
#import "SoundTools.h"
#import <AudioToolbox/AudioToolbox.h>
/**
將所有的音頻文件在此單例中統一處理
*/
@interface SoundTools()
{
NSDictionary *_soundDict; // 音頻字典
}
@end
@implementation SoundTools
singleton_implementation(SoundTools)
- (id)init
{
self = [super init];
if (self) {
// 完成所有音頻文件的加載工作
_soundDict = [self loadSounds];
}
return self;
}
復制代碼
2.3.啟動系統聲音服務
系統聲音服務通過SystemSoundID來播放聲音文件,對於同一個聲音文件,可以創建多個SystemSoundID
系統聲音服務是一套C語言的框架
為了提高應用程序性能,避免聲音文件被重復加載,通常采用單例模式處理系統聲音的播放
Singleton.m 實現
復制代碼
#pragma mark 加載指定的音頻文件
- (SystemSoundID)loadSoundWithURL:(NSURL *)url
{
SystemSoundID soundID = 0;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
return soundID;
}
復制代碼
2.4.加載bound裡所有的音效文件,並記錄進全局的字典中
復制代碼
#pragma mark 加載所有的音頻文件
- (NSDictionary *)loadSounds
{
// 思考:如何直到加載哪些音頻文件呢?
// 建立一個sound.bundle,存放所有的音效文件
// 在程序執行時,直接遍歷bundle中的所有文件
// 1. 取出bundle的路徑名
NSString *mainBundlPath = [[NSBundle mainBundle] bundlePath];
NSString *bundlePath =[mainBundlPath stringByAppendingPathComponent:@"sound.bundle"];
// 2. 遍歷目錄
NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:bundlePath error:nil];
// 3. 遍歷數組,創建SoundID,如何使用?
NSMutableDictionary *dictM = [NSMutableDictionary dictionaryWithCapacity:array.count];
[array enumerateObjectsUsingBlock:^(NSString *fileName, NSUInteger idx, BOOL *stop) {
// 1> 拼接URL
NSString *filePath = [bundlePath stringByAppendingPathComponent:fileName];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
SystemSoundID soundID = [self loadSoundWithURL:fileURL];
// 將文件名作為鍵值
[dictM setObject:@(soundID) forKey:fileName];
}];
return dictM;
}
復制代碼
2.5.播放音頻
注意 斷言:在項目開發中,防止被無意中修改音效名,找不到要播放的音效文件
復制代碼
#pragma mark - 播放音頻
- (void)playSoundWithName:(NSString *)name
{
SystemSoundID soundID = [_soundDict[name] unsignedLongValue];
NSLog(@"%ld",soundID);
//斷言它必須大於0;
NSAssert(soundID > 0, @"%@ 聲音文件不存在!", name);
AudioServicesPlaySystemSound(soundID);
}
復制代碼
在控制器裡調用按鈕的點擊事情即可
- (void)clickMe
{
[[SoundTools sharedSoundTools] playSoundWithName:@"game_overs.mp3"];
}
2.6.優化之前的代碼 —— 每次都會重復加載新的音效
復制代碼
// NSURL *url = [[NSBundle mainBundle] URLForResource:@"bullet.mp3" withExtension:nil];
// SystemSoundID soundID = 0;
//
// // 創建聲音,並且生成soundID的數值
// AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
//
// // 播放聲音
// // 同樣遵守蘋果的靜音原則,如果用戶靜音,會震動!提示用戶注意!
//// AudioServicesPlayAlertSound(<#SystemSoundID inSystemSoundID#>)
// // 只播放聲音,遵守蘋果的靜音原則 HIG
// AudioServicesPlaySystemSound(soundID);
//
// NSLog(@"%ld", soundID);
復制代碼