@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
// 播放音效
// 传入需要 播放的音效文件名称
+ (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