// // CSAudioManager.m // MusicVideos // // Created by iOS_Chris on 16/8/8. // Copyright © 2016年 kyExpress. All rights reserved. // #import "CSAudioManager.h" #import @interface CSAudioManager() @property (nonatomic, strong) NSMutableDictionary *musicPlayers; @property (nonatomic, strong) NSMutableDictionary *soundIDs; @property (nonatomic, strong) AVAudioSession *session; @end static CSAudioManager *_instance = nil; @implementation CSAudioManager + (void)initialize { // 音频会话 AVAudioSession *session = [AVAudioSession sharedInstance]; // 设置会话类型(播放类型、播放模式,会自动停止其他音乐的播放) [session setCategory:AVAudioSessionCategoryPlayback error:nil]; // 激活会话 [session setActive:YES error:nil]; } + (instancetype)defaultManager { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; } - (instancetype)init { __block CSAudioManager *temp = self; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if ((temp = [super init]) != nil) { _musicPlayers = [NSMutableDictionary dictionary]; _soundIDs = [NSMutableDictionary dictionary]; } }); self = temp; return self; } + (instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [super allocWithZone:zone]; }); return _instance; } ////获取播放语音唯一标识 - 防止音频修改后UniqueID没有变 //+ (NSString *)getPlayIDWithNoticeRecieveModel:(NoticeRecieveModel *)nrModel //{ // NSString *playId = [NSString stringWithFormat:@"%@%@",nrModel.UniqueId,nrModel.AddTime]; // return playId; //} #pragma mark - 音乐 //播放音乐 - (AVAudioPlayer *)playingMusicWithURL:(NSURL *)url playID:(NSString *)playID{ NSLog(@"playingMusicWithURL-----------"); if (playID.length == 0) { NSLog(@"请传入playID"); return nil; } if (url == nil ) { NSLog(@"url地址为空,无法播放"); return nil; } NSData *data = [NSData dataWithContentsOfURL:url]; return [self playingMusicWithData:data playID:playID]; } - (AVAudioPlayer *)playingMusicWithData:(NSData *)musicData playID:(NSString *)playID { if (playID.length == 0) { NSLog(@"请传入playID"); return nil; } if (musicData == nil || musicData.length == 0) { NSLog(@"音频文件为空,无法播放"); return nil; } AVAudioPlayer *player = self.musicPlayers[playID]; //先查询对象是否缓存了 player.delegate = self; player.numberOfLoops = -1;//设置音乐播放次数 -1为一直循环 if (!player) { NSError *error = nil; player = [[AVAudioPlayer alloc] initWithData:musicData error:&error]; player.delegate = self; player.numberOfLoops = -1;//设置音乐播放次数 -1为一直循环 if (![player prepareToPlay]){ NSLog(@"播放器缓冲失败"); return nil; } self.musicPlayers[playID] = player; //对象是最新创建的,那么对它进行一次缓存 } NSLog(@"delegate : %@",player.delegate); if (![player isPlaying]) {//如果没有正在播放,那么开始播放,如果正在播放,那么不需要改变什么 NSLog(@"================= 开始播放 ================="); if (_blockPlayerStartPlay) { _blockPlayerStartPlay(); } [_session setCategory:AVAudioSessionCategoryPlayback error:nil]; [_session setActive:YES error:nil]; [player play]; }else{ NSLog(@"该音频正在播放,停止播放"); [player stop]; [self.musicPlayers removeObjectForKey:playID]; if (_blockPlayerStopPlay) { _blockPlayerStopPlay(); } // [player play]; } return player; } - (BOOL)isPlayingWithPlayID:(NSString *)playID { if ([self.musicPlayers.allKeys containsObject:playID]) { AVAudioPlayer *player=self.musicPlayers[playID]; NSLog(@"这个播放器是否正在播放:%d",[player isPlaying]); return [player isPlaying]; }else{ NSLog(@"没有这个播放器,无法查看是否正在播放"); return NO; } } -(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { NSLog(@"播放完毕-----------"); if (_blockPlayerDidFinishPlaying) { _blockPlayerDidFinishPlaying(); } } - (void)stopAllMusic { if (self.musicPlayers.allKeys.count > 0) { for ( NSString *playID in self.musicPlayers.allKeys) { AVAudioPlayer *player=self.musicPlayers[playID]; [player stop]; [self.musicPlayers removeObjectForKey:playID]; if (_blockPlayerStopPlay) { _blockPlayerStopPlay(); } } } } -(void)setBlockPlayerStartPlay:(BlockPlayerStartPlay)blockPlayerStartPlay { _blockPlayerStartPlay = blockPlayerStartPlay; } -(void)setBlockPlayerStopPlay:(BlockPlayerStopPlay)blockPlayerStopPlay { _blockPlayerStopPlay = blockPlayerStopPlay; } -(void)setBlockPlayerDidFinishPlaying:(BlockPlayerDidFinishPlaying)blockPlayerDidFinishPlaying { _blockPlayerDidFinishPlaying = blockPlayerDidFinishPlaying; } - (void)pauseMusicWithPlayID:(NSString *)playID { if (playID == nil || playID.length == 0) { NSLog(@"请传入playID"); return ; } AVAudioPlayer *player = self.musicPlayers[playID]; if ([player isPlaying]) { [player pause]; } } - (void)stopMusicWithPlayID:(NSString *)playID { if (playID == nil || playID.length == 0) { NSLog(@"请传入playID"); return ; } AVAudioPlayer *player = self.musicPlayers[playID]; [player stop]; [self.musicPlayers removeObjectForKey:playID]; if (_blockPlayerStopPlay) { _blockPlayerStopPlay(); } } #pragma mark - 音效 //播放音效 - (void)playSoundWithSoundName:(NSString *)soundName PlayID:(NSString *)playID { if (playID == nil || playID.length == 0) { NSLog(@"请传入playID"); return ; } if (!soundName){ NSLog(@"请传入soundName"); return; } //取出对应的音效ID SystemSoundID soundID = (int)[self.soundIDs[playID] unsignedLongValue]; if (!soundID) {//如果soundID为空,创建一个。 NSString *path = [NSString stringWithFormat:@"/System/Library/Audio/UISounds/%@.caf",soundName]; NSURL *url = [NSURL fileURLWithPath:path]; OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID); if (error != kAudioServicesNoError) {//获取的声音的时候,出现错误 NSLog(@"获取声音时,出现错误,无法播放"); soundID = nil; return; } self.soundIDs[playID] = @(soundID); } // 设置播放完成回调 AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL); AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); // 播放 AudioServicesPlaySystemSound(soundID); } //当音频播放完毕会调用这个函数 void soundCompleteCallback(SystemSoundID soundID,void* sample) { AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); //震动 AudioServicesPlaySystemSound(soundID); /*播放全部结束,因此释放所有资源 */ // AudioServicesDisposeSystemSoundID(sample); // CFRelease(sample); // CFRunLoopStop(CFRunLoopGetCurrent()); } //摧毁音效 - (void)disposeSoundWithPlayID:(NSString *)playID { if (!playID) return; SystemSoundID soundID = (int)[self.soundIDs[playID] unsignedLongValue]; if (soundID) { AudioServicesDisposeSystemSoundID(soundID); [self.soundIDs removeObjectForKey:playID]; //音效被摧毁,那么对应的对象应该从缓存中移除 } } -(AVAudioSession *)session { if (!_session) { _session = [AVAudioSession sharedInstance]; // 设置会话类型(播放类型、播放模式,会自动停止其他音乐的播放) [_session setCategory:AVAudioSessionCategoryPlayback error:nil]; // 激活会话 [_session setActive:YES error:nil]; } return _session; } /* 1.声音格式是MP3或m4r的需要转成caf格式(可先转成aif , aiff,然后修改后缀) 2.路径在/System/Library/Audio/UISounds 里,需要更改的可以根据以下列表进行替换 3详细列表: 信息 ReceivedMessage.caf--收到信息,仅在短信界面打开时播放。 sms-received1.caf-------三全音 sms-received2.caf-------管钟琴 sms-received3.caf-------玻璃 sms-received4.caf-------圆号 sms-received5.caf-------铃声 sms-received6.caf-------电子乐 SentMessage.caf--------发送信息 邮件 mail-sent.caf----发送邮件 new-mail.caf-----收到新邮件 电话 dtmf-0.caf----------拨号面板0按键 dtmf-1.caf----------拨号面板1按键 dtmf-2.caf----------拨号面板2按键 dtmf-3.caf----------拨号面板3按键 dtmf-4.caf----------拨号面板4按键 dtmf-5.caf----------拨号面板5按键 dtmf-6.caf----------拨号面板6按键 dtmf-7.caf----------拨号面板7按键 dtmf-8.caf----------拨号面板8按键 dtmf-9.caf----------拨号面板9按键 dtmf-pound.caf---拨号面板#按键 dtmf-star.caf------拨号面板*按键 Voicemail.caf-----新语音邮件 输入设备声音提示 Tock.caf-----------------------点击键盘 begin_record.caf-----------开始录音 begin_video_record.caf--开始录像 photoShutter.caf------------快门声 end_record.caf--------------结束录音 end_video_record.caf-----结束录像 其他 beep-beep.caf--充电、注销及连接电脑 lock.caf------------锁定手机 shake.caf---------“这个还没搞清楚” unlock.caf--------滑动解锁 low_power.caf--低电量提示 语音控制 jbl_ambiguous.caf--找到多个匹配 jbl_begin.caf------等待用户的输入 jbl_cancel.caf-----取消 jbl_confirm.caf----执行 jbl_no_match.caf---没有找到匹配 日历 alarm.caf--日历提醒 iPod Touch 1G sq_alarm.caf sq_beep-beep.caf sq_lock.caf sq_tock.caf */ @end