您的位置:首页 > 移动开发 > IOS开发

iOS 关于音频开发

2012-11-08 21:31 459 查看
音频方面的知识,相对其他编程还是较为复杂的,特别是要搞清楚框架里具体使用的参数和方法,不然写起代码来非常迷茫.

1:播放简短性质的音频,例如按键声音,等可以这样实现.

一:引入框架:

#import <AudioToolbox/AudioToolbox.h>


二:先声明一个声音源ID

SystemSoundID _bookSoundID;


三:提供需要播放的音频地址进行声音源的注册.

NSURL *bookSoundUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"bookSound" ofType:@"wav"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)bookSoundUrl, &_bookSoundID);


四:在需要的时候播放:

AudioServicesPlaySystemSound(_bookSoundID);


五:不用的声音源记得释放掉

AudioServicesDisposeSystemSoundID(_bookSoundID);

2: 关于 AVAudioSession 的使用

首先知道 AVAudioSession  是一个单例模式,也就是说,不用开发者自行实例化. 这个类在各种音频环境中起着非常重要的作用

一:首先是设置 AVAudioSession 的 类别

                                                                                      获取输入硬 件          获取输出硬件       与IPOD混合      遵从振铃/静音按键
AVAudioSessionCategoryAmbient                            否                               是                          是                         是

AVAudioSessionCategorySoloAmbient                    否                              是                           否                         是

AVAudioSessionCategoryPlayback                          否                               是                           否                        否

AVAudioSessionCategoryRecord                              是                              否                           否                         否

AVAudioSessionCategoryPlayAndRecord              是                              是                           否                         否
根据实际的使用情况来设定具体的类别,设置代码如下:

AVAudioSession * audioSession = [AVAudioSession sharedInstance]; //得到AVAudioSession单例对象
[audioSession setDelegate:self];//设定代理
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];//设置类别,表示该应用同时支持播放和录音
[audioSession setActive:YES error: &error];//启动音频会话管理,此时会阻断后台音乐的播放.


二:在录制完声音或者播放完声音后,可以将音频会话关闭,来延续后台音乐的播放,代码如下:

[[AVAudioSession sharedInstance] setActive:NO error: nil];

三:通过音频会话可以强制的设置应用程序使用指定的输出方式,例如:内声道,扬声器,代码如下:

UInt32 audioRouteOverride = hasHeadset ?kAudioSessionOverrideAudioRoute_None:kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);

kAudioSessionOverrideAudioRoute_None  内声道,耳机

kAudioSessionOverrideAudioRoute_Speaker 扬声器

四:那么怎么判断用户是否已经插入耳机?代码如下: (参考: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表示没有插入耳机

五:监听用户拔出插入耳机事件

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];
}

六:如何保持后台音乐的一直播放呢? (参考: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 等等 去实现在线播放,也是可以的,但是如果要实现更多更能,还是别折腾这玩意,浪费生命. 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: