AudioServicesPlaySystemSound播放声音

最近在做一个项目,先录制一段声音,然后保存声音到手机里,最后用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());
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容