//
|
// CSAudioManager.m
|
// MusicVideos
|
//
|
// Created by iOS_Chris on 16/8/8.
|
// Copyright © 2016年 kyExpress. All rights reserved.
|
//
|
|
#import "CSAudioManager.h"
|
#import <AVFoundation/AVFoundation.h>
|
|
|
@interface CSAudioManager()<AVAudioPlayerDelegate>
|
@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
|