一,背景
最近在做系统音频的总结,网上大多是一些前人的经验之谈,而少有自己探究,所以要来个总结
二,获取系统音频
- 1,系统音频的名称和soundID大多数可以参考wiki的:http://iphonedevwiki.net/index.php/AudioServices,网页是2011年更新的,预计是早期的系统音频,soundID范围在1000~1350;
- 2,获取最新系统的名称和soundID:得到/System/Library/Audio/UISounds一级目录下的文件269个,算上二级目录一共466个,soundID的范围在5053~5518,猜想iOS系统更新后,音频也会跟着更新
- 3,重要:一定要在真机的情况下获取,否则无效;
//获取目录/System/Library/Audio/UISounds下的url数组
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *directoryURL = [NSURL URLWithString:@"/System/Library/Audio/UISounds"];
NSArray *keys = [NSArray arrayWithObject:NSURLIsDirectoryKey];
NSDirectoryEnumerator *enumerator = [fileManager
enumeratorAtURL:directoryURL
includingPropertiesForKeys:keys
options:0
errorHandler:^(NSURL *url, NSError *error) {
// Handle the error.
// Return YES if the enumeration should continue after the error.
return YES;
}];
//再遍历/System/Library/Audio/UISounds下文件夹里的子文件夹文件数组
for (NSURL *url in enumerator) {
NSError *error;
NSNumber *isDirectory = nil;
if (! [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error]) {
// handle error
}else if (! [isDirectory boolValue]) {
[_audioFileList addObject:url];
}else {
// 文件夹层级
NSDirectoryEnumerator *newEnumerator = [fileManager
enumeratorAtURL:url
includingPropertiesForKeys:keys
options:0
errorHandler:^(NSURL *url, NSError *error) {
return YES;
}];
for (NSURL *url in newEnumerator) {
NSError *error;
NSNumber *isDirectory = nil;
if (! [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error]) {
// handle error
}else if (! [isDirectory boolValue]) {
[_audioFileList addObject:url];
}else {
};
};
}
};
三,自定义本地音频
音频文件不超过30s
四,播放音频
封装的工具类核心代码如下:
#pragma mark - 系统音效1:文件全称
- (void)playSystemSoundWith:(NSString *)fileName {
if (!_soundID) {
NSString *path = [NSString stringWithFormat:@"/System/Library/Audio/UISounds/%@",fileName];
if (path) {
// 注册系统文件
OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path],&_soundID);
if (error != kAudioServicesNoError) {//获取的声音的时候,出现错误
_soundID = 0;
}
}
};
[self play];
}
#pragma mark - 系统音效2:文件名 + 类型
- (void)playSystemSoundWith:(NSString *)fileName fileType:(NSString *)fileType {
if (!_soundID) {
NSString *path = [NSString stringWithFormat:@"/System/Library/Audio/UISounds/%@.%@",fileName,fileType];
if (path) {
// 注册系统文件
OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path],&_soundID);
if (error != kAudioServicesNoError) {//获取的声音的时候,出现错误
_soundID = 0;
}
}
};
[self play];
}
#pragma mark - 自定义音效1:bundle文件全称
- (void)playSelfdefinedSoundInBundleWith:(NSString *)fileName {
if (!_soundID) {
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:fileName withExtension:nil];
if (fileURL != nil)
{
//使用本地
SystemSoundID theSoundID;
OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)fileURL, &theSoundID);
if (error == kAudioServicesNoError){
_soundID = theSoundID;
}else {
NSLog(@"Failed to create sound ");
}
}else {
//使用系统
[self playSystemSoundWith: @"Tock" fileType:@"caf"];
}
};
[self play];
}
#pragma mark - 自定义音效2:bundle文件名 + 类型
- (void)playSelfdefinedSoundInBundleWith:(NSString *)fileName fileType:(NSString *)fileType {
if (!_soundID) {
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:fileType];
if (path) {
//使用本地
SystemSoundID theSoundID;
OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &theSoundID);
if (error == kAudioServicesNoError) {
_soundID = theSoundID;
}else {
NSLog(@"Failed to create sound ");
}
} else {
//使用系统
[self playSystemSoundWith:@"Tock" fileType:@"caf"];
}
};
[self play];
}
#pragma mark - 自定义音效3:沙盒文件
- (void)playSelfdefinedSoundInDocumentWith:(NSString *)fileName {
if (!_soundID) {
NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [documents stringByAppendingPathComponent:fileName];
if (path) {
// 注册系统文件
OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path],&_soundID);
if (error != kAudioServicesNoError) {//获取的声音的时候,出现错误
_soundID = 0;
}
}
};
[self play];
}
#pragma mark - 开启声音
- (void)play {
AudioServicesPlaySystemSound(_soundID);
}
#pragma mark - 停止声音
- (void)stop {
_soundID = 0;
}
#pragma mark - 销毁
- (void)dealloc {
AudioServicesDisposeSystemSoundID(_soundID);
}
@end
五,音频转换
下载一个工具软件,可以对已有的音频进行编辑处理,https://pan.baidu.com/s/1b5hsqf33k96Z7udQbVyb9Q
六,优缺点
- 才用C语言封装,节省内存
- 文件播放类型有限
- 不能及时根据音量开关,调整音频的大小;
- 不能控制声道
- 更加高级的音频用法,可以参考播放器框架AVPlayer和AVAudioPlayer,后续会继续研究