cdts/xdts-ios 3/TreeHole/Code/Utility/VoiceRecoder/MTAudioManager.m

235 lines
7.1 KiB
Mathematica
Raw Normal View History

2023-07-27 09:20:00 +08:00
//
// 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];
//线 8162432
[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