cdts/xdts-ios 3/TreeHole/Code/Utility/VoiceRecoder/MTAudioManager.m
2023-07-27 09:20:00 +08:00

235 lines
7.1 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Copyright 1999-2015 MyApp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "MTAudioManager.h"
#import <AVFoundation/AVFoundation.h>
#import "NSTimer+BlocksKit.h"
#import "DDAudioManager.h"
@interface MTAudioManager()<AVAudioPlayerDelegate>
@property (nonatomic, strong) AVAudioSession *session;
@property (nonatomic, strong) NSURL *recordFileURL;
@property (nonatomic, copy) NSString *recordUrlKey;
@property (nonatomic, copy) didPlayFinish finishBlock;
@property (nonatomic, strong) NSTimer *recordProgressTimer;
@end
@implementation MTAudioManager
+ (instancetype)sharedInstance
{
static MTAudioManager *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[MTAudioManager alloc] init];
});
return instance;
}
- (instancetype)init
{
self = [super init];
if(self)
{
[self activeAudioSession];
}
return self;
}
- (void)activeAudioSession
{
self.session = [AVAudioSession sharedInstance];
NSError *sessionError = nil;
[self.session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:&sessionError];
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
AudioSessionSetProperty (
kAudioSessionProperty_OverrideAudioRoute,
sizeof (audioRouteOverride),
&audioRouteOverride
);
#pragma clang diagnostic pop
if(!self.session)
{
NSLog(@"Error creating session: %@", [sessionError description]);
}
else
{
[self.session setActive:YES error:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
}
- (void)playWithData:(NSData *)data finish:(void (^)(void))didFinish;
{
[self stopPlay];
self.finishBlock = didFinish;
if (self.player) {
if (self.player.isPlaying) {
[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.player play];
}
else
{
NSLog(@"Error creating player: %@", [playerError description]);
}
}
- (void)stopPlay
{
if (self.player)
{
if (self.player.isPlaying)
{
[self.player stop];
}
self.player.delegate = nil;
self.player = nil;
// 恢复其他app音频播放
// [[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
if (self.finishBlock)
{
self.finishBlock();
self.finishBlock = nil;
}
}
}
- (BOOL)initRecord
{
[self activeAudioSession];
//录音设置
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc]init];
//设置录音格式 AVFormatIDKey==kAudioFormatLinearPCM
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
//设置录音采样率(Hz) 如AVSampleRateKey==8000/44100/96000影响音频的质量
[recordSetting setValue:[NSNumber numberWithFloat:16000.0] forKey:AVSampleRateKey]; //调低采样率,防止小程序播放不支持
//录音通道数 1 或 2
[recordSetting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
//线性采样位数 8、16、24、32
[recordSetting setValue:[NSNumber numberWithInt:8] forKey:AVLinearPCMBitDepthKey]; //设置最小8位防止小程序播放不支持
//录音的质量
[recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
NSTimeInterval timeInterval = [[NSDate date] timeIntervalSince1970];
NSString *strUrl = [NSString stringWithFormat:@"%@/%f.m4a", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject], timeInterval];
NSURL *url = [NSURL fileURLWithPath:strUrl];
self.recordUrlKey = 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
{
BOOL succees = [self.recorder record];
if (succees) {
__weak MTAudioManager * weakSelf = self;
NSTimer *timer = [NSTimer bk_scheduleTimerWithTimeInterval:0.1 repeats:YES usingBlock:^(NSTimer * _Nonnull timer) {
if ([weakSelf.recordDelegate respondsToSelector:@selector(audioManager:audioPath:recordingProgress:)]) {
[weakSelf.recordDelegate audioManager:weakSelf audioPath:weakSelf.recordUrlKey recordingProgress:[weakSelf recordTime]];
}
}];
self.recordProgressTimer = timer;
}
return succees;
}
- (void)stopRecord
{
NSTimeInterval duration = self.recorder.currentTime;
[self.recorder stop];
// 恢复其他app音频播放
// [[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
[self.recordProgressTimer invalidate];
self.recordProgressTimer = nil;
if ([self.recordDelegate respondsToSelector:@selector(audioManagerDidStopedRecord:audioPath:duration:)]) {
[self.recordDelegate audioManagerDidStopedRecord:self audioPath:self.recordUrlKey duration:round(duration)];
}
}
- (CGFloat)peakPowerMeter
{
return 0.5;
}
- (NSTimeInterval)recordTime
{
return (self.recorder.currentTime);
}
- (void)handleInterruption:(NSNotification *)noti
{
;
}
#pragma mark - AVAudioPlayerDelegate
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
// 恢复其他app音频播放
// [[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
if (self.finishBlock)
{
self.finishBlock();
self.finishBlock = nil;
}
}
/* if an error occurs while encoding it will be reported to the delegate. */
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError * __nullable)error
{
;
}
@end