235 lines
7.1 KiB
Mathematica
235 lines
7.1 KiB
Mathematica
|
|
//
|
|||
|
|
// 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
|