加载声音资源的工具

@interface HMAudioTool : NSObject
// 播放音效
// 传入需要 播放的音效文件名称
+ (void)playAudioWithFilename:(NSString  *)filename;


// 销毁音效
+ (void)disposeAudioWithFilename:(NSString  *)filename;
@end




@implementation HMAudioTool


static NSMutableDictionary *_soundIDs;
/*
+ (void)initialize
{
    _soundIDs = [NSMutableDictionary dictionary];
}
 */


+ (NSMutableDictionary *)soundIDs
{
    if (!_soundIDs) {
        _soundIDs = [NSMutableDictionary dictionary];
    }
    return _soundIDs;
}


+ (void)playAudioWithFilename:(NSString *)filename
{
    /*
    // -1.创建URL
    NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
    
    // 0.创建音效ID
    SystemSoundID soundID;
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
    
    // 1.播放音效(本地音效)
#warning ios8的模拟器不支持播放音效(真机可以)
    AudioServicesPlaySystemSound(soundID);
     */
    // 0.判断文件名是否为nil
    if (filename == nil) {
        return;
    }
    
    // 1.从字典中取出音效ID
    SystemSoundID soundID = [[self soundIDs][filename] unsignedIntValue];
    
    // 判断音效ID是否为nil
    if (!soundID) {
        NSLog(@"创建新的soundID");
        
        // 音效ID为nil
        // 根据文件名称加载音效URL
        NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
        
        // 判断url是否为nil
        if (!url) {
            return;
        }
        
        // 创建音效ID
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
        
        // 将音效ID添加到字典中
        [self soundIDs][filename] = @(soundID);
    }
    // 播放音效
    AudioServicesPlaySystemSound(soundID);
}


+ (void)disposeAudioWithFilename:(NSString *)filename
{
    // 0.判断文件名是否为nil
    if (filename == nil) {
        return;
    }
    
    // 1.从字典中取出音效ID
    SystemSoundID soundID = [[self soundIDs][filename] unsignedIntValue];
    
    if (soundID) {
        // 2.销毁音效ID
        AudioServicesDisposeSystemSoundID(soundID);
        
        // 3.从字典中移除已经销毁的音效ID
        [[self soundIDs] removeObjectForKey:filename];
    }
  
}
@end






//调用音频工具类
@implementation ViewController


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"%s", __func__);
    
    /*
    // -1.创建URL
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"buyao.wav" withExtension:nil];
    
    // 0.创建音效ID
    SystemSoundID soundID;
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
    
    // 1.播放音效(本地音效)
#warning ios8的模拟器不支持播放音效(真机可以)
    AudioServicesPlaySystemSound(soundID);
     */
    
    // 1.播放音效(本地音效)
//    AudioServicesPlaySystemSound(self.soundID);
    
    // 利用工具类播放音效
//    [HMAudioTool playAudioWithFilename:@"buyao.wav"];
    
    
    // 随机播放
//    NSString *filename = [NSString stringWithFormat:@"m_%02d.wav", arc4random_uniform(14) + 3];
//    [HMAudioTool playAudioWithFilename:filename];
    
    // 同一时刻播放多个音效
//    [HMAudioTool playAudioWithFilename:@"m_17.wav"];
//    [HMAudioTool playAudioWithFilename:@"buyao.wav"];
    
    // 利用AudioServicesPlaySystemSound播放音乐, 但是注意: 真实开发中不建议使用该函数播放音乐
    [HMAudioTool playAudioWithFilename:@"normal.aac"];


}


// 接收到内存警告
- (void)didReceiveMemoryWarning
{
    [HMAudioTool disposeAudioWithFilename:@"buyao.wav"];
}


/*
- (SystemSoundID)soundID
{
    if (!_soundID) {
        // -1.创建URL
        NSURL *url = [[NSBundle mainBundle] URLForResource:@"buyao.wav" withExtension:nil];
        
        // 0.创建音效ID
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &_soundID);
    }
    return _soundID;
}
 */
@end




//音频工具升级版
@implementation HMAudioTool


static NSMutableDictionary *_soundIDs;


static NSMutableDictionary *_players;


+ (NSMutableDictionary *)soundIDs
{
    if (!_soundIDs) {
        _soundIDs = [NSMutableDictionary dictionary];
    }
    return _soundIDs;
}
+ (NSMutableDictionary *)players
{
    if (!_players) {
        _players = [NSMutableDictionary dictionary];
    }
    return _players;
}


+ (void)playAudioWithFilename:(NSString *)filename
{


    // 0.判断文件名是否为nil
    if (filename == nil) {
        return;
    }
    
    // 1.从字典中取出音效ID
    SystemSoundID soundID = [[self soundIDs][filename] unsignedIntValue];
    
    // 判断音效ID是否为nil
    if (!soundID) {
        NSLog(@"创建新的soundID");
        
        // 音效ID为nil
        // 根据文件名称加载音效URL
        NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
        
        // 判断url是否为nil
        if (!url) {
            return;
        }
        
        // 创建音效ID
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
        
        // 将音效ID添加到字典中
        [self soundIDs][filename] = @(soundID);
    }
    // 播放音效
    AudioServicesPlaySystemSound(soundID);
}


+ (void)disposeAudioWithFilename:(NSString *)filename
{
    // 0.判断文件名是否为nil
    if (filename == nil) {
        return;
    }
    
    // 1.从字典中取出音效ID
    SystemSoundID soundID = [[self soundIDs][filename] unsignedIntValue];
    
    if (soundID) {
        // 2.销毁音效ID
        AudioServicesDisposeSystemSoundID(soundID);
        
        // 3.从字典中移除已经销毁的音效ID
        [[self soundIDs] removeObjectForKey:filename];
    }
  
}


// 根据音乐文件名称播放音乐
+ (void)playMusicWithFilename:(NSString  *)filename
{
    // 0.判断文件名是否为nil
    if (filename == nil) {
        return;
    }
    
    // 1.从字典中取出播放器
    AVAudioPlayer *player = [self players][filename];
    
    // 2.判断播放器是否为nil
    if (!player) {
        NSLog(@"创建新的播放器");
        
        // 2.1根据文件名称加载音效URL
        NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
        
        // 2.2判断url是否为nil
        if (!url) {
            return;
        }
        
        // 2.3创建播放器
        player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
        
        // 2.4准备播放
        if(![player prepareToPlay])
        {
            return;
        }
        // 允许快进
        player.enableRate = YES;
        player.rate = 3;
        
        // 2.5将播放器添加到字典中
        [self players][filename] = player;
        
    }
    // 3.播放音乐
    if (!player.playing)
    {
        [player play];
    }
   
}


// 根据音乐文件名称暂停音乐
+ (void)pauseMusicWithFilename:(NSString  *)filename
{
    // 0.判断文件名是否为nil
    if (filename == nil) {
        return;
    }
    
    // 1.从字典中取出播放器
    AVAudioPlayer *player = [self players][filename];


    // 2.判断播放器是否存在
    if(player)
    {
        // 2.1判断是否正在播放
        if (player.playing)
        {
            // 暂停
            [player pause];
        }
    }
    
}


// 根据音乐文件名称停止音乐
+ (void)stopMusicWithFilename:(NSString  *)filename
{
    // 0.判断文件名是否为nil
    if (filename == nil) {
        return;
    }
    
    // 1.从字典中取出播放器
    AVAudioPlayer *player = [self players][filename];


    // 2.判断播放器是否为nil
    if (player) {
        // 2.1停止播放
        [player stop];
        // 2.2清空播放器
//        player = nil;
        // 2.3从字典中移除播放器
        [[self players] removeObjectForKey:filename];
    }
}
@end


//调用工具类的方法
@interface ViewController ()
//  播放器
//@property (nonatomic, strong) AVAudioPlayer *player;


// 播放
- (IBAction)playMusic:(id)sender;
// 暂停
- (IBAction)pauseMusic:(id)sender;
// 停止
- (IBAction)stopMusic:(id)sender;
// 下一首
- (IBAction)nextMusic:(id)sender;
// 保存所有的音乐
@property (nonatomic, strong) NSArray *musics;


// 记录当前播放音乐的索引
@property (nonatomic, assign) int  currentIndex;
@end


@implementation ViewController


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"%s", __func__);
    /*
    // 0.加载音乐文件
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"简单爱.mp3" withExtension:nil];
    // 1.创建音乐播放器
    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    self.player = player;
    // 2.缓冲音乐文件(准备)
    [player prepareToPlay];
    // 3.播放音乐
    [player play];
     */
    
//    [self.player play];
    
}


/*
- (AVAudioPlayer *)player
{
    if (!_player)
    {
        // 0.加载音乐文件
        NSURL *url = [[NSBundle mainBundle] URLForResource:@"简单爱.mp3" withExtension:nil];
        // 1.创建音乐播放器
        _player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
        // 2.缓冲音乐文件(准备)
        [_player prepareToPlay];
    }
    return _player;
}
 */


- (IBAction)playMusic:(id)sender {
    // 播放器的url时readonly的, 所以不能设置, 也就是说一个播放器对应一首歌
//    self.player.url = nil;
    // 播放
//    [self.player play];
    
    [HMAudioTool playMusicWithFilename:self.musics[self.currentIndex]];
}


- (IBAction)pauseMusic:(id)sender {
    // 暂停
//    [self.player pause];
    
    [HMAudioTool pauseMusicWithFilename:self.musics[self.currentIndex]];
}


- (IBAction)stopMusic:(id)sender {
    // 停止
#warning 注意: 如果播放器销毁, 播放器就不可以用了,因为如果播放器销毁后就不可控制器了. 建议每次调用播放器的销毁方法之后都清空播放器
//    [self.player stop];
//    self.player = nil;
    [HMAudioTool stopMusicWithFilename:self.musics[self.currentIndex]];
    
}


- (IBAction)nextMusic:(id)sender {
    // 下一首
    
    // 1.递增索引
    int nextIndex = self.currentIndex + 1;
    
    // 3.判断是否越界
    if (nextIndex >= self.musics.count) {
        nextIndex = 0;
    }
    NSLog(@"当前 %d  下一首 %d",  self.currentIndex, nextIndex);
    // 4.播放
    // 停止上一首播放
    [self stopMusic: nil];
    self.currentIndex = nextIndex;
    // 播放下一首
    [self playMusic:nil];
    
}




#pragma mark - 懒加载
- (NSArray *)musics
{
    if (!_musics) {
        _musics = @[@"最佳损友.mp3", @"心碎了无痕.mp3", @"瓦解.mp3", @"简单爱.mp3"];
    }
    return _musics;
}
@end





















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值