最近在做一个项目,先录制一段声音,然后保存声音到手机里,最后用AudioServicesPlaySystemSound播放声音。
在用AudioServicesPlaySystemSound播放声音时出项了一个问题。
问题描述
录制了一段声音保存到
NSString *audioPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) lastObject];
audioPath = [audioPath stringByAppendingPathComponent:@"abc.aac"];
然后用这个文件直接用AudioServicesPlaySystemSound播放,第一次播放成功,接下来再录制一遍就播放不了了。代码如下:
(第一段代码)
SystemSoundID soundID;
NSURL *url = [NSURL URLWithString:_audioPath];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
//Registers a callback function that is invoked when a specified system sound finishes playing.
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, &playCallback, (__bridge void * _Nullable)(self));
// AudioServicesPlayAlertSound(soundID);
AudioServicesPlaySystemSound(soundID);
后来改成
SystemSoundID soundID;
NSString *audioPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) lastObject];
NSString *name = [NSString stringWithFormat:@"%d.aac",arc4random()];
NSString *dest = [audioPath stringByAppendingPathComponent:name];
[NSFileManager.defaultManager copyItemAtPath:_audioPath toPath:dest error:NULL];
NSURL *destURL = [NSURL fileURLWithPath:dest];
//Creates a system sound object.
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(destURL), &soundID);
//Registers a callback function that is invoked when a specified system sound finishes playing.
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, &playCallback, (__bridge void * _Nullable)(self));
// AudioServicesPlayAlertSound(soundID);
AudioServicesPlaySystemSound(soundID);
就可以每次都成功播放。上面代码就是把原文件复制一到另一个地址,用另一个唯一的地址生成soundID。但有个缺点上面复制的文件没有删除。不知道删除后还会不会正常。
在苹果官网上查询,得知如果一个声音你要重复播放的话应该把soundID保存下来,下次直接用这个soundID播放。如果只播一次的话,你要在播放完成后移除soundIDAudioServicesDisposeSystemSoundID
一般是在播放完成的回调方法块里完成移除:
void playCallback(SystemSoundID ssID, void* __nullable clientData) {
AudioServicesDisposeSystemSoundID(ssID);
// CFRelease(clientData);//是播放声音时,放入的任意参数。
// CFRunLoopStop(CFRunLoopGetCurrent());
}