(1)音效播放,核心代码,主要是创建一个播放器,然后播放。
#import "WPSound.h"
#import <AVFoundation/AVFoundation.h>
@implementation WPSound
static NSMutableDictionary *_soundIDDict;
+(void)initialize{
_soundIDDict=[NSMutableDictionary dictionary];
}
//不能用懒加载,因为给用户使用的时类方法,所以需要在上面的类初始化中设置
//-(NSMutableDictionary *)soundIDDict{
// if (_soundIDDict==nil) {
// _soundIDDict=[NSMutableDictionary dictionary];
// }
// return _soundIDDict;
//}
+(void)soundPlay:(NSString *)fileName{
if (!fileName) return;
//取出soundID
SystemSoundID soundID=[_soundIDDict[fileName] unsignedIntValue];
if (!soundID) {
NSURL *url=[[NSBundle mainBundle]URLForResource:fileName withExtension:nil];
if (!url) return;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID);
//放入字典
_soundIDDict[fileName]=@(soundID);
}
AudioServicesPlaySystemSound(soundID);
}
+(void)soundDispose:(NSString *)fileName{
if (fileName) return;
SystemSoundID soundID=[_soundIDDict[fileName] unsignedIntValue];
if (!soundID) return;
AudioServicesDisposeSystemSoundID(soundID);
//从字典中移除
[_soundIDDict removeObjectForKey:fileName];
}
@end
(2)音乐播放,核心代码。需要注意的是创建的播放器需要是全局变量。
#import "MusicTool.h"
@implementation MusicTool
static NSMutableDictionary *_audioPlayerDict;
static AVAudioPlayer *_audioPlayer;
+(void)initialize{
_audioPlayerDict=[NSMutableDictionary dictionary];
//设置会话类型
AVAudioSession *session=[AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategorySoloAmbient error:nil];
[session setActive:YES error:nil];
}
+(AVAudioPlayer *)musicPlay:(NSString *)fileName{
if (!fileName) return nil;
//取出播放器
AVAudioPlayer *audioPlayer=_audioPlayerDict[fileName];
if (!audioPlayer) {
NSURL *url=[[NSBundle mainBundle]URLForResource:fileName withExtension:nil];
if (!url) return nil;
//创建audioPlayer
AVAudioPlayer *audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:NULL];
_audioPlayer=audioPlayer;
[_audioPlayer prepareToPlay];
_audioPlayer.enableRate=YES;
//以下设置播放速度,可以测试用
// _audioPlayer.rate=10;
// _audioPlayerDict[fileName]=audioPlayer;
}
if (!_audioPlayer.isPlaying) {
[_audioPlayer play];
}
return _audioPlayer;
}
+(void)musicPause:(NSString *)fileName{
if (!fileName) return;
AVAudioPlayer *audioPlayer=_audioPlayerDict[fileName];
if (audioPlayer.isPlaying) {
[audioPlayer pause];
}
}
+(void)musicStop:(NSString *)fileName{
if (!fileName) return;
AVAudioPlayer *audioPlayer=_audioPlayerDict[fileName];
if (audioPlayer.isPlaying) {
[audioPlayer stop];
[_audioPlayerDict removeObjectForKey:fileName];
}
}
+(AVAudioPlayer *)currentPlayingAudioPlayer{
for (NSString *fileName in _audioPlayerDict) {
AVAudioPlayer *audioPlayer=_audioPlayerDict[fileName];
if (audioPlayer.isPlaying) {
return audioPlayer;
}
}
return nil;
}
@end
(3)录音,核心代码。
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()
@property(nonatomic,strong) AVAudioRecorder *recorder;
@property(nonatomic,strong) CADisplayLink *link;
@property(nonatomic,assign) float silentDuration;
- (IBAction)recordStart:(id)sender;
- (IBAction)recordStop:(id)sender;
@end
@implementation ViewController
-(CADisplayLink *)link{
if (_link==nil) {
_link=[CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
}
return _link;
}
-(void)update{
//更新录音器的测量值
[self.recorder updateMeters];
//获得平均分贝
float power=[self.recorder averagePowerForChannel:0];
if (power<-30) {
self.silentDuration+=self.link.duration;
if (self.silentDuration>=2) {
[self.recorder stop];
[self.link invalidate];
self.link=nil;
}
}else{
self.silentDuration=0;
}
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)recordStart:(id)sender {
NSString *path=[[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"test.caf"];
NSURL *url=[NSURL fileURLWithPath:path];
NSMutableDictionary *setting=[NSMutableDictionary dictionary];
//音频格式
setting[AVFormatIDKey]=@(kAudioFormatAppleIMA4);
//音频采样率
setting[AVSampleRateKey]=@(8000.0);
//音频通道数
setting[AVNumberOfChannelsKey]=@(1);
//线性音频位深度
setting[AVLinearPCMBitDepthKey]=@(8);
AVAudioRecorder *recorder=[[AVAudioRecorder alloc]initWithURL:url settings:setting error:nil];
//允许测量分贝
recorder.meteringEnabled=YES;
//缓冲
[recorder prepareToRecord];
//录音
[recorder record];
self.recorder=recorder;
//开启定时器
self.silentDuration=0;
[self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
- (IBAction)recordStop:(id)sender {
[self.link invalidate];
self.link=nil;
[self.recorder stop];
}
@end
(3)后台播放音乐,设置3处地方。
——在AppDelegate.m中设置
- (void)applicationDidEnterBackground:(UIApplication *)application {
[application beginBackgroundTaskWithExpirationHandler:nil];
}
——在info.plist中设置
——还有一个在程序中设置音频会话类型(可省略)
+(void)initialize{
_audioPlayerDict=[NSMutableDictionary dictionary];
//设置会话类型
AVAudioSession *session=[AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategorySoloAmbient error:nil];
[session setActive:YES error:nil];
}