iOS扬声器和听筒模式的切换以及距离传感器红外感应的设置

时间:2020-12-04 09:11:58

#import "MyAudioManager.h"

#import <AVFoundation/AVFoundation.h>

#import "NSStringEx.h"


@interface MyAudioManager()<AVAudioPlayerDelegate>


@property (nonatomic, strong) AVAudioSession *session;

@property (nonatomic, strong) AVAudioPlayer *player;

@property (nonatomic, strong) AVAudioRecorder *recorder;

@property (nonatomic, strong) NSURL *recordFileURL;

@property (nonatomic, copy)   NSString *recordUrlKey;

@property (nonatomic, copy) didPlayFinish finishBlock;


@end


@implementation MyAudioManager


+ (instancetype)sharedInstance

{

    static MyAudioManager *_sharedInstance = nil;

    static dispatch_once_t onceToken;

    

    dispatch_once(&onceToken, ^{

        _sharedInstance = [[self alloc ] init];

        [_sharedInstance setproximity];

    });

    return _sharedInstance;

}



#pragma mark --设置距离传感器

- (void)setproximity{

    self.session = [AVAudioSession sharedInstance];

    NSError *sessionError = nil;

    

    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;

#pragma clang diagnostic push

#pragma clang diagnostic ignored "-Wdeprecated-declarations"

    AudioSessionSetProperty (

                             kAudioSessionProperty_OverrideAudioRoute,

                             sizeof (audioRouteOverride),

                             &audioRouteOverride

                             );

    UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;

    AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,

                            sizeof(sessionCategory),

                            &sessionCategory);

    

    //默认情况下扬声器播放

    [self.session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&sessionError];

    [self.session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&sessionError];


    if(!self.session) {

        TDDLogEvent(@"Error creating session: %@", [sessionError description]);

    }

    else {

        [self.session setActive:YES error:nil];

    }

}


//proximityState 属性 如果用户接近手机,此时属性值为YES,并且屏幕关闭(非休眠)。

-(void)sensorStateChange:(NSNotificationCenter *)notification{


    if ([[UIDevice currentDevice] proximityState] == YES)

    {

        //NSLog(@"Device is close to user");

        [self.session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

    }

    else

    {

        // NSLog(@"Device is not close to user");

        [self.session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];

        [self.session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];

    }

}


- (void)playWithData:(NSData *)data finish:(void (^)())didFinish;

{

    NSLog(@"datat========%@",data);

    self.finishBlock = didFinish;

    if (self.player) {

        if (self.player.isPlaying) {

            [self handleNotification:NO];

            [self.player stop];

        }

        self.player.delegate = nil;

        self.player = nil;

    }

    

    NSError *playerError = nil;

    self.player = [[AVAudioPlayer alloc] initWithData:data error:&playerError];

    if (self.player)  {

        self.player.delegate = self;

        [self handleNotification:YES];

        [self.player play];

        

    }

    else {

        TDDLogEvent(@"Error creating player: %@", [playerError description]);

    }

}

#pragma mark - 监听听筒or扬声器

- (void) handleNotification:(BOOL)state

{

    [[UIDevice currentDevice] setProximityMonitoringEnabled:state]; //建议在播放之前设置yes,播放结束设置NO,这个功能是开启红外感应

    if(state)//添加监听

    {

        [[NSNotificationCenter defaultCenter] addObserver:self

                                                 selector:@selector(sensorStateChange:) name:@"UIDeviceProximityStateDidChangeNotification"

                                                   object:nil];

    }

    else//移除监听

    {

        [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIDeviceProximityStateDidChangeNotification" object:nil];

    }

}

- (void)stopPlay{

    if (self.player) {

        if (self.player.isPlaying) {

            [self handleNotification:NO];


            [self.player stop];

        }

        self.player.delegate = nil;

        self.player = nil;

        

        [[NSNotificationCenter defaultCenter] postNotificationName:@"audioCellStopAnimating" object:nil];

        

    }

}


- (BOOL)initRecord{

    

    //录音设置

    NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc]init];

    //设置录音格式  AVFormatIDKey==kAudioFormatLinearPCM

    [recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];

    //设置录音采样率(Hz) 如:AVSampleRateKey==8000/44100/96000(影响音频的质量)

    [recordSetting setValue:[NSNumber numberWithFloat:44100] forKey:AVSampleRateKey];

    //录音通道数  1 2

    [recordSetting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];

    //线性采样位数  8162432

    [recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];

    //录音的质量

    [recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];

    

    NSString *strUrl = [NSString stringWithFormat:@"%@/%@.mp4", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject], [NSString uuid]];

    NSURL *url = [NSURL fileURLWithPath:strUrl];

    self.recordUrlKey = strUrl;

//   self.audioRecord.filePath = strUrl;

    

    NSError *error;

    //初始化

    _recorder = [[AVAudioRecorder alloc]initWithURL:url settings:recordSetting error:&error];

    //开启音量检测

    self.recorder.meteringEnabled = YES;

    

    if ([self.recorder prepareToRecord]){

        return YES;

    }

    return NO;

}



- (BOOL)startRecord

{

    return [self.recorder record];

}


- (void)stopRecordWithBlock:(didRecordFinish)block

{

    NSTimeInterval duration = self.recorder.currentTime;

    [self.recorder stop];

    

    if (block) {

        block(self.recordUrlKey, (NSInteger)(round(duration)));

    }

}


- (CGFloat)peakPowerMeter{

    [self.recorder updateMeters];

    double  peakPower = pow(10, (0.05* [self.recorder peakPowerForChannel:0]));

    return peakPower;

}


- (NSInteger)recordTime{

    return self.recorder.currentTime+0.5;

}


#pragma mark - AVAudioPlayerDelegate

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{

    if (self.finishBlock) {

        self.finishBlock();

        [self handleNotification:NO];

    }

}

@end