(九十五)音效播放方法和工具类的制作

音效通过AVFoundation框架实现,是通过函数而不是方法,因此需要进行桥接等操作,具体步骤如下。

进行音效播放,首先要得到音效的URL(只能是本地音频),然后转换为音效ID(唯一),通过ID播放音效。

【音效播放方法】

①导入框架主头文件

#import <AVFoundation/AVFoundation.h>

②通过Bundle拿到本地音效,然后调用AudioServicesCreateSystemSoundID函数得到音效ID,ID为0代表无效,以此为依据可进行懒加载

@interface ViewController ()
@property (nonatomic, assign) SystemSoundID soundID;
@end

@implementation ViewController

- (SystemSoundID)soundID{
    
    if (!_soundID) {
        //    AudioServicesPlayAlertSound(<#SystemSoundID inSystemSoundID#>) // 播放+震动
        //    AudioServicesPlaySystemSound(<#SystemSoundID inSystemSoundID#>) // 只播放不震动
        
        // 首先要创建音效ID, 只能播放本地音效,音频相关通过C实现,需要桥接。
        NSURL *url = [[NSBundle mainBundle] URLForResource:@"xxx.wav" withExtension:nil];
        SystemSoundID soundID;
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
        
        _soundID = soundID;
    }
    
    return _soundID;
    
}

③调用AudioServicesPlaySystemSound传入ID来播放音效

AudioServicesPlaySystemSound(self.soundID);

【工具类的抽取】

工具类通过类方法实现传入文件名自动播放音效,并且包含懒加载,当收到内存警告时,还可以调用删除单个音效和所有音效的方法,通过字典存储音效ID。

//
//  SGAudioTool.h
//  音效播放
//
//  Created by 11 on 7/28/15.
//  Copyright (c) 2015 soulghost. All rights reserved.
//

#import <Foundation/Foundation.h>

/*
 iOS默认能播放的音频格式
 硬件解码:AAC ALAC HE-AAC MP3 CAF (硬件解码同一时间只支持一个音频)
 软件解码:AAC ALAC iLBC IMA4 Linea PCM MP3 CAF U-law and a-law
 */

// 系统自带的音频转换
// afconvert
// 转aac afconvert -f adts -d aac buyao.wav

@interface SGAudioTool : NSObject

+ (void)playAudioWithName:(NSString *)audioName;

+ (void)disposeAudioWithAudioName:(NSString *)audioName;

+ (void)disposeAll;

@end
//
//  SGAudioTool.m
//  音效播放
//
//  Created by 11 on 7/28/15.
//  Copyright (c) 2015 soulghost. All rights reserved.
//

#import "SGAudioTool.h"
#import <AVFoundation/AVFoundation.h>

@implementation SGAudioTool

static NSMutableDictionary *_soundIDs;

+ (void)initialize{
    // 第一次使用类时调用的公共初始化类方法。
    _soundIDs = [NSMutableDictionary dictionary];
    
}

+ (void)playAudioWithName:(NSString *)audioName{
    
    // 判断文件名是否为空
    if(audioName == nil){
        NSLog(@"文件名不能为空");
        return;
    }
    SystemSoundID soundID = [_soundIDs[audioName] unsignedIntValue]; // nil的uintvalue=0,也就是没有记录过的ID=0
    if (!soundID) {
        NSURL *url = [[NSBundle mainBundle] URLForResource:audioName withExtension:nil];
        // 判断url是否有效
        if (url == nil) {
            NSLog(@"找不到文件");
            return;
        }
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
        _soundIDs[audioName] = @(soundID);
    }
    
    AudioServicesPlaySystemSound(soundID);
    
    
}

+ (void)disposeAudioWithAudioName:(NSString *)audioName{
    
    if (audioName == nil) {
        return;
    }
    
    SystemSoundID soundID = [_soundIDs[audioName] unsignedIntValue];
    if (soundID) {
        AudioServicesDisposeSystemSoundID(soundID);
        [_soundIDs removeObjectForKey:audioName];
    }

}

+ (void)disposeAll{
    
    for (NSString *audioName in _soundIDs) {
        NSLog(@"%@",audioName);
        SystemSoundID soundID = [_soundIDs[audioName] unsignedIntValue];
        AudioServicesDisposeSystemSoundID(soundID);
    }
    
    [_soundIDs removeAllObjects];
    
}

@end

原文地址:https://www.cnblogs.com/aiwz/p/6154099.html