实用知识:音效播放的方法使用

本文介绍了一个iOS应用中音效管理的实现方式,包括音效的创建、播放和销毁过程,并通过一个具体的ViewController类展示了如何利用SystemSoundID进行音效管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#import "ViewController.h"
#import "ModalVC.h"
#import "AudioTool.h"

// 处理Audio, Video相关
#import <AVFoundation/AVFoundation.h>

@interface ViewController ()

@property (assign, nonatomic) SystemSoundID soundID;
//@property (assign, nonatomic) SystemSoundID soundID2;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 音效, C语言API, 以AudioServices开头
    // 0. 音效依靠SoundID来识别
    // 1. 音效只需要创建一次, 就整个App都可以使用
    // 2. 两个音效同时播放时, 互相不影响
    // 3. 音效文件不提供暂停, 停止的功能
    // 4. 如果销毁正在播放的音效, 会中断播放
    // 5. 音效文件跟控制器的生命周期无关
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // Modal出控制器, 在ModalVC当中音效创建, 将SoundID回传
    ModalVC *modal = [[ModalVC alloc] init];
    modal.createSoundIDBlock = ^ (SystemSoundID soundID) {
        self.soundID = soundID;
    };

    [self presentViewController:modal animated:YES completion:nil];
}

- (IBAction)createBtnAction:(id)sender
{
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"xiaosheng.mp3" withExtension:nil];
    //    NSURL *url2 = [[NSBundle mainBundle] URLForResource:@"win.aac" withExtension:nil];

    //    SystemSoundID soundID;
    // 创建音效
    // 转换成CF的URL, 需要自己去管理cfUrl的内存
    CFURLRef cfUrl = CFBridgingRetain(url);
    AudioServicesCreateSystemSoundID(cfUrl, &_soundID);
    CFRelease(cfUrl);

    //    CFURLRef cfUrl2 = CFBridgingRetain(url2);
    //    AudioServicesCreateSystemSoundID(cfUrl2, &_soundID2);
    //    CFRelease(cfUrl2);
}

- (IBAction)playBtnAction:(id)sender
{
    /**
    // 播放音效, 根据SoundID对应的音效来播放
    AudioServicesPlaySystemSound(_soundID);

    //    AudioServicesPlaySystemSound(_soundID2);

    // 播放音效, 会抖动...
    //    AudioServicesPlayAlertSound(soundID);
     */

    NSURL *url = [[NSBundle mainBundle] URLForResource:@"xiaosheng.mp3" withExtension:nil];
    [AudioTool playAudioWithURL:url];
}

- (IBAction)disposeBtnAction:(id)sender
{
//    // 销毁音效, 不能再用
//    AudioServicesDisposeSystemSoundID(_soundID);

    [AudioTool disposeAll];
}

@end

#import <Foundation/Foundation.h>

@interface AudioTool : NSObject

/**
 *  播放指定URL的音效文件
 *
 *  @param url 音效文件的URL
 */
+ (void)playAudioWithURL:(NSURL *)url;

/**
 *  销毁所有缓存的音效
 */
+ (void)disposeAll;

@end




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

/**
 1. 负责管理所有音效的工具类, 类方法
 2. 缓存, (NSDictionary: Key - Value), 使用URL作为Key, NSNumber(SoundID)作为Value
 */

//@interface AudioTool ()

//@property (strong, nonatomic) NSMutableDictionary *cache;

//@end

static NSMutableDictionary *_cache;

@implementation AudioTool

// 当类加载到内存时, 就会调用, 只会调用一次
+ (void)load
{
    // 初始化
    _cache = [NSMutableDictionary dictionary];
}

// 当类第一次进行实例化时调用, 只会调用一次
//+ (void)initialize
//{
//    
//}

+ (void)playAudioWithURL:(NSURL *)url
{
    if (url == nil) {
        NSLog(@"URL不能为空");
        return;
    }

    // 1. 判断是否创建过音效
    NSNumber *number = _cache[url];

    // 2. 没有, 创建
    if (number == nil) {
        NSLog(@"创建了音效");
        SystemSoundID soundID;
        CFURLRef cfUrl = CFBridgingRetain(url);
        AudioServicesCreateSystemSoundID(cfUrl, &soundID);
        CFRelease(cfUrl);

        // 更新到number上
        number = [NSNumber numberWithUnsignedInt:soundID];

        // 添加到缓存当中
        _cache[url] = number;
    }

    // 3. 直接播放
    AudioServicesPlaySystemSound([number unsignedIntValue]);
}

+ (void)disposeAll
{
    // 销毁所有
    [_cache enumerateKeysAndObjectsUsingBlock:^(NSURL *key, NSNumber *obj, BOOL * _Nonnull stop) {

        AudioServicesDisposeSystemSoundID([obj unsignedIntValue]);
    }];

    // 清空缓存
    [_cache removeAllObjects];
}

@end
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ModalVC : UIViewController

@property (copy, nonatomic) void(^createSoundIDBlock)(SystemSoundID);

@end




#import "ModalVC.h"

@interface ModalVC ()

@end

@implementation ModalVC

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.view setBackgroundColor:[UIColor redColor]];

    CFURLRef url = CFBridgingRetain([[NSBundle mainBundle] URLForResource:@"win.aac" withExtension:nil]);

    // 创建一个音效
    SystemSoundID soundID;
    AudioServicesCreateSystemSoundID(url, &soundID);
    CFRelease(url);

    // 返回给别人
    if (self.createSoundIDBlock) {
        self.createSoundIDBlock(soundID);
    }
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"我走了");
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值