iOS音频播放学习(2)

AVAudioSession

在上一遍学习中提到了AudioSession和AVAudioSession两个类,在苹果文档中可以看到,在iOS 7以后苹果建议使用的是AVAudioSession,所以AudioSession就等以后有时间再进行学习。
AVAudioSession是AVFoundation框架中的类,用来设置app的音频上下文,主要的功能有:
  • 激活或者取消app的audio session
  • 设置系统使用音频的方式
  • 配置如采样率,I/O缓存时长和信道数等音频设置
  • 处理Route Change(如拔出耳机后音频停止播放)
  • 应对其他事件
系统只允许一个session来控制audio routin。如果当前有多个sessions在运行的话,系统会根据当前的重要性来选择一个最重要的session并且判断该session是否允许混合。

获取AVAudioSession单例

[AVAudioSession shareInstance];

录音时请求用户允许

- (void)requestRecordPermission:(PermissionBlock)response // 参数response表示用户允许或拒绝时的回调函数
录音需要获取用户的允许,系统会自动跳出提示的。

typedef void (^PermissionBlock)(BOOL granted)
PermissionBlock,返回YES允许录音,NO则不允许

- (AVAudioSessionRecordPermission)recordPermission
返回当前录音的许可状态
有三个返回参数:AVAudioSessionPermissionGranted/AVAudioSessionPermissionDenied/AVAudioSessionPermissionUndetermined


管理Audio Session

@property(readonly) NSString *category
当前Audio session的类别,默认是AVAudioSessionCategorySoloAmbinet

NSString *const  AVAudioSessionCategoryAmbient ; // 该播放不是主要的。使用此类时,音频会与其他app的进行混合。锁屏或者静音模式下无法播放声音
NSString *const  AVAudioSessionCategorySoloAmbient ; // 锁屏或者静音模式下无法播放声音。音频不会与其他app混合
NSString *const  AVAudioSessionCategoryPlayback ; // 
NSString *const  AVAudioSessionCategoryRecord ;
NSString *const  AVAudioSessionCategoryPlayAndRecord ;
NSString *const  AVAudioSessionCategoryAudioProcessing ;
NSString *const  AVAudioSessionCategoryMultiRoute;
Audio Session的Category

@property(readonly) AVAudioSessionCategoryOptions categoryOptions
当前Category相关的选项

enum {
   AVAudioSessionCategoryOptionMixWithOthers  = 1, // 混合其他已激活的Session的音频。使用这个选项激活Session的话,会打断其他app正在播放的声音。如果不使用的话,则会打断其他不允许混合的session
   AVAudioSessionCategoryOptionDuckOthers  = 2, // 在本Session播放时避开其他session的音频
   AVAudioSessionCategoryOptionAllowBluetooth  = 4, // 允许蓝牙作为输入
   AVAudioSessionCategoryOptionDefaultToSpeaker  = 8 // 接入到系统默认的扬声器
};
typedef NSUInteger  AVAudioSessionCategoryOptions;
前两个个Options都需要在AVAudioSessionCategoryPlayback或者AVAudioSessionPlayAndRecord下才能使用,第三个在AVAudioSessionPlayAndRecord或者AVAudioSessionRecord,最后一个需在AVAudioSessionPlayAndRecord下使用

- (BOOL)setCategory:(NSString *)theCategory
              error:(NSError **)outError
设置Audio Session的Category
一般会在激活之前设置好Category和mode。但是也可以在已激活的audio session中设置,不过会在发生route change之后才会发生改变

- (BOOL)setCategory:(NSString *)category
        withOptions:(AVAudioSessionCategoryOptions)options
              error:(NSError **)outError
跟上面的函数相似

@property(readonly) NSString *mode
Audio Session使用的mode

NSString *const  AVAudioSessionModeDefault ;
NSString *const  AVAudioSessionModeVoiceChat ;
NSString *const  AVAudioSessionModeGameChat 
NSString *const AVAudioSessionModeVideoRecording;
NSString *const  AVAudioSessionModeMeasurement ;
NSString *const  AVAudioSessionModeMoviePlayback ;
NSString *const  AVAudioSessionModeVideoChat;
Audio Session Mode

- (BOOL)setMode:(NSString *)theMode
          error:(NSError **)outError
设置Mode

- (BOOL)setActive:(BOOL)beActive
            error:(NSError **)outError
激活或者取消Audio Session
如果另外一个活动中的Audio Session的优先级高于你所定义的(比如说有电话打进来)或者有一个允许混音的Audio Session,那么激活可能会失败。如果当前的音频相关对象正在运行的话,取消Audio Session有可能会失败

- (BOOL)setActive:(BOOL)active
      withOptions:(AVAudioSessionSetActiveOptions)options
            error:(NSError **)outError
跟上面的函数相似
第二个参数:
enum {
   AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation  = 1
};
typedef NSUInteger  AVAudioSessionSetActiveOptions;
表明当你的Audio Session被取消时,其他被你的Audio Session所打断的Audio Session可以恢复至其激活状态


音频设备设定

@property(readonly) float outputVolume
outputVolume的范围是0.0-1.0.系统的音量可以直接设置,想要控制音量大小的话,可以使用MPVolumeView类。
可以通过KVO来监测该值的变化

@property(readonly) float inputGain
输入增益inputGain的范围是0.0 - 1.0.
可通过KVO来监测变化

@property(readonly, getter=isInputGainSettable) BOOL inputGainSettable
因为不是所有设备都允许添加输入增益,所以在设置之前要检查是否允许设置输入增益inputGain。

- (BOOL)setInputGain:(float)gain
               error:(NSError **)outError
设置inputGain为特定值。gain的范围是0.0 - 1.0。调用此方法之前要检查是否允许设置inputGain

@property(readonly) NSTimeInterval inputLatency
音频输入的等待时间,以秒为单位。
如果Audio Session的Category设置不允许音频输入,该函数会返回AVAudioSessionErrorCodeIncompatibleCategory

@property(readonly) NSTimeInterval outputLatency
音频输出的等待时间,以秒为单位

@property(readonly) double sampleRate
当前音频的采样率,以赫兹为单位

@property(readonly) double preferredSampleRate
首选的采样率

- (BOOL)setPreferredSampleRate:(double)sampleRate
                         error:(NSError **)outError
设置输入输出的首选采样率
在激活和取消Audio Session之前或之后都可以进行设置

@property(readonly) NSTimeInterval IOBufferDuration
I/O的缓冲时间

@property(readonly) NSTimeInterval preferredIOBufferDuration
首选的I/O缓冲时间

- (BOOL)setPreferredIOBufferDuration:(NSTimeInterval)duration
                               error:(NSError **)outError
设置首选I/O缓冲时间
I/O缓冲时间是指单音频输入/输出周期的时长。比如说I/O缓冲时间为0.005s,那么在每一个音频I/O周期里,在获取输入时,会收到0.005s的音频,在输出时,必须提供0.005s的音频
通常来说I/O缓冲时间的范围是0.005s至0.93s

@property(readonly) BOOL secondaryAudioShouldBeSilencedHint
表明另一个app是否正在播放音频
返回YES表明另一个有着不允许混音的Audio Session的app正在播放音频


音频信道

@property(readonly) NSInteger inputNumberOfChannels
当前route的音频输入信道数
使用KVO来监测此值。如果Audio Session不支持录音的话,会产生AVAudioSessionErrorCodeIncompatibleCategory

@property(readonly) NSInteger maximumInputNumberOfChannels
可接受的最大的音频输入信道数

@property(readonly) NSInteger preferredInputNumberOfChannels
首选的音频输入信道数

- (BOOL)setPreferredInputNumberOfChannels:(NSInteger)count
                                    error:(NSError **)outError
设置首选的音频输入信道数
只能在设置Audio Session的Category和mode,并在激活session后调用

输出的话将input换成output即可

音频输入输出的Route

@property(readonly) AVAudioSessionRouteDescription *currentRoute
描述当前音频输入输出的route

@property(readonly, getter=isInputAvailable) BOOL inputAvailable
表明当前设备是否支持音频输入

@property(readonly, getter=isOtherAudioPlaying) BOOL otherAudioPlaying
其他app是否正在播放音频
在iOS 8.0以后要使用secondaryAudioShouldBeSilencedHint来代替这个属性

- (BOOL)overrideOutputAudioPort:(AVAudioSessionPortOverride)portOverride
                          error:(NSError **)outError
暂时更改当前的音频路线
第一个参数:
enum {
   AVAudioSessionPortOverrideNone     = 0, // 不覆写
   AVAudioSessionPortOverrideSpeaker  = 'spkr' // 将输入输出变换到内置扬声器和话筒
};
typedef NSUInteger  AVAudioSessionPortOverride;
使用AVAudioSessionPortOverrideSpeaker和AVAudioSessionCategoryPlayAndRecord的话会无视其他设置进行话筒录音和扬声器播放,不过会在重新调用这个方法并且参数为AVAudioSessionPortOverrideNone时失效

@property(readonly) NSArray *availableInputs
Route的输入端口数组
AVAudioSessionPortDescription对象的数组。代表了当前与系统相关的以及与当前Audio Session相关Category和mode的音频输入设备

@property(readonly) AVAudioSessionPortDescription *preferredInput
音频线路首要的输入端口

- (BOOL)setPreferredInput:(AVAudioSessionPortDescription *)inPort
                    error:(NSError **)outError
设置首要输入端口
inPort参数必须是availableInputs中的一个AVAudioSessionPortDescription对象
只能在设置了Audio Session的category和mode并且激活了session后才能进行调用设置

@property(readonly) NSArray *inputDataSources
Audio session的输入端口的可接受的数据源数组

@property(readonly) AVAudioSessionDataSourceDescription *inputDataSource
当前选择的输入数据源

- (BOOL)setInputDataSource:(AVAudioSessionDataSourceDescription *)dataSource
                     error:(NSError **)outError
设置选择的数据源

输出的话将input换成output即可

Notification

AVAudioSessionInterruptionNotification
当音频中断出现时传递给主线程
notification的userInfo字典包含了AVAudioSessionInterruption TypeKey,如果中断的类型是AVAudioSessionInterruptionTypeBegan,则app的audio session会被中断。如果是AVAudioSessionInterruptionTypeEnded,则字典会同时包含AVAudioSessionInterruptionOptionKey

AVAudioSessionRouteChangeNotification
当系统的音频线路发生改变时通知主线程
notification的userInfo字典会包含AVAudioSessionRouteChangeReasonKey和AVAudioSessionRouteChangePreviousRouteKey

AVAudioSessionMediaServicesWereLostNotification
当媒体服务终止时通知主线程
将该通知作为提示来在重新启动服务之前做相关处理
此notification不包含userInfo

AVAudioSessionMediaServicesWereResetNotification
媒体服务重新启动时通知主线程
不包含userInfo

AVAudioSessionSilenceSecondaryAudioHintNotification
当其他app的首要音频开始播放或者停止时通知主线程
userInfo中AVAudioSessionSilenceSecondaryAudioHintTypeKey的值为AVAudioSessionSilenceSecondaryAudioHintType类型


你可能感兴趣的:(iOS,学习)