73_iOS乾貨39_iOS系統音訊彙總
阿新 • • 發佈:2018-11-15
一,背景
最近在做系統音訊的總結,網上大多是一些前人的經驗之談,而少有自己探究,所以要來個總結
二,獲取系統音訊
- 1,系統音訊的名稱和soundID大多數可以參考wiki的:http://iphonedevwiki.net/index.php/AudioServices,網頁是2011年更新的,預計是早期的系統音訊,soundID範圍在1000~1350;
- 2,獲取最新系統的名稱和soundID:得到/System/Library/Audio/UISounds一級目錄下的檔案269個,算上二級目錄一共466個,soundID的範圍在5053~5518,猜想iOS系統更新後,音訊也會跟著更新
- 3,重要:一定要在真機的情況下獲取,否則無效;
//獲取目錄/System/Library/Audio/UISounds下的url陣列 NSFileManager *fileManager = [[NSFileManager alloc] init]; NSURL *directoryURL = [NSURL URLWithString:@"/System/Library/Audio/UISounds"]; NSArray *keys = [NSArray arrayWithObject:NSURLIsDirectoryKey]; NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:directoryURL includingPropertiesForKeys:keys options:0 errorHandler:^(NSURL *url, NSError *error) { // Handle the error. // Return YES if the enumeration should continue after the error. return YES; }]; //再遍歷/System/Library/Audio/UISounds下資料夾裡的子資料夾檔案陣列 for (NSURL *url in enumerator) { NSError *error; NSNumber *isDirectory = nil; if (! [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error]) { // handle error }else if (! [isDirectory boolValue]) { [_audioFileList addObject:url]; }else { // 資料夾層級 NSDirectoryEnumerator *newEnumerator = [fileManager enumeratorAtURL:url includingPropertiesForKeys:keys options:0 errorHandler:^(NSURL *url, NSError *error) { return YES; }]; for (NSURL *url in newEnumerator) { NSError *error; NSNumber *isDirectory = nil; if (! [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error]) { // handle error }else if (! [isDirectory boolValue]) { [_audioFileList addObject:url]; }else { }; }; } };
三,自定義本地音訊
音訊檔案不超過30s
四,播放音訊
封裝的工具類核心程式碼如下:
#pragma mark - 系統音效1:檔案全稱 - (void)playSystemSoundWith:(NSString *)fileName { if (!_soundID) { NSString *path = [NSString stringWithFormat:@"/System/Library/Audio/UISounds/%@",fileName]; if (path) { // 註冊系統檔案 OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path],&_soundID); if (error != kAudioServicesNoError) {//獲取的聲音的時候,出現錯誤 _soundID = 0; } } }; [self play]; } #pragma mark - 系統音效2:檔名 + 型別 - (void)playSystemSoundWith:(NSString *)fileName fileType:(NSString *)fileType { if (!_soundID) { NSString *path = [NSString stringWithFormat:@"/System/Library/Audio/UISounds/%@.%@",fileName,fileType]; if (path) { // 註冊系統檔案 OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path],&_soundID); if (error != kAudioServicesNoError) {//獲取的聲音的時候,出現錯誤 _soundID = 0; } } }; [self play]; } #pragma mark - 自定義音效1:bundle檔案全稱 - (void)playSelfdefinedSoundInBundleWith:(NSString *)fileName { if (!_soundID) { NSURL *fileURL = [[NSBundle mainBundle] URLForResource:fileName withExtension:nil]; if (fileURL != nil) { //使用本地 SystemSoundID theSoundID; OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)fileURL, &theSoundID); if (error == kAudioServicesNoError){ _soundID = theSoundID; }else { NSLog(@"Failed to create sound "); } }else { //使用系統 [self playSystemSoundWith: @"Tock" fileType:@"caf"]; } }; [self play]; } #pragma mark - 自定義音效2:bundle檔名 + 型別 - (void)playSelfdefinedSoundInBundleWith:(NSString *)fileName fileType:(NSString *)fileType { if (!_soundID) { NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:fileType]; if (path) { //使用本地 SystemSoundID theSoundID; OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &theSoundID); if (error == kAudioServicesNoError) { _soundID = theSoundID; }else { NSLog(@"Failed to create sound "); } } else { //使用系統 [self playSystemSoundWith:@"Tock" fileType:@"caf"]; } }; [self play]; } #pragma mark - 自定義音效3:沙盒檔案 - (void)playSelfdefinedSoundInDocumentWith:(NSString *)fileName { if (!_soundID) { NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *path = [documents stringByAppendingPathComponent:fileName]; if (path) { // 註冊系統檔案 OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path],&_soundID); if (error != kAudioServicesNoError) {//獲取的聲音的時候,出現錯誤 _soundID = 0; } } }; [self play]; } #pragma mark - 開啟聲音 - (void)play { AudioServicesPlaySystemSound(_soundID); } #pragma mark - 停止聲音 - (void)stop { _soundID = 0; } #pragma mark - 銷燬 - (void)dealloc { AudioServicesDisposeSystemSoundID(_soundID); } @end
五,音訊轉換
下載一個工具軟體,可以對已有的音訊進行編輯處理,https://pan.baidu.com/s/1b5hsqf33k96Z7udQbVyb9Q
六,優缺點
- 才用C語言封裝,節省記憶體
- 檔案播放型別有限
- 不能及時根據音量開關,調整音訊的大小;
- 不能控制聲道
- 更加高階的音訊用法,可以參考播放器框架AVPlayer和AVAudioPlayer,後續會繼續研究