美文网首页
音效的实现

音效的实现

作者: MONKEY小巧 | 来源:发表于2016-05-05 13:42 被阅读106次
    在很多游戏中,当执行某个动作的时候,会发出声音。或者在设置界面,点击按钮的时候也会发出声音。这些声音一般比较短,瞬间就可以播放完。这就是音效,时间长度在30秒之内的音频,我们把它们归为音效播放。

    iOS中播放音效和音乐需要用不同的方式。###

    基本实现步骤:

    1.导入框架,AVFoundation
    2.创建音效文件
    3.AudioServicesCreateSystemSoundID,C语言的方法,涉及到CF的内容,需要桥接
    4.在mainBundle中,获取音频文件的URL
    5.两种播放方式
    不带震动的播放
    带震动的播放,真机才有效果
    6.清空音效
    如果不需要播放了,需要释放音效所占用的内存

    工具类方法:

    VRAudioTools.h

    #import <Foundation/Foundation.h>
    #import <AVFoundation/AVFoundation.h>
    
    @interface VRAudioTools : NSObject
    
    /** 播放系统音效*/
    + (void)playSystemSoundWithURL:(NSURL *)url;
    
    /** 播放震动音效*/
    + (void)playAlertSoundWithURL:(NSURL *)url;
    
    /** 清空音效文件的内存*/
    + (void)clearMemory;
    
    @end
    

    VRAudioTools.m

    /** 缓存字典*/
    static NSMutableDictionary *_soundIDDict;
    
    @implementation VRAudioTools
    
    // 只要头文件参与了编译调用
    //+ (void)load
    
    /** 缓存字典初始化*/
    + (void)initialize
    {
        _soundIDDict = [NSMutableDictionary dictionary];
    }
    
    + (void)playSystemSoundWithURL:(NSURL *)url
    {
        // 不带震动的播放
        AudioServicesPlaySystemSound([self loadSoundIDWithURL:url]);
    }
    
    /** 播放震动音效*/
    + (void)playAlertSoundWithURL:(NSURL *)url
    {
        // 带震动的播放
        AudioServicesPlayAlertSound([self loadSoundIDWithURL:url]);
    
    }
    
    #pragma mark 播放音效的公用方法
    + (SystemSoundID)loadSoundIDWithURL:(NSURL *)url
    {
        // 思路思路
        // soundID重复创建 --> soundID每次创建, 就会有对应的URL地址产生
        // 可以将创建后的soundID 及 对应的URL 进行缓存处理
        
        //1. 获取URL的字符串
        NSString *urlStr = url.absoluteString;
        
        //2. 从缓存字典中根据URL来取soundID 系统音效文件,SystemSoundID==UInt32
        SystemSoundID soundID = [_soundIDDict[urlStr] intValue];
        
        //需要在刚进入的时候, 判断缓存字典是否有url对应的soundID
        
        //3. 判断soundID是否为0, 如果为0, 说明没有找到, 需要创建
        if (soundID == 0) {
            //3.1 创建音效文件
            AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundID);
            
            //3.2 缓存字典的添加键值
            _soundIDDict[urlStr] = @(soundID);
        }
        
        return soundID;
    }
    
    
    /** 清空音效文件的内存*/
    + (void)clearMemory
    {
        //1. 遍历字典
        [_soundIDDict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            
            //2. 清空音效文件的内存
            SystemSoundID soundID = [obj intValue];
            AudioServicesDisposeSystemSoundID(soundID);
        }];
    }
    
    @end
    

    在需要播放音效的控制器文件中调用:

    #pragma mark 点击播放音效
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        //1. 获取URL地址
        NSURL *url = [[NSBundle mainBundle] URLForResource:@"xxx.wav" withExtension:nil];
        
        //2. 调用工具类播放音效
        //[VRAudioTools playSystemSoundWithURL:url];
        
        [VRAudioTools playAlertSoundWithURL:url];
        
    }
    #pragma mark 当前控制器收到内存警告时会调用的方法
    - (void)didReceiveMemoryWarning
    {
        // 局部音效需要在这里进行释放
        [VRAudioTools clearMemory];
        NSLog(@"%s",__func__);
    }
    

    当需要释放全局的音效的时候(比如多个控制器里都有音效需要释放)要在 AppDelegate里释放

    AppDelegate.m

    
    #pragma mark 清空全局的音效文件
    - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
    {
        [VRAudioTools clearMemory];
        //NSLog(@"%s",__func__);
    }```

    相关文章

      网友评论

          本文标题:音效的实现

          本文链接:https://www.haomeiwen.com/subject/evedrttx.html