音频播放
// LCAVAudioPlayer.m
#import "LCAVAudioPlayer.h"
@interface LCAVAudioPlayer ()
@property (nonatomic, strong) AVAudioPlayer *player;
@end
@implementation LCAVAudioPlayer
- (instancetype)initAudioPlayer
{
if (self = [super init]) {
NSError *error;
NSString *mp3Path = [[NSBundle mainBundle] pathForResource:@"BIGBANG_IFYOU" ofType:@"mp3"];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:mp3Path] error:&error];
if (error) NSLog(@"play error:%@", [error localizedDescription]);
//play music all the time
self.player.numberOfLoops = -1;
//prepare play
[self.player prepareToPlay];
[self.player play];
}
return self;
}
在合适的地方调用,就可以播放了
// ViewController.m
#import "ViewController.h"
#import "LCAVAudioPlayer.h"
@interface ViewController ()
@property (nonatomic, strong) LCAVAudioPlayer *player;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
LCAVAudioPlayer *player = [[LCAVAudioPlayer alloc] initAudioPlayer];
//不太明白这里为什么非得拥有LCAVAudioPlayer的实例才能播放
self.player = player;
}
后台播放
1.首先,播放音频之前先要设置AVAudioSession模式,通常只用来播放的App可以设为AVAudioSessionCategoryPlayback即可。模式意义及其他模式请参考文档。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
if (![session setCategory:AVAudioSessionCategoryPlayback error:&error]) {
NSLog(@"Category Error: %@", [error localizedDescription]);
}
if (![session setActive:YES error:&error]) {
NSLog(@"Active Error: %@", [error localizedDescription]);
}
return YES;
}
2.通知OS该app支持background audio。当按下home键时,当前正在运行的程序被suspend,状态从active变成in-active,也就是说如果正在播放音频,按下HOME后就会停止。这里需要让app在按在HOME后,转到后台运行而非被suspend,解决办法是在程序的-info.plist中增加required background modes这个key项,并选择App plays audio or streams audio/video using AirPlay这个value项。至此支持后台播放了。
音频打断
程序在运行期间不可避免会有其他声音响起,这时候播放会被打断,为了更好的体验要对打断进行处理
1.添加打断通知的接收
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruptionNotificationReceived:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]]
2.处理打断事件
打断开始通知信息:
{
AVAudioSessionInterruptionTypeKey = 1;
}
打断结束通知信息:
{
AVAudioSessionInterruptionOptionKey = 0;
AVAudioSessionInterruptionTypeKey = 0;
}
- (void)interruptionNotificationReceived:(NSNotification *)notification
{
NSLog(@"interruptInfo%@", notification.userInfo);
NSInteger interruptState = [notification.userInfo[AVAudioSessionInterruptionTypeKey] integerValue];
NSError *error;
if (interruptState == AVAudioSessionInterruptionTypeBegan) {
NSLog(@"AVAudioSessionInterruptionTypeBegan");
}else if (interruptState == AVAudioSessionInterruptionTypeEnded) {
NSLog(@"AVAudioSessionInterruptionTypeEnded");
if ([[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDuckOthers
error:&error]) { //打断结束,恢复播放
[[LCAVAudioPlayer shareAudioPlayer] play];
}
}
}
AVAudioSessionCategoryOptionDuckOthers
这个选项会让系统中其他app发出的声音减半,主要是导航软件这一类的使用,可以让车主听到更清晰的导航语音。
AVAudioSessionCategoryOptionMixWithOthers
这个选项使用有点微妙,它可以让你的应用和其他音乐App做混音播放后一起播放出来
线路切换
接收到的 notiInfo
如下所示:
{
"AVAudioSessionRouteChangePreviousRouteKey":{
"AVAudioSessionRouteDescription":"0x170019bc0",
"inputs":"null",
"noutputs":[
{
"AVAudioSessionPortDescription":"0x170017a30",
"type":"Speaker",
"name":"扬声器",
"UID":"Speaker",
"selectedDataSource":"null"
}
]
},
"AVAudioSessionRouteChangeReasonKey":1
}
线路切换处理
- (void)routeChangeNotificationReceived:(NSNotification *)notification
{
NSDictionary *notiInfo = notification.userInfo;
AVAudioSessionRouteChangeReason reson = [notiInfo[AVAudioSessionRouteChangeReasonKey] unsignedIntegerValue];
if (reson == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {//连接设备断开,不可用
NSLog(@"Headphones Be Unplugged");
//stop play or other operation
[[LCAVAudioPlayer shareAudioPlayer] stop];
}
if (reson == AVAudioSessionRouteChangeReasonNewDeviceAvailable) {//接入可用的新设备
NSLog(@"New Device Plugged in");
[[LCAVAudioPlayer shareAudioPlayer] play];
}
}