水平有限。。。只是为了方便自己学习写的。。。 这是偶的第一篇博文。。。。
AVAudioSession类由AVFoundation框架引入。每个IOS应用都有一个音频会话。这个会话可以被AVAudioSession类的sharedInstance类方法访问
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
在获得一个AVAudioSession类的实例后,你就能通过调用音频会话对象的setCategory:error:实例方法,来从IOS应用可用的不同类别中作出选择。下面列出了可供使用的音频会话类别:
AVAudioSessionCategorySoloAmbient
这个类别非常像AVAudioSessionCategoryAmbient类别,除了会停止其他程序的音频回放,比如iPad程序。当设备被设置为静音模式,你的音频回放将会停止。
AVAudioSessionCategoryRecord
这会停止其他应用的声音(比如iPod)并让你的应用也不能初始化音频回放(比如AVAudioPlayer)。在这种模式下,你只能进行录音。使用这个 类别,调用AVAudioPlayer的prepareToPlay会返回YES,但是调用play方法将返回NO。主UI界面会照常工作。这时,即使你 的设备屏幕被用户锁定了,应用的录音仍会继续。
AVAudioSessionCategoryPlayback
这个类别会静止其他应用的音频回放(比如iPad应用的音频回放)。你可以使用AVAudioPlayer的prepareToPlay和play方法,在你的应用中播放声音。主UI界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放都会继续。
AVAudioSessionCategoryPlayAndRecord
这个类别允许你的应用中同时进行声音的播放和录制。当你的声音录制或播放开始后,其他应用的声音播放将会停止。主UI界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放和录制都会继续。
AVAudioSessionCategoryAudioProcessing
这个类别用于应用中进行音频处理的情形,而不是音频回放或录制。设置了这种模式,你在应用中就不能播放和录制任何声音。调用AVAPlayer的prepareToPlay和play方法都将返回NO。其他应用的音频回放,比如iPad,也会在此模式下停止。
AVAudioSessionCategoryAmbient
这个类别不会停止其他应用的声音,相反,它允许你的音频播放于其他应用的声音之上,比如iPod。你的应用的主UI线程会工作正常。调用 AVAPlayer的prepareToPlay和play方法都将返回YES。当用户锁屏时,你的应用将停止所有正在回放的音频。仅当你的应用是唯一播 放该音频文件的应用时,静音模式将停止你程序的音频回放。如果正当iPod播放一手歌时,你开始播放音频,将设备设为静音模式并不能停止你的音频回放。
关于iOS音频开发例子:
一:播放简短性质的音频,例如按键声音等
1.引入框架
#import <AudioToolbox/AudioToolbox.h>
2.声明一个声音源ID
SystemSoundID _bookSoundID;
3.提供需要播放的音频地址进行声音源注册
NSURL *bookSoundUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"bookSound" ofType:@"wav"]]; AudioServicesCreateSystemSoundID((__bridge CFURLRef)bookSoundUrl, &_bookSoundID);
4.在需要的时候执行这个方法
AudioServicesPlaySystemSound(_bookSoundID);
5.不用的声音源记得释放掉
AudioServicesDisposeSystemSoundID(_bookSoundID);
二: AVAudioSession的使用
首先知道 AVAudioSession 是一个单例模式,也就是说,不用开发者自行实例化. 这个类在各种音频环境中起着非常重要的作用
1: 首先是设置 AVAudioSession 的 类别
AVAudioSession * audioSession = [AVAudioSession sharedInstance]; //得到AVAudioSession单例对象 [audioSession setDelegate:self];//设定代理 [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];//设置类别,表示该应用同时支持播放和录音 [audioSession setActive:YES error: &error];//启动音频会话管理,此时会阻断后台音乐的播放.
2: 在录制完声音或者播放完声音后,可以将音频会话关闭,来延续后台音乐的播放,代码如下:
[[AVAudioSession sharedInstance] setActive:NO error: nil];
3: 通过音频会话可以强制的设置应用程序使用指定的输出方式,例如:内声道,扬声器,代码如下:
UInt32 audioRouteOverride = hasHeadset ?kAudioSessionOverrideAudioRoute_None:kAudioSessionOverrideAudioRoute_Speaker; AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride); kAudioSessionOverrideAudioRoute_None 内声道,耳机 kAudioSessionOverrideAudioRoute_Speaker 扬声器
4: 那么怎么判断用户是否已经插入耳机?代码如下:(参考:http://iandworld.sinaapp.com/?p=184001)
- (BOOL)hasHeadset { //模拟器不支持 #if TARGET_IPHONE_SIMULATOR #warning *** Simulator mode: audio session code works only on a device return NO; #else CFStringRef route; UInt32 propertySize = sizeof(CFStringRef); AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &route); if((route == NULL) || (CFStringGetLength(route) == 0)){ // Silent Mode NSLog(@"AudioRoute: SILENT, do nothing!"); } else { NSString* routeStr = (__bridge NSString*)route; NSLog(@"AudioRoute: %@", routeStr); /* Known values of route: * "Headset" * "Headphone" * "Speaker" * "SpeakerAndMicrophone" * "HeadphonesAndMicrophone" * "HeadsetInOut" * "ReceiverAndMicrophone" * "Lineout" */ NSRange headphoneRange = [routeStr rangeOfString : @"Headphone"]; NSRange headsetRange = [routeStr rangeOfString : @"Headset"]; if (headphoneRange.location != NSNotFound) { return YES; } else if(headsetRange.location != NSNotFound) { return YES; } } return NO; #endif }
返回YES,表示已经插入耳机,返回NO表示没有插入耳机
5: 监听用户拔出插入耳机事件
1:注册监听事件,和回调函数
AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self);
2:实现回调函数进行相关处理:
void audioRouteChangeListenerCallback ( void *inUserData, AudioSessionPropertyID inPropertyID, UInt32 inPropertyValueSize, const void *inPropertyValue ) { if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return; // Determines the reason for the route change, to ensure that it is not // because of a category change. CFDictionaryRef routeChangeDictionary = inPropertyValue; CFNumberRef routeChangeReasonRef = CFDictionaryGetValue (routeChangeDictionary, CFSTR (kAudioSession_AudioRouteChangeKey_Reason)); SInt32 routeChangeReason; CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason); NSLog(@" ===================================== RouteChangeReason : %d", routeChangeReason); AudioHelper *_self = (AudioHelper *) inUserData; if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) { [_self resetSettings]; if (![_self hasHeadset]) { [[NSNotificationCenter defaultCenter] postNotificationName:@"ununpluggingHeadse" object:nil]; } } else if (routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable) { [_self resetSettings]; if (![_self hasMicphone]) { [[NSNotificationCenter defaultCenter] postNotificationName:@"pluggInMicrophone" object:nil]; } } else if (routeChangeReason == kAudioSessionRouteChangeReason_NoSuitableRouteForCategory) { [_self resetSettings]; [[NSNotificationCenter defaultCenter] postNotificationName:@"lostMicroPhone" object:nil]; } //else if (routeChangeReason == kAudioSessionRouteChangeReason_CategoryChange ) { // [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; //} [_self printCurrentCategory]; }
6: 如何保持后台音乐的一直播放呢? (参考:http://blog.csdn.net/yhawaii/article/details/7788340)
1:在Info.plist中,添加"Required background modes"键,其值设置如下图所示:
2:系统音频服务支持音频播放,并关闭其他正在播放的音频
AVAudioSession *session = [AVAudioSession sharedInstance]; [session setActive:YES error:nil]; [session setCategory:AVAudioSessionCategoryPlayback error:nil];
3:设置app支持接受远程控制事件代码:
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
设置app支持接受远程控制事件,其实就是在dock中可以显示应用程序图标,同时点击该图片时,打开app,如下图所示:
4:执行 AVAudioPlayer
七 关于音量
1:由应用主动获取系统音量
UInt32 dataSize = sizeof(float); AudioSessionGetProperty (kAudioSessionProperty_CurrentHardwareOutputVolume, &dataSize, &keyVolume);
获取之前要确保
AVAudioSession *session = [AVAudioSession sharedInstance]; [session setActive:YES error:nil]; [session setCategory:AVAudioSessionCategoryPlayback error:nil];
2:由应用主动设置系统音量 (参考:http://blog.csdn.net/studyrecord/article/details/6452354)
八:关于音频边下载边播放的实现.
请参考:AudioStreamer
https://github.com/mattgallagher/AudioStreamer
如果你只是想简简单单在线播放以下不做任何处理. 那使用AVPlayer 等等 去实现在线播放,也是可以的,但是如果要实现更多更能,还是别折腾这玩意,浪费生命.