1. 程式人生 > >73_iOS乾貨39_iOS系統音訊彙總

73_iOS乾貨39_iOS系統音訊彙總

一,背景

最近在做系統音訊的總結,網上大多是一些前人的經驗之談,而少有自己探究,所以要來個總結

二,獲取系統音訊

  • 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

六,優缺點

  1. 才用C語言封裝,節省記憶體
  2. 檔案播放型別有限
  3. 不能及時根據音量開關,調整音訊的大小;
  4. 不能控制聲道
  5. 更加高階的音訊用法,可以參考播放器框架AVPlayer和AVAudioPlayer,後續會繼續研究