最近做IM消息, 接受到很多消息时, 如果播放声音, 会造成持续的连声, 可以这样解决, 用延时来做, 记录下 !
// 注册声音
- (void)registerSystemSound
{
NSString *path1 = [[NSBundle mainBundle] pathForResource:@"sendmsg" ofType:@"caf"];
NSString *path2 = [[NSBundle mainBundle] pathForResource:@"in" ofType:@"caf"];
//注册声音到系统
CFURLRef url1 = (__bridge CFURLRef)[NSURL fileURLWithPath:path1];
AudioServicesCreateSystemSoundID(url1,&sendmsg_sound_id);
CFURLRef url2 = (__bridge CFURLRef)[NSURL fileURLWithPath:path2];
AudioServicesCreateSystemSoundID(url2,&receive_sound_id);
}
// 播放声音
- (void)playSound:(int)type
{if(_isSoundPlaying) {
return;
};
_isSoundPlaying = YES;
//这个是重点
[self delayExecutePlaySoundTimeInterval:20.f completionCallBack:^{
_isSoundPlaying = NO;
}];
// 添加音频结束时的回调
AudioServicesAddSystemSoundCompletion(sendmsg_sound_id, NULL, NULL, completionCallback, (__bridge void *)(self));
AudioServicesPlaySystemSound(sendmsg_sound_id);
}
//这样是每次都要注册一个声音, 播放完就注销了, 个人不建议这么做, 这个注销的可以写在dealloc中, 就是声音只需要注册一次就够了
static void completionCallback (SystemSoundID mySSID, void* clientData)
{
// 在播放结束后循环播放
// AudioServicesPlaySystemSound(mySSID);
// 移除完成后执行的函数
AudioServicesRemoveSystemSoundCompletion(mySSID);
// 释放声音对象以及相关的所有资源
AudioServicesDisposeSystemSoundID(mySSID);
}
//延时操作
-(void)delayExecutePlaySoundTimeInterval:(CGFloat)timeInterval completionCallBack:(void(^)(void))completionBlock {
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeInterval * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
completionBlock();
});
}