From f6bf02df56894b053b1a5da89e43e63d1e41b23d Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 9 Jun 2017 17:32:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0l=20=E6=A8=A1=E4=BB=BF?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=BD=95=E9=9F=B3=E7=9A=84HUD=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E5=BC=95=E8=B5=B7=E9=97=AE=E9=A2=98=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChatKit/ChatKit.xcodeproj/project.pbxproj | 12 + .../Conversation/View/ChatBar/LCCKChatBar.m | 138 +++---- .../View/ChatBar/LCCKRecordAudioHUD.h | 91 +++++ .../View/ChatBar/LCCKRecordAudioHUD.m | 360 ++++++++++++++++++ .../chat_record_allbg@2x.png | Bin 0 -> 2058 bytes .../chat_record_allbg@3x.png | Bin 0 -> 2870 bytes .../chat_record_cancel@2x.png | Bin 0 -> 2267 bytes .../chat_record_cancel@3x.png | Bin 0 -> 2968 bytes .../chat_record_microphone@2x.png | Bin 0 -> 2905 bytes .../chat_record_microphone@3x.png | Bin 0 -> 3965 bytes .../chat_record_titlebg@2x.png | Bin 0 -> 1187 bytes .../chat_record_titlebg@3x.png | Bin 0 -> 1354 bytes .../chat_record_volume_0@2x.png | Bin 0 -> 1119 bytes .../chat_record_volume_0@3x.png | Bin 0 -> 15145 bytes .../chat_record_volume_1@2x.png | Bin 0 -> 1178 bytes .../chat_record_volume_1@3x.png | Bin 0 -> 15264 bytes .../chat_record_volume_2@2x.png | Bin 0 -> 1210 bytes .../chat_record_volume_2@3x.png | Bin 0 -> 15348 bytes .../chat_record_volume_3@2x.png | Bin 0 -> 1237 bytes .../chat_record_volume_3@3x.png | Bin 0 -> 15423 bytes .../chat_record_volume_4@2x.png | Bin 0 -> 1255 bytes .../chat_record_volume_4@3x.png | Bin 0 -> 15495 bytes .../chat_record_volume_5@2x.png | Bin 0 -> 1291 bytes .../chat_record_volume_5@3x.png | Bin 0 -> 15561 bytes .../chat_record_volume_6@2x.png | Bin 0 -> 1291 bytes .../chat_record_volume_6@3x.png | Bin 0 -> 15619 bytes .../chat_record_volume_7@2x.png | Bin 0 -> 1310 bytes .../chat_record_volume_7@3x.png | Bin 0 -> 15710 bytes .../chat_record_volume_8@2x.png | Bin 0 -> 1314 bytes .../chat_record_volume_8@3x.png | Bin 0 -> 15751 bytes .../chat_record_warning@2x.png | Bin 0 -> 1013 bytes .../chat_record_warning@3x.png | Bin 0 -> 1075 bytes .../Class/Tool/Vendor/VoiceLib/Mp3Recorder.h | 19 +- .../Class/Tool/Vendor/VoiceLib/Mp3Recorder.m | 86 ++++- 34 files changed, 630 insertions(+), 76 deletions(-) mode change 100644 => 100755 ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m create mode 100644 ChatKit/Class/Module/Conversation/View/ChatBar/LCCKRecordAudioHUD.h create mode 100644 ChatKit/Class/Module/Conversation/View/ChatBar/LCCKRecordAudioHUD.m create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_allbg@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_allbg@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_cancel@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_cancel@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_microphone@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_microphone@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_titlebg@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_titlebg@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_0@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_0@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_1@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_1@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_2@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_2@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_3@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_3@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_4@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_4@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_5@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_5@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_6@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_6@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_7@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_7@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_8@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_8@3x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_warning@2x.png create mode 100644 ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_warning@3x.png mode change 100755 => 100644 ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.h diff --git a/ChatKit/ChatKit.xcodeproj/project.pbxproj b/ChatKit/ChatKit.xcodeproj/project.pbxproj index 6ef7ff83..29f2d795 100644 --- a/ChatKit/ChatKit.xcodeproj/project.pbxproj +++ b/ChatKit/ChatKit.xcodeproj/project.pbxproj @@ -502,6 +502,9 @@ 9AC44E9D1E15154300619112 /* UITableView+FDTemplateLayoutCellDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = 9AC44D7D1E15154300619112 /* UITableView+FDTemplateLayoutCellDebug.m */; }; 9AC44E9E1E15154300619112 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 9AC44D7E1E15154300619112 /* LICENSE */; }; 9AC44E9F1E15154300619112 /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = 9AC44D7F1E15154300619112 /* README.md */; }; + FAE19C971EEA8EE4003B95FE /* LCCKRecordAudioHUD.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE19C951EEA8EE4003B95FE /* LCCKRecordAudioHUD.h */; }; + FAE19C981EEA8EE4003B95FE /* LCCKRecordAudioHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = FAE19C961EEA8EE4003B95FE /* LCCKRecordAudioHUD.m */; }; + FAE19C9E1EEA95CC003B95FE /* LCCKRecordAudioHUD.bundle in Resources */ = {isa = PBXBuildFile; fileRef = FAE19C9D1EEA95CC003B95FE /* LCCKRecordAudioHUD.bundle */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -1005,6 +1008,9 @@ 9AC44D7E1E15154300619112 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 9AC44D7F1E15154300619112 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; A9601FCE9729A0FE4669D33E /* libPods-ChatKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ChatKit.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + FAE19C951EEA8EE4003B95FE /* LCCKRecordAudioHUD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LCCKRecordAudioHUD.h; sourceTree = ""; }; + FAE19C961EEA8EE4003B95FE /* LCCKRecordAudioHUD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LCCKRecordAudioHUD.m; sourceTree = ""; }; + FAE19C9D1EEA95CC003B95FE /* LCCKRecordAudioHUD.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = LCCKRecordAudioHUD.bundle; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1276,6 +1282,8 @@ 9AAFA1871E14FBA3006618E0 /* LCCKInputViewPluginTakePhoto.m */, 9AAFA1881E14FBA3006618E0 /* LCCKProgressHUD.h */, 9AAFA1891E14FBA3006618E0 /* LCCKProgressHUD.m */, + FAE19C951EEA8EE4003B95FE /* LCCKRecordAudioHUD.h */, + FAE19C961EEA8EE4003B95FE /* LCCKRecordAudioHUD.m */, ); path = ChatBar; sourceTree = ""; @@ -1354,6 +1362,7 @@ 9AAFA1B21E14FBA4006618E0 /* Other.bundle */, 9AAFA1B31E14FBA4006618E0 /* Placeholder.bundle */, 9AAFA1B41E14FBA4006618E0 /* VoiceMessageSource.bundle */, + FAE19C9D1EEA95CC003B95FE /* LCCKRecordAudioHUD.bundle */, ); path = Resources; sourceTree = ""; @@ -2137,6 +2146,7 @@ 9AAFA21A1E14FBA4006618E0 /* NSMutableArray+LCCKMessageExtention.h in Headers */, 9AAFA2631E14FBA5006618E0 /* LCCKInputViewPluginTakePhoto.h in Headers */, 9AC44E6F1E15154300619112 /* POPSpringSolver.h in Headers */, + FAE19C971EEA8EE4003B95FE /* LCCKRecordAudioHUD.h in Headers */, 9AAFA24B1E14FBA4006618E0 /* LCCKFaceManager.h in Headers */, 9AAFA2D01E14FBA6006618E0 /* Mp3Recorder.h in Headers */, 9AAFA2B71E14FBA5006618E0 /* LCCKAlertController.h in Headers */, @@ -2422,6 +2432,7 @@ 9AAFA2871E14FBA5006618E0 /* MBProgressHUD.bundle in Resources */, 9AC44E181E15154300619112 /* ImageSelectedSmallOn@2x.png in Resources */, 9AAFA2821E14FBA5006618E0 /* ChatKeyboard.bundle in Resources */, + FAE19C9E1EEA95CC003B95FE /* LCCKRecordAudioHUD.bundle in Resources */, 9AC44E9E1E15154300619112 /* LICENSE in Resources */, 9AC44E0D1E15154300619112 /* ImageError@3x.png in Resources */, 9AC44E231E15154300619112 /* UIBarButtonItemArrowRight.png in Resources */, @@ -2556,6 +2567,7 @@ 9AC44DC51E15154300619112 /* ViewController+MASAdditions.m in Sources */, 9AAFA2D91E14FBA6006618E0 /* LCCKSwipeView.m in Sources */, 9AC44DCF1E15154300619112 /* MJRefreshBackFooter.m in Sources */, + FAE19C981EEA8EE4003B95FE /* LCCKRecordAudioHUD.m in Sources */, 9AC44E951E15154300619112 /* UIView+WebCacheOperation.m in Sources */, 9AC44E511E15154300619112 /* POPAnimationRuntime.mm in Sources */, 9AC44D9C1E15154300619112 /* FDTransformLayer.m in Sources */, diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m old mode 100644 new mode 100755 index 57a4bb04..171ea0fc --- a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m @@ -9,13 +9,13 @@ #import "LCCKChatBar.h" #import "LCCKChatMoreView.h" #import "LCCKChatFaceView.h" -#import "LCCKProgressHUD.h" +#import "LCCKRecordAudioHUD.h" #import "Mp3Recorder.h" -#if __has_include() -#import -#else -#import "Masonry.h" -#endif + #if __has_include() + #import + #else + #import "Masonry.h" + #endif #import "LCCKUIService.h" #import "UIImage+LCCKExtension.h" #import "NSString+LCCKExtension.h" @@ -333,25 +333,6 @@ - (void)textViewDidChange:(UITextView *)textView }); } -#pragma mark - MP3RecordedDelegate - -- (void)endConvertWithMP3FileName:(NSString *)fileName { - if (fileName) { - [LCCKProgressHUD dismissWithProgressState:LCCKProgressSuccess]; - [self sendVoiceMessage:fileName seconds:[LCCKProgressHUD seconds]]; - } else { - [LCCKProgressHUD dismissWithProgressState:LCCKProgressError]; - } -} - -- (void)failRecord { - [LCCKProgressHUD dismissWithProgressState:LCCKProgressError]; -} - -- (void)beginConvert { - [LCCKProgressHUD changeSubTitle:@"正在转换..."]; -} - #pragma mark - LCCKChatFaceViewDelegate - (void)faceViewSendFace:(NSString *)faceName { @@ -422,7 +403,66 @@ - (void)beginInputing { [self.textView becomeFirstResponder]; } +#pragma mark - MP3RecordedDelegate +- (void)averagePowerWithVolume:(CGFloat)volume { + [LCCKRecordAudioHUD changeVolume:volume]; +} + +- (void)endConvertWithMP3FileName:(NSString *)fileName { + if (fileName) { + [LCCKRecordAudioHUD dismissWithState:LCCKRecoderResultStateSuccess]; + [self sendVoiceMessage:fileName seconds:[LCCKRecordAudioHUD seconds]]; + } else { + [LCCKRecordAudioHUD dismissWithState:LCCKRecoderResultStateFail]; + } +} + +- (void)tooShortFailRecord { + [LCCKRecordAudioHUD dismissWithState:LCCKRecoderResultStateShort]; +} + #pragma mark - Private Methods +/** + * 开始录音 + */ +- (void)startRecordVoice { + [LCCKRecordAudioHUD show]; + self.voiceRecordButton.selected = YES; + [self.MP3 startRecord]; +} + +/** + * 取消录音 + */ +- (void)cancelRecordVoice { + [LCCKRecordAudioHUD dismissWithState:LCCKRecoderResultStateCancel]; + self.voiceRecordButton.selected = NO; + [self.MP3 cancelRecord]; +} + +/** + * 录音结束 + */ +- (void)confirmRecordVoice { + self.voiceRecordButton.selected = NO; + [self.MP3 stopRecord]; +} + +/** + * 更新录音显示状态,手指向上滑动后提示松开取消录音 + */ +- (void)updateCancelRecordVoice { + [LCCKRecordAudioHUD changeProgressState:LCCKRecordProgressStateOutSide]; + [_voiceRecordButton setTitle:@"松开 取消" forState:UIControlStateSelected]; +} + +/** + * 更新录音状态,手指重新滑动到范围内,提示向上取消录音 + */ +- (void)updateContinueRecordVoice { + [LCCKRecordAudioHUD changeProgressState:LCCKRecordProgressStateInSide]; + [_voiceRecordButton setTitle:@"松开 结束" forState:UIControlStateSelected]; +} - (void)keyboardWillHide:(NSNotification *)notification { NSString *reason = [NSString stringWithFormat:@"🔴类名与方法名:%@(在第%@行),描述:%@", @(__PRETTY_FUNCTION__), @(__LINE__), @"Should update on main thread"]; @@ -496,47 +536,11 @@ - (void)setup { }]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(confirmRecordVoice) name:kLCCKRecordAudioTooLong object:nil]; self.backgroundColor = self.messageInputViewBackgroundColor; [self setupConstraints]; -} - -/** - * 开始录音 - */ -- (void)startRecordVoice { - [LCCKProgressHUD show]; - self.voiceRecordButton.highlighted = YES; - [self.MP3 startRecord]; -} - -/** - * 取消录音 - */ -- (void)cancelRecordVoice { - [LCCKProgressHUD dismissWithMessage:@"取消录音"]; - self.voiceRecordButton.highlighted = NO; - [self.MP3 cancelRecord]; -} - -/** - * 录音结束 - */ -- (void)confirmRecordVoice { - [self.MP3 stopRecord]; -} - -/** - * 更新录音显示状态,手指向上滑动后提示松开取消录音 - */ -- (void)updateCancelRecordVoice { - [LCCKProgressHUD changeSubTitle:@"松开取消录音"]; -} - -/** - * 更新录音状态,手指重新滑动到范围内,提示向上取消录音 - */ -- (void)updateContinueRecordVoice { - [LCCKProgressHUD changeSubTitle:@"向上滑动取消录音"]; + + [LCCKRecordAudioHUD instance]; } - (void)setShowType:(LCCKFunctionViewShowType)showType { @@ -650,7 +654,7 @@ - (void)showMoreView:(BOOL)show { - (void)showVoiceView:(BOOL)show { self.voiceButton.selected = show; - self.voiceRecordButton.selected = show; +// self.voiceRecordButton.selected = show; self.voiceRecordButton.hidden = !show; self.textView.hidden = !self.voiceRecordButton.hidden; } @@ -773,10 +777,10 @@ - (UIButton *)voiceRecordButton { UIImage *voiceRecordButtonNormalBackgroundImage = [[self imageInBundlePathForImageName:@"VoiceBtn_Black"] resizableImageWithCapInsets:edgeInsets resizingMode:UIImageResizingModeStretch]; UIImage *voiceRecordButtonHighlightedBackgroundImage = [[self imageInBundlePathForImageName:@"VoiceBtn_BlackHL"] resizableImageWithCapInsets:edgeInsets resizingMode:UIImageResizingModeStretch]; [_voiceRecordButton setBackgroundImage:voiceRecordButtonNormalBackgroundImage forState:UIControlStateNormal]; - [_voiceRecordButton setBackgroundImage:voiceRecordButtonHighlightedBackgroundImage forState:UIControlStateHighlighted]; + [_voiceRecordButton setBackgroundImage:voiceRecordButtonHighlightedBackgroundImage forState:UIControlStateSelected]; _voiceRecordButton.titleLabel.font = [UIFont systemFontOfSize:14.0f]; [_voiceRecordButton setTitle:@"按住 说话" forState:UIControlStateNormal]; - [_voiceRecordButton setTitle:@"松开 结束" forState:UIControlStateHighlighted]; + [_voiceRecordButton setTitle:@"松开 结束" forState:UIControlStateSelected]; [_voiceRecordButton addTarget:self action:@selector(startRecordVoice) forControlEvents:UIControlEventTouchDown]; [_voiceRecordButton addTarget:self action:@selector(cancelRecordVoice) forControlEvents:UIControlEventTouchUpOutside]; [_voiceRecordButton addTarget:self action:@selector(confirmRecordVoice) forControlEvents:UIControlEventTouchUpInside]; diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKRecordAudioHUD.h b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKRecordAudioHUD.h new file mode 100644 index 00000000..38cb330f --- /dev/null +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKRecordAudioHUD.h @@ -0,0 +1,91 @@ +// +// LCCKRecordAudioHUD.h +// LCCKChatBarExample +// +// Created by alex-W on 2017/6/7. +// Copyright © 2017年 http://codewpf.com/ . All rights reserved. +// + +#import + +#define kLCCKRecordAudioTooLong @"kLCCKRecordAudioTooLong" + +/** + 音频记录结果 + + - LCCKRecoderResultStateSuccess: 成功 + - LCCKRecoderResultStateFail: 失败 转换音频格式错误 + - LCCKRecoderResultStateShort: 失败 音频时长太短不发送 + - LCCKRecoderResultStateLong: 成功 音频时长太长结束并发送 + - LCCKRecoderResultStateCancel: 取消 + */ +typedef NS_ENUM(NSUInteger, LCCKRecordResultState) { + LCCKRecoderResultStateSuccess , + LCCKRecoderResultStateFail , + LCCKRecoderResultStateShort , + LCCKRecoderResultStateLong , + LCCKRecoderResultStateCancel , +}; + + +/** + 音频记录状态 + + - LCCKRecordProgressStateOutSide: 手指松开,取消发送 + - LCCKRecordProgressStateInSide: 手指上滑,取消发送 + */ +typedef NS_ENUM(NSUInteger, LCCKRecordProgressState) { + LCCKRecordProgressStateOutSide, + LCCKRecordProgressStateInSide, +}; + +@interface LCCKRecordAudioHUD : UIView +/** 是否正在显示 */ +@property (nonatomic, assign, readonly, getter=isShowing) BOOL showing; +/** + HUD 单例 + + @return 单例 + */ ++ (LCCKRecordAudioHUD *)instance; + +/** + 显示录音指示器 + */ ++ (void)show; + +/** + 隐藏录音指示器,根据结果 + + @param recderState 结果 + */ ++ (void)dismissWithState:(LCCKRecordResultState)resultState; + + +/** + 修改录音指示器,根据状态 + + @param progressState 状态 + */ ++ (void)changeProgressState:(LCCKRecordProgressState)progressState; + + +/** + 修改音量 + + @param level 音量 + */ ++ (void)changeVolume:(NSInteger)level; + + +/** + 录音总时间 + + @return 录音总时间 + */ ++ (NSInteger)seconds; + +@end + + + diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKRecordAudioHUD.m b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKRecordAudioHUD.m new file mode 100644 index 00000000..1b4beac7 --- /dev/null +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKRecordAudioHUD.m @@ -0,0 +1,360 @@ +// +// LCCKRecordAudioHUD.m +// LCCKChatBarExample +// +// Created by alex-W on 2017/6/7. +// Copyright © 2017年 http://codewpf.com/ . All rights reserved. +// + +#import "LCCKRecordAudioHUD.h" +#import "UIImage+LCCKExtension.h" +#import "UIColor+LCCKExtension.h" +#if __has_include() +#import +#else +#import "Masonry.h" +#endif + +// 录音总时间 +const NSInteger LCCKRecordMAXTime = 60; +// Title 文字颜色 +NSString *const LCCKCancelStateTextColor = @"e5e5e5ff"; +NSString *const LCCKNormalStateTextColor = @"ffffffff"; + +// 结束 提示文字 +NSString *const LCCKRecoderResultStateFailTitle = @"转换音频格式失败"; +NSString *const LCCKRecoderResultStateShortTitle = @"说话时间太短"; +NSString *const LCCKRecoderResultStateLongTitle = @"说话时间超长"; +// 状态 提示文字 +NSString *const LCCKRecordProgressStateOutSideTitle = @"松开手指,取消发送"; +NSString *const LCCKRecordProgressStateInSideTitle = @"手指上滑,取消发送"; + + + +@interface LCCKRecordAudioHUD () +@property (nonatomic, assign) NSInteger seconds; +@property (nonatomic, assign) LCCKRecordResultState resultState; +@property (nonatomic, assign) LCCKRecordProgressState progressState; + +/** 倒计时 */ +@property (nonatomic, strong) NSTimer *timer; + +/** 整体控件 黑色透明背景图片 */ +@property (nonatomic, strong) UIImageView *bgIV; + +/** 提示标题 背景图片 */ +@property (nonatomic, strong) UIImageView *titleIV; +/** 提示标题 文本 */ +@property (nonatomic, strong) UILabel *titleLabel; + +/** 倒计时 文本 */ +@property (nonatomic, strong) UILabel *countDownLabel; +/** 警告 图片 */ +@property (nonatomic, strong) UIImageView *warningIV; +/** 取消 图片 */ +@property (nonatomic, strong) UIImageView *cancelIV; + +/** 正常录音 背景 */ +@property (nonatomic, strong) UIView *recordBg; +/** 正常录音 麦克风图片 */ +@property (nonatomic, strong) UIImageView *microPhoneIV; +/** 正常录音 音量图片 */ +@property (nonatomic, strong) UIImageView *volumeLevelIV; + +@end + + +@implementation LCCKRecordAudioHUD +#pragma mark - Init +- (instancetype)initWithFrame:(CGRect)frame { + if(self = [super initWithFrame:frame]) { + [self setup]; + } + return self; +} + +- (void)setup { + // 只需要初始化子控件 + [self titleIV]; + [self titleLabel]; + [self countDownLabel]; + [self warningIV]; + [self cancelIV]; + [self microPhoneIV]; + [self volumeLevelIV]; + + [self renew]; +} + +#pragma mark - Private Mehods +- (void)renew { + self.seconds = 0; + self.recordBg.hidden = NO; + self.warningIV.hidden = YES; + self.cancelIV.hidden = YES; + self.titleIV.hidden = YES; + self.countDownLabel.hidden = YES; + self.titleLabel.text = LCCKRecordProgressStateInSideTitle; + self.countDownLabel.text = [NSString stringWithFormat:@"%ld",LCCKRecordMAXTime-self.seconds]; +} +- (void)show { [self timer]; + + UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; + [keyWindow addSubview:self]; + _showing = YES; +} + +- (void)dismissWithDelay:(BOOL)delay { + if(!_timer) return; + _showing = NO; + NSInteger delayTime = 0; + if(delay) { + delayTime = 1.5; + } + if(_timer) { + [_timer invalidate]; + _timer = nil; + } + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + if(self.superview) { + [self removeFromSuperview]; + [self renew]; + } + }); + +} +- (void)timerAction { + self.seconds++; + self.countDownLabel.text = [NSString stringWithFormat:@"%ld",LCCKRecordMAXTime-self.seconds]; + + if(LCCKRecordMAXTime-self.seconds < 10 && self.cancelIV.hidden == YES) { + self.countDownLabel.hidden = NO; + self.recordBg.hidden = YES; + } + + if(self.seconds == LCCKRecordMAXTime) { + [self setResultState:LCCKRecoderResultStateLong]; + [[NSNotificationCenter defaultCenter] postNotificationName:kLCCKRecordAudioTooLong object:nil]; + } + +} +#pragma mark - Setters +- (void)setResultState:(LCCKRecordResultState)resultState { + if(self.isShowing == NO) return; + + if(resultState == LCCKRecoderResultStateSuccess || + resultState == LCCKRecoderResultStateCancel) { + [self dismissWithDelay:NO]; + } else { + self.recordBg.hidden = YES; + self.cancelIV.hidden = YES; + self.countDownLabel.hidden = YES; + self.warningIV.hidden = NO; + if(resultState == LCCKRecoderResultStateFail) { + self.titleLabel.text = LCCKRecoderResultStateFailTitle; + } else if(resultState == LCCKRecoderResultStateShort){ + self.titleLabel.text = LCCKRecoderResultStateShortTitle; + } else if(resultState == LCCKRecoderResultStateLong) { + self.titleLabel.text = LCCKRecoderResultStateLongTitle; + } + [self dismissWithDelay:YES]; + } +} + +- (void)setProgressState:(LCCKRecordProgressState)progressState { + if(self.isShowing == NO) return; + + switch (progressState) { + case LCCKRecordProgressStateOutSide: + self.titleLabel.text = LCCKRecordProgressStateOutSideTitle; + self.titleIV.hidden = NO; + self.cancelIV.hidden = NO; + self.recordBg.hidden = YES; + self.countDownLabel.hidden = YES; + self.titleLabel.textColor = [UIColor CJ_16_Color:LCCKCancelStateTextColor]; + break; + case LCCKRecordProgressStateInSide: + self.titleLabel.text = LCCKRecordProgressStateInSideTitle; + self.titleIV.hidden = YES; + self.cancelIV.hidden = YES; + if(self.seconds > LCCKRecordMAXTime - 10) { + self.countDownLabel.hidden = NO; + } else { + self.recordBg.hidden = NO; + } + self.titleLabel.textColor = [UIColor CJ_16_Color:LCCKNormalStateTextColor]; + break; + } +} + + +#pragma mark - Getters +- (NSTimer *)timer { + if(_timer) { + [_timer invalidate]; + _timer = nil; + } + _timer = [NSTimer scheduledTimerWithTimeInterval:1 + target:self + selector:@selector(timerAction) + userInfo:nil + repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes]; + return _timer; +} + +- (UIImageView *)bgIV { + if(!_bgIV) { + _bgIV = [UIImageView new]; + _bgIV.image = [self imageInBundlePathForImageName:@"chat_record_allbg"]; + [_bgIV sizeToFit]; + [self addSubview:_bgIV]; + [_bgIV mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self); + }]; + } + return _bgIV; +} + +- (UIImageView *)titleIV { + if(!_titleIV) { + _titleIV = [[UIImageView alloc] initWithFrame:CGRectMake(7.5f, 117, 135, 25)]; + _titleIV.image = [self imageInBundlePathForImageName:@"chat_record_titlebg"]; + _titleIV.hidden = YES; + [self.bgIV addSubview:_titleIV]; + } + return _titleIV; +} +- (UILabel *)titleLabel { + if(!_titleLabel) { + _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(7.5f, 117, 135, 25)]; + _titleLabel.textAlignment = NSTextAlignmentCenter; + _titleLabel.font = [UIFont systemFontOfSize:14]; + _titleLabel.textColor = [UIColor CJ_16_Color:LCCKNormalStateTextColor]; + [self.bgIV addSubview:_titleLabel]; + } + return _titleLabel; +} +- (UILabel *)countDownLabel { + if(!_countDownLabel){ + _countDownLabel = [[UILabel alloc] initWithFrame:CGRectMake(25, 16, 100, 100)]; + _countDownLabel.textAlignment = NSTextAlignmentCenter; + _countDownLabel.font = [UIFont systemFontOfSize:80]; + _countDownLabel.textColor = [UIColor CJ_16_Color:LCCKNormalStateTextColor]; + _countDownLabel.hidden = YES; + [self.bgIV addSubview:_countDownLabel]; + } + return _countDownLabel; +} + +- (UIImageView *)warningIV { + if(!_warningIV) { + _warningIV = [[UIImageView alloc] initWithFrame:CGRectMake(71.5, 41.5f, 7, 55)]; + _warningIV.image = [self imageInBundlePathForImageName:@"chat_record_warning"]; + _warningIV.hidden = YES; + [self.bgIV addSubview:_warningIV]; + } + return _warningIV; +} + +- (UIImageView *)cancelIV { + if(!_cancelIV) { + _cancelIV = [[UIImageView alloc] initWithFrame:CGRectMake(49, 41, 52, 52)]; + _cancelIV.image = [self imageInBundlePathForImageName:@"chat_record_cancel"]; + _cancelIV.hidden = YES; + [self.bgIV addSubview:_cancelIV]; + } + return _cancelIV; +} + +- (UIView *)recordBg { + if(!_recordBg) { + _recordBg = [[UIView alloc] initWithFrame:CGRectMake(42, 30, 66, 66)]; + _recordBg.backgroundColor = [UIColor clearColor]; + _recordBg.hidden = YES; + [self.bgIV addSubview:_recordBg]; + } + return _recordBg; +} + +- (UIImageView *)microPhoneIV { + if(!_microPhoneIV) { + _microPhoneIV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 39, 66)]; + _microPhoneIV.image = [self imageInBundlePathForImageName:@"chat_record_microphone"]; + [self.recordBg addSubview:_microPhoneIV]; + } + return _microPhoneIV; +} + +- (UIImageView *)volumeLevelIV { + if(!_volumeLevelIV) { + _volumeLevelIV = [[UIImageView alloc] initWithFrame:CGRectMake(48, 15, 18, 51)]; + _volumeLevelIV.image = [self imageInBundlePathForImageName:@"chat_record_volume_0"]; + [self.recordBg addSubview:_volumeLevelIV]; + } + return _volumeLevelIV; +} + +- (UIImage *)imageInBundlePathForImageName:(NSString *)imageName { + UIImage *image = [UIImage lcck_imageNamed:imageName bundleName:@"LCCKRecordAudioHUD" bundleForClass:[self class]]; + return image; +} + +#pragma mark - Class Methods ++ (LCCKRecordAudioHUD *)instance { + static dispatch_once_t onceToken; + static LCCKRecordAudioHUD *_instace; + dispatch_once(&onceToken, ^{ + _instace = [[LCCKRecordAudioHUD alloc]initWithFrame:[[UIScreen mainScreen] bounds]]; + _instace.backgroundColor = [UIColor clearColor]; + + }); + return _instace; +} + +/** +显示录音指示器 +*/ ++ (void)show { + [[LCCKRecordAudioHUD instance] show]; +} + +/** + 隐藏录音指示器,根据结果 + + @param recderState 结果 + */ ++ (void)dismissWithState:(LCCKRecordResultState)resultState { + [[LCCKRecordAudioHUD instance] setResultState:resultState]; +} + +/** + 修改录音指示器,根据状态 + + @param progressState 状态 + */ ++ (void)changeProgressState:(LCCKRecordProgressState)progressState { + [[LCCKRecordAudioHUD instance] setProgressState:progressState]; +} + +/** + 修改音量 + + @param level 音量 0 - 120 + */ ++ (void)changeVolume:(NSInteger)level { + // 转换为 0~8 + NSInteger l = level/10 - 2; + if(l < 0) l = 0; + if(l > 8) l = 8; + [LCCKRecordAudioHUD instance].volumeLevelIV.image = [[LCCKRecordAudioHUD instance] imageInBundlePathForImageName:[NSString stringWithFormat:@"chat_record_volume_%ld",l]]; +} + ++ (NSInteger)seconds{ + return [[LCCKRecordAudioHUD instance] seconds]; +} + + + + +@end diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_allbg@2x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_allbg@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c334ca5c1ebdfc88ce4d4369155713d1076b5ac6 GIT binary patch literal 2058 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&4mO}jWo=(6kdiEMjVKAuPb(=;EJ|f?Ovz75 zRq)JBOiv9;O-!jQJeg|4z`(4L84^(v;p=0SoS&=?Nk^)#sNw%#L#8DBx0SeCfMX3s=dS<%GhQ<~O=9YSf zrj`~)COQg628L$(2A2AUCb|ZORtA<<28Ieypait7C?(A*$i)q67m#PGlu=SrV5P5L zUS6(OZmgGIl&)`RX=$l%V5DzkqzhD`TU?n}l31aeSF8*(!6mggxhS)sBr`ux0c2ug zQhsTPtrF0s5HI8wz>Uo-h6WQb!1OB;3-k^33_xCjDfIQluQWFouDZA+C>7yetOgf{ zR2HP_2c;J0mlh=hBQ8xDWL1Hcb5UwyNq$jCetr%t6azByOY(~|@(UE4ok5{yuAt$Y zn4Fmh64V6i^7Xay%quQQ%u7!7bg@+enxmJQnPTN)X=3hVXkuVuZ02NW=xXk0VeIT` z>S$(UWNB#WXzl{j>yn>bnwy$e0@Is<&})cOFDOCe765H_NiE7OOHFYr%Fk5*d)z7$ zn_G+=&5WIlO>vqB)tiFNEfBqCIQ8lS9itD5UZm)T2?5g(hzU=;Kn^_lr{)3Ed=W5l zU*PoE$H2f+;pyTSQgQ3e?Ty}33T2Lee7;9z%7ra097~lK-jP~kd1yh~GPmjfwux${SQaVK%yl38ge!wX%vt0D%`v+f}{8QRbmsb>jzhJs*@!ZqTHr>q8 zl0G|2^uYa_r?+iBn`4@tKL6KWr^V;9*S-lWI~m(3{7J8R+FDujh~=Ah-~1!!$oxb6 z+vce`mcQ@mM=0M+GJBkMpnlst-BjznO{Q~fPb|C3sd2>Zo5Ah1^)Kow>hyQNvU6}e zw#oSB>~{%US2aHmn-|HrbZ3C9P0xKRo@;;Ktl7=Ly6V1%Z`%4MBI zK_&qmhYbuY+&}`v1`=R43pbcejHG~$Iz{@SHdE+|QB&|n-4F@gA9oYpS~43je0!CU zyBkPvoBi{#m)S!xhlh4o4$e9gmB%RZu2gnS{>{?u3|!k|*k5~>SxT4lF9>+Q`T5y% z{PQ;GNfs?tp7+&%eB`}~%M$>H{!qfX9C*?m|43wMxq^og`P{1%F@ zZ(hz>d%gR3C3~se?9*wRSLQ7F_4TIsf%z-;AKx=MH*IyK_3s<+#p}2X7$$ylihpQ- R$_-RId%F6$taD0e0ssdFpC14K literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_allbg@3x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_allbg@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..54003473919cf267775028ef835968659a71496f GIT binary patch literal 2870 zcmd5;Yfuwc6uv21QZ2|7U*KyAjG~fvNJu1L9-vW!DW(-m5kj&+B%585g#-%n5LBvA z`%)=_POW1tMM`T$WdKW+ht-HvumNO{>0o_;SP@&ppxs5l{wV#Ooo{FFo;lxl&OP_c z*)3E>taF>?JqrNfrdThJ1c1^=-qhC#OXkAXFyi5bhehFA&;;C~F~LBhL*rpcfoKxp zNLZswPicjN0dVoxtE2EJR=}fd=Vy zV%pX~B}<9P;3WO}3=_O1BSNjsNY)BWX5i>zYWxUPs;lV&Cj z8h62y#k7}6MJZK~3^l<}AcIfWvbjN!K*(SR3WGSj0Eok4^O-Cmlg*>E*dmrt#9~7e z7mbK!(j|x@<>3>th&M4U3CA%JlWDP77#1!AH6=3HLZOh!;xIWJI^jV#ryFsNm2Ncq zPAbS@v(}`?a6M{-NJULNnu?2QM5ZsdfM8RyM)O3Oh=MV#8jQ(iu*fY&1kAgOB`H+FBu9G$xN^YM@?!JHB44fm4xD`ISIuenT)KO z0P}fe^-)Dc{;B$6NAPe#;EhvMRrBv8*Ar87xolY4vxenA6?NuJI>hDbYvM28~xHw zbUmxTt*L-&WVG2W^?17fNg%zs>6m}Y&R=*LzihOn7h1N@VQU$g8<;)-uY%Icu1WT`5wS& z;WGm`CDu|YP77yiw7=Q;(Z$59Ltv_)%moy5UG=CpyMwv+V|G9KksO8ApUxpE4fC_4EY{06NB_l%JW~{`=o}>5}?}Ke<7<^c5X>+Y&J33 zlLbSiH&45UTq;dYEr%bo$XnlTy<+&|77YRl|Cli7T@U{}aJOZKgjP{y_1W##*dnw#R+t*YY9y#1mj swl`~kU14R@!Eee!Y1KCd1&&o0!Mj5VygZ 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 literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_microphone@2x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_microphone@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d28cbcc69bbceb182630da130118656fc8536ecd GIT binary patch literal 2905 zcmaJ@3piAH8z1+GqR6FWj8ZNxoEHnp(K}dQR7k} zCU&r>#Ah?L(QX-AtUkjs8xbP48*Ns7!&bY`^L>5idCvKt_x=BVzxVQgpYxm?D#cq* z$4mzTf#{KZ2>!~IqP#QLXeys>gXX=;#gtDB=I`S~@ek3s0K}caIS4>WELt?+56~D% z3Eu;*5Qy4NW2Q8<5s*N0e23lEFo^FbT}ap=$?_#p>4hZ~Ks$6~PvBnp8-*(niryd*ZC zCbVPotUf9b03Myo1o=!38@i%MJIE36@i1kkf0n=kKgqIrAKIjB7(z$`5%zH8N=YAq zWb*%qvRI$cJib5hSHAyKm=}-)0tkPA#}RPp%7crtS_uW>Jh=dk&*27eIPo95NR8p} zIlLGS2=(+_=^6&QlT4#C*(*+)RTi0yBe8jW8k-J~2zZ!M2hL&MKb#%bE z+uIW{?gURH(b*AAP_~VTCSX2t2^_kB1+e)axs1QK?w{qZ34|Ahw8z;HW!XCVEgMHo_LBg1ciaK(>F zAQLuh)G#3SuZIye(y1N+Crv614xCKCv_=owWV+PZN)0p9g}U|9WRAVX*k-}V>;sVU z>dVNek?_=xp_{zP5ns29TDQ*Ke+oS~lWCUOwpD zX5&Qh5;WCG=k@+GWnO0#<(_$2Z{#Kv`q!O#1iZ>i%$~811QqX}-<1?@3Dv(#z0#pT z=}J)Uihp2xF666w=dta!^~Mejx3syCLL z){e?j)FV~ut+N!dzG?TX^~0`dgLwZn^^eqBPZ(yn+^=d7S=$DI*}hU6XN?+#VW}u% zAE-l7TIf|%X~nLZ8a36*-PKLDydwV8??*!697l&Pew zq~PsQ;(K_FT}HV#*;WYRfKd^DUG8eB_*}_w5A^KG}mV@7}ayg zmaP&M(=AZ2J*%X6&Es1>maT%@uXD3z+O@+@gS_KlhYet^{uD@|YO1pxoNswwa*{Ev zHYO(uPIO8(y^64F`SrKwQL5gEs6_4b5qMZcDGbb2n^<;f58A%uD~xFc%dRhv7OTcA zVG-`H-Z3vXygfDlqeStq?fOQKlWZWEFU8e(>8p(kN;k#r{4KlrCuU|3)xj;FYHcZsqsd%x1!vmV>3NwFE+2JM=R-7qE~{$)8Ay5AKsn1 zV)bI{hPj8rXQ}F zl(Abowtkg;Y=?hlT<77LxwB$vr1=z6?!+Co4KJUPCKc**?k`>#F&egSq!47XH z{Jfv@=ncmtSc|g75%L_`jn*Bmc~fU1hZH>tZ;QOg6n+`TjWvF`$)V?i=i}_Q zc-bAh*(u3v)SGBoSTvcD%%2#3QH(ZS=<7;JyQ*{;h3=3&xF$|_ou9iKcr_#C+Wzvh zZ*sIMhNuzg0ufMHS!glw@JLW`w77+$Zecrf^s6F<#XaXA#%?YO6QzWbiSBz=LZk5< z($G02{&>S~uRe zxUuuOYB@KbXB%3{#CibpwOW6;Qx;vP2105^&7 zp8Z4m*FhV=&W=Hp1wQujT2Dmwv-1nRmzVF`#OOSW>JN|Xu$o_bIkJgex0spN+M$Ry zj<;@ia<5}JtY4o97LeXvIA+$}T2^7?8GZCMlNzy!{4#8^nPDVPNZcO%)}-ysmQt3Z z=O4J~>hly^$y3YkWjj@Kxi&NKdZ+PfR)ImIHKota&pp?yl$GZi=s7E^UZ;LNrw>`! zXE-%kaV5l+)quFE`E{1<_&ReZNL|*L+3kde>>%)Adb@Z4xcwf2c2%=`FzpPwvDK} wNfbY}b@HEV-5W-v7OOBw`MO`n-m9BHepzZeh}Jq)xbm}0B2ozT9+4UU0oRw-xc~qF literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_microphone@3x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_microphone@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..07fefbc0aba3837814f287b30b63ade31edd22c6 GIT binary patch literal 3965 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 X`hHxU1Drdw`9q9FSs?Er&V>C39;*y1 literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_titlebg@2x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_titlebg@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ffe9fc8ffa1e02803dfb1a1710a165604fb2d455 GIT binary patch literal 1187 zcmaJ>OK1~O6n!;NL~T(~MCoFjy71HF%_Pldrb*K@6K%w)F%1|H)XB_iGqm$@=GCMT zU5E&RiYOw2zm3Zl6t$sUbfv|W9|T1aj0<%kD!Nb?72l*ut6-eP+z;oRd*6L`=2WVG zN6WGe%K!i^$vzEVuY^h^2B%2kfy2-JRG6to63qQDsEVa z@_Pbqne~OJAm?HIT*%wmL3tTA02vOlooV<7KtKs9%GY- zuuv#?3O_p~sp!`2_PTHHBi zb3s1-=;s)EDQYIg_ zkc15@V;Cd#DW>uUHtf7%Qt`MmwIH=wlw?(Rl3S`QQRI`ljU`=1Ng+ZL9gnIiJj*2n zpU@lY^abK9n+V22zIehP3wXU8%f*61ohumfsD^Z0=PHZb-iBOfAvBXz7LcVLM#^@} z(5ULcd9`sbp@w=juF|*{t|1qaW}tJue_VGxMRv$>7nYX<3+s<`vhx;M?r>)LA@ZfI zN(!+|@#V)CGiRHmH4iEqcYZqgSpWR!?&I{+i7s5kUp8a`a-~JIfdJ8@Qzdl?F+_||{gn={TubY4L z+(|nJp1qT zn`ouXxl)yDmGTrZ=PNI!T`B2$B`l7Zv-YfDyu XzKM0;w4>k4&Tk``=ocn>4<7#wfsub& literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_titlebg@3x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_titlebg@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..b64f45b447383166f5362e49be2637c117d8cab6 GIT binary patch literal 1354 zcmeAS@N?(olHy`uVBq!ia0y~yV4MnMdvmY>$sH0>7l4#xiEBhjaDG}zd16s2gJVj5 zQmTSyZen_BP-l zO)W`OsL0L9E4HezRRWu91!RMS^_3LBN=mYAl^~9a@C{IK&M!(;Fx4~DO*S;PP%yXD zGc>idFf!3mFfuSS(>JixH#E^TFtjqTv@$SMfC43;ZAB?*RzWUqP`iLUTcwPWk^(Dz z{qpj1y>er{{GxPyLrY6beFGzXBO_g)3fZE`@j@w*YQzUNJP7fB~jokyxN_sAmB35=^15FMg%Dxp39RB|)hO_hL1; zIHa;5RX-@TIKQ+g85nVC${?!>telHd6HD@oLh|!-V4)b0kzbNuoRMFk;Oq1&oCuf{`K?x$a0BEyIYEfocYKmJ? zey#%8<5rot-GbXZsNNK8Zh`p21*co|fsWA!MK4lx!-Rlo2*iXZULXga{8RIQX}$=U zxD9=G&j#kS9iA?ZAr-gY+%oiI3KVGzl-RyNr-3&jVag5xSKjE&3k7mxTf~BPFzA>{ z-eo#cJ=vVIgh@Z_xk^3r-Q0b9Qht4Z+f9f!sO{sqXKD$Zw4B&nMN9uZ_J#{ zP|)z^gvw&0Qf>yV8D?>s3?W6c0xiqf8MGu!@)#Uc-4`)Am@Z;!Sizv6#n8b8LNFdg zU=b5s07)9I9!VOe9w-Nwrogz4E@7yfz;+ziADJ3bcZaco>sHUH+13mJ2dmvupYbt- z7@S^lW^WjSML=1~yuirgY8$WlGTd;Ew%YV=-@mA1ddb||857vMFZI7UaZUZ`&%>2( y%)ZI|?pb?>yMgy+>-tNbyD#;oet*86ftev#L35|mvGZF%rJJX#pUXO@geCx3i@6{G literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_0@2x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_0@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e88910b92a7c136d3c9c6c511b5cad6deebaeec1 GIT binary patch literal 1119 zcmbVL&1=*^6ps{C>aO5L&{Ie~STM;Xn=~IZ*4<>+F1TyiuGouUb~3vg+I*Ny-E2Xu zJykCj`~xg{(u3ed58~IcAc)uc2Y9d`dgw{e$?m3lCO?>$#i%HFRaz}9Q*M| zC?Xl3*dZ@)fcL!gUITQD8|Y6O`=aA!KSX>3#ldm}Nj=&V8JTEzaG(@Ove7R`E-8w= zWCd{9Lq4ur21EXEj_c?`8x~qxyTEErOJ=1hO=eXf3#_EtqEt{|3jj6qvmd`yGC{GT zsRUaRgtAh!Oi)%O*&;%gWlPDpRX@hI4^bA|C9y|bEUErsNuaW6uCE%Q;7nP9w@E5`($A&HdG|RVIhPHE45XTRV7Vh zB}ak45dmn)M1djS`CkQjk`$k|%U|u29g&_)mwUrNHhbfQd@@538J3OjyL~cfx2jgL znQZTTex6^wkQ;kRlW`*6LphI1z>o2yLe%b`aPu63R~{WSTtdot_(f3Tak*Is=1 s`Q!c0z4h1gX6NPB_MPK-!+B$b#{gCOnA^Qy&$;QySIc$lS?T)PZ<3)}LI3~& literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_0@3x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_0@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..e70e16aecab58cba13576419ccb73446c561eb0d GIT binary patch literal 15145 zcmeI3Ply{;9LJy9imsLlQmoR$kSbW)$;>1(NoGj0>?XVJg4wRy)o$_NPG(+`vB}JI zW_FWZFJh^p#mip&i{Q;uz1h+hD}@$32&GaFq97__rBIZDh==+ne}9`leTx*lyg)X; zeee7I{oZ`upP9?NH9z<4j*>)k9H%Zer7E$1xtnJG{dPyb<-*0Xrty5HA3m}hN~M#aljRE*|IZ{o98Y>ILpjL z4l4z*;O20}npyYoq4l{%WBsV1nvwDBSh}H+1T`G!T%%UCeXWs+H1ldC4x5Dt*OUZD zGm(j~Ah%SQ=W>pRIVGCl4Jn@Dl4?{^)KpA9z{Nx76tP^Z7R z=3-$1`_77IU?Sf;JkiuD8D0Bow~%OR72CnkRAkQXoM>2m)98BK6|dR^Z5jfu;u@*r z69&>y0B*$z9KYg>DB109LL62&uu3BUhCL%~xM7X3g*`1>b4|6TI!&My3fe)>BFkT| z<{e`tysp`NmUKi-%haTj5ihExIIo&Tg_jem!ly(<;^mYcljBLFD2l1HFfvVVRkceE zDKR;j6DOwC6iGKJNmI#*d`_H7$x5EA=qV+i?4$?QfwZ%>ALzD$+atHg$kk%0RE#SI zUn<2?yo^gSpNg3hFG-4SDq=zrPwGZemQ3C-j3h6YQZYUyt12&>NkcSaqF7W2%>jFFOr$`%)ouRQxf-zd zvUhNROCDS-GnOAX-Wuo#2NfPAhw!n@t(}glwMBAWeq`5cx)B~ySzjmgLnxrFH{_Nh zEYuPVfxfkcFkl~Dqh7&wmYmv2UQF;}a#2cXVnUPR`^A(dik+c0Ril&mPARDC9-b(Z z4VP`*CgwY*2A9i)w}mA4bU`;PJ3LDEb@FaDjxJzSbi0hrtk5xb8u~41A)LIbwR!GZ zt(&K`vpxowK)AcLoQHL?G!`AFy0r`HH}yu=%ZKxNfct4nT3qhX?j~s|`*IW<(<-eE z%K>LB%mI}BImkWT)B}A>S)dl=F%7Nccr`u9S~b0l1=lX8gZ&Z#;c85YjQ z)55T3;0o^w;W(?)Z2UvBbsZWyAM-&Aq{M)v|?tbf$J6mCQzqRLl z!M1{ItX-|I8Mwk*R}01=^0IYL5&$MDk3OgxF8K`%y3Z= zK>@=BX;5Q^i;4&e7%oVI8Z%r}L{PwRK^oMU;i4jf0)`9HpvDXr6%iCLT#yDeX1J(` zpn&0mG^jDdMMVS!3>Tz9jTtT~A}C8PsPP?fjrHEb#5Q^LvQFNy zd`CWzChuo*#>_$iq4lQ_dhIwuf8Qp**AZF~5&C@@A?-bc9& z`CPkx`PiO~8z*0V^NX7YPhQ;Eb9nb}pA>hEU;4DX;cvfj`rhg*e>Bc-eE-skAD&sh zcBa0odiddgUi|XxlkfgCzFPQm>Fh5%5xRZ*J~UT(oI7=EUxr*inw^@Eb* zx;~<%SQ88RxI)WnjF(hJ5ZBQH;F~z0a=gd_UIVHIczSLy#G7vxw5;AS=ZowTOc7&G z9g4SR^oqQD*UA<0K!Rhdk*`@5qE zNTSiU`4&lvF{rz6$VLuM>j{Q@iJ6wE@dX&qtA#kLnt6#8n^cKafW)(+VhCbfhIs&# zvYmza?d?g>)}e|7+s^YTxlK=klp;zx5i%v|a+#ZU0&F-Cm3>>p_Z&C=SFV=yk%3)5 z=emRCD(EV@*bR!VM<De%OB-aJ|Z<4E$5qoZ06euIi!bt z(kxdG3s*>^-A?Omxp3;s)MVWQP)prkc6wjW&8PI4hEY&axpZ|kH&(l$ac@Jz)aH}Q zmLGj<)_1nlk4`5qy{((9sQ#DnIatv*uzk;yiOVOB9@p@Zrt98?^nrU1KYn7*2DRhg z#@}RWPG#S{-uo4QIM>77`LN^Ot-)uvzNnvCUOig*^7#vPdGSz{wz2a3$z|apK;2ke VKlXmf_tnwgBAx2gueI;o{|nheat{Ci literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_1@3x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_1@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..94251ab533c77f6bf944bd00c4eaa8d4529da962 GIT binary patch literal 15264 zcmeI3eQXnD9LJAnhzyWKVn&9+ql_S8dv|TG?OocEt=(J=9djEvG{oKRo^I#bUb(x{ zZkk}gh)NX0VpKvT(Z9$dFHXcaLYNBC7$6~lF~q1*6Ln;XphOeY=lc4rFFcDO{`Fke z_P6Kx{$B3$yxl+dd{^g#3mcjmD2iGb=?HhjUl07ee#cz+tt|TdC-^fj)v?K-sQHVn z&m3y+z9keT98!Dx%)aP4QPvU;Nzn#?Bb!J;HAVT?W>b44klHb-gPzgOUU_s_78KjsV1qv^!T}P4rt!tvCEvxM|%Ya#|u8E`vKa?avp{i7|v~HIgu4amZJ-oE!Y4p zzpli@?r?h{9sDm~8#2w5$S|2q#*uM3G<}fa1VLa}C*yS5p~7yABuy!6PZ}%oL5gw0 zz>sw{WvW_|w&F?yTG|ZQY*wPuRk*K2DjF@NN*V=vkRy|oQVi!{nM8uA24 zPosAv1(*x^*5f(Qip+pG zNWeS>WWdz~kQ&lV%^1?^q%3vkAl6E3s>3baF1w%%@OHOH;O#z^=j?8uF{7l_2 z&FALBa7MTBVQ(=!;#w6pk~B;yDT6}gDy*D! z14&`sR;e!d72}q!36$%xAI@d zs>;0_y+pcv%hi*mLp4lIA3-{-qO7f?2W*+yTI`6cvm{sI2Uoo)$<`(nG$cshf`YV_ zOU`>(iSmLP&}TOhs@&`6$P9sG5boMuJL|Et-d@flvhdHfhV_XoTP!uFsvpGAVrE9t zLCYXqaKZdB(N)|v=upTy7QFO*QAt*l)>g8*7`URTW1bwaeh=!0c&-OAst9?YV>Mae0Dcf=~S+)91nyg6I9ZM$E2r7yA&j^tcVfS z6g4(dD+W4ZRt!X083Uf_ieyT&ih^p9IEpOBG(91iK{X)_0w$Fl^fTo~L|Hl;#E=%( zbXXP$y8KM7X2i=n6|8+6P9`b0Y&btt)mEwRvo^4JI;Z!--G^lv&iXF6qTQ9Qn{Muk zc2~NVJvSs(Gw3X2t7t~NtfMOrqX#~&fuM)yUA&*EY_9a^QnMi57gphkW>^~u?=JXM zcGPs-RCeTe$Um1Y=ZW+bJo9S>d9unarF<)VZiA1EOzD|%<|->~U$@vO-_k7(jD{mg zP#Rd9;KCw81q2sL18WmpSVX9R;6iC&ZGsDn2o(@qC=IMlaA6Ul0)h*rfwc)PEFx4u zaG^A?Ho=8OgbD~Qlm^x&xUh&&0l|gRz}f^C77;2SxKJ8co8ZDCLIngDN&{;XTv$Y? zfZ#%DU~Pg6iwG4ETqq5!O>kimp#p*nrGd2xE-WHcKyaZnur|SkMT80nE|dn=Cb+PO zPyxY((!kmT7ZwpJAh=K(SexL&B0>cO7fJ(b6I@tCsDR)?X<%)F3yTO95L_q?tbJ2l z4du5mK@z@tnSt+EdbczJ_zGgj;&EUr&7%b==;vWbU_(6Jzwni6h6}O)uY>TF|J^nSYnuV*7+X_40Gu zPEFo(^3p5j8_a?9^`6Z)HXJ|d-hcM|=|?-)&tLHWTvKa@*=4)Wj>X+i?Y#P3>iw(J zhnpXJaaCsGiPb?q9B38}Y`@`tcJuE?M!wv0`P$u{1KW>&8rV2_ap~kYB-2(rjyCBb>sb~&%DqNuj7mMM&4UGC2JAK*vA_u?`+!V?;M+2C5%6F#nZQX zeAmN&?LOLZZmjv<3x^LbzINRvZ2RNwHNjOMOn<*Cz4?6erCn$G8h&lcy!ykN?_4#GXC506Sq-^R(enGzkK;`>mAxiTW9!SYyb9t0bJgg AbpQYW literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_2@2x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_2@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..786c52d48480fc6c726e7a5ab52acf9dd8420862 GIT binary patch literal 1210 zcmbVMUuYaf7+;%GOEFjw1WPUBMntiDJG-}=-C1(2cefXF;wABVv@z{N=VoVf+hljv z-AQi~Dq4#V1q;R2hZIq3Q450LQ$=Z25Jb}#A%&9mN%TPxeGuwH#X6hhq7R{n3%m2p z%j*#1qmL+-R&Dj?y)v1Z8T5V^u3aH4O8-R?sPL(tpC(5S_N>VyZT2%4QQH>fsOc zlm&Npca#G~G|pHOh@#*bmyy|!M!fEpWN}mQ0?*NWQfwo?s35OxD#jo(6&sqGV%S(W ziWX@@X!q=Fq+h92VR;xqfvsp-%__T9ShEe&6-3rd*Xrrkqm<)_(4Ox=_(pCS>1goo zx=uBrn6sqC*i5er#ygC&w8LUht>#s?z~c=}f+#WQ0o=uy#ZU;~O2jRm{e|S@Q$vbrUj|1;L zaPHdVWB2Yr=PmQaV~e+b%3>Q-@?V+=`+fWCI8~ZtMu literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_2@3x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_2@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..36e2e635366d3b2bae22071036ae3fe2b0fa249c GIT binary patch literal 15348 zcmeI3TZ|J`7{_PXmAES+0gMQ1Qj6dPrZdxa+Ro6{blY8bmEyWAvP6wLojKi3XlKgI zEZeQoAZQ{=q7gLUC4$C85fL;zC=u{N%$gWAUV=PGf(c%Nw_sR>L_E{$*|y8s7=1gN zwEgy+|Nr~W{LW?OWj6P&xaIP;`E3+MUEb3j>w~{O_}Ovkboi}YF?I_6v}U{4m=tx{ z9Q)HmJ@ec=iW1&X`vj5db+}p1$FKs!d1;mtSwUnuN9oTQ zZi7+KP?BO_tgBQG{ugqlEGsKA%*e=yYsBNyjUk2;1c71QjN45^1#OOMmXxD4b73(_ zIZq6jvY}=zRo5JLUMZmuTOp^@E>!s|T~{U>k5@`*W{Do;$mFCf!?{={lVKV;O{))7 z2ieeR_K#)((+5m_*pLB~FKnEsb3Ghg>1wBtsB=BgtcI!JoLxLoqxyMujakISD|!XHpx;sgv03o}#U=rixP?gizvf z@peOn%U?>zba~jmuAW#JcDNK(5xJ!7NeD>~Ehq_|_WA^#4zN5&djpc&>+#D8mJI}% zNz+tURjE{i5*-~;Hqs@qFkJ`7b^0T*DBBtE@-eugJNcNuoF1{(rR~v7OVVUe8o3Hb z4%|LY@c0B;@wx-FmrVrdgxepWVKe7<3w*%MddjI0dtK@nFx2%x=`!?8VZ&r4!vyx? z4LQrJx3a@ZR13>rRO`ni`6b!!O z#ct)_&Q+bgn!Stzx#arA(yf}7Zj2%w_Mq&eWF=TPv9;WhR;Ng=!Vm6xQIhRLDr`!S zz6}Lws}8y7unQFh4WLhLA=KF?uQ8GWS{R<%ewy{stiPZ0i7YSj-X&~6WZCji3#!SJ zn0nG0kqi(Sf*USeyiN3$PYp*jYTp+8jvL~VtZMdAa$`B~MC0TIA2`-I(T~AN#f@)3GkyZ17m}G%k+N|jDmuXj$ z6qPkO;<}?r|9EXcZDr_4r$kesf>IdutEInM%`{C)svJ7W`m#k=a zt#!@Ct!Q_xwd!1@saDuss#epCxa?b35yndRxCX*Lp7-!Urnb4((W~Y_dLX94JDO=9 zB)qresqJWJTvIi2Jmg=fR&XLcC1-K3AWv3>tyFA<&u#FLk*Pd0PTXaccO7fJ&g6I@tCsDR)?X<%c53yTO95L_q?Y)o)r5upNt3#EaL z2`(%mR6uZ{G_Wzjg++u42riTcHYT{Rh)@B+h0?&r1Q!+&Dj>K}8rYcN!XiQi1Q$vJ z8xveuM5ut^LTO-Qf(wfX6%bq~4QxzsVG*GMf(xaAjR`I+B2++dp){~D!G%SH3J5Ng z1~$GZuD0r1m_UQCUXH+bEVn%QMIOGN>5#ko;uMu%L{S?yQPf`-;O~zVHOx}fPlFUC zZl|cL^e68<+C@=KhkIg?{@n4?$KP``N7_I7oypHR9vDCQ%MU+29Nd(f!F<^KNPkE4 z+1}l+INy9ZbBC>mn=w7K^Qo~je;oh$tTt=jzUM!G?Ax}t=bms!-le|3Rywm~aAcA1@z&pZZ%WUb z{q$wO@ZLQ;T2C*zZckHt^RrhUSrPrn^%95zyFdG@~d@rhL@Lrc6iwM+x7aA2dGc?9~$_0 ze)IV7(2SY4ZN9JN+^)OspV^w9cK5VZTbf0%G2FCQ_CEe)>$z7Cy||@+amps+iQKaL z#_R%l+pW*4__Ky!d+H%dJyH7o_^R;8+@z1aP{>ZZ5R?gqE`}%Wh z(#PIh_mar3-YUN=K^Zmxm6D?89P7QelNGDb46@# I$Kb|)0K;L|qW}N^ literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_3@2x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_3@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..728c73915ed00ca6a4b19852fc80b5488a62e494 GIT binary patch literal 1237 zcmbVMTWB0r7@m?EYjvwAf{L`qX^|?Ooy*Q-F3H$zW_FWRHwl}?ZbWHk&z#AQ$y}T{ zaVLvU5or~{Ds8>J1QHSY;6q7mpeVzX4%vl<^ zwodPp%3L`#P{SQ)MQEfoScR=|sM_@2hd@uF5d$8=7D&7aKh_eRUa_l@dAiNgU<;Mj`h6sUMuJrSI|FUY>1AlQz2q2C=MngNb=$A zY?Fz0*LRcxNi^C}J>=t(sng^nYrD3_J1|#QogAaub%_zXREbeIiDyK` z62zPg>l~-F?QFzX&Ack8l1Z?AJYSIWroj~yQ8I~;1<91#+>#$-%ZI4#+a@Hi-_0!D<(nPJ^+eDH346=(+;DHsTHFtw3 zEZKsx$lDBrP-a9&5g0{ORYtUB$k_tN)g_|9D&PLU3bG_9HZ7Nbl}~$%)MPqcZw9hh zZztrF9*Rh_uvf3VLmKVZl9{h2%ik~a+opSOD_W1~&)s?ID{$|*&sv=?_oC#E(= z{V;sum(5$8g^|nmUple>^*8=9`VR5V+{sT4JaQQ1r#Ihp`>uiio*cUQ@snQn#}{@i z^;}q*lkwcqTW);nS)=2-pZ_@Wd-u#o?;k%ty6wU97vH+tKRdho#jg*(bY*er$lITu z=s)|~+^duG+qK2sOs2Znd**XEbYA%KLuKFTH_`rA(8%(A=-3UFg&*g)f7_V3BZXXA zfY(l4M#Y1p$FvVB&L}v#=VI%dV#kw>89g)q=Wm;aHg!^8{J@+$y+gk>{n3;PgXX(^ H2d4i91#zBN literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_3@3x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_3@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..e59ae55735272088513a15cc852578fcdf9f916e GIT binary patch literal 15423 zcmeI3eQX=$9mlU-Ur18mk7y%nCe3pOYr358&c3sKH`~Rv-6SJU^9D^jjrM%^*ty2` zxp$Yw>AI;cV+hJ$NQmfWB{5d8JR&;3`efZyu1$3KKW zO}U=UCPlTh+MgxV0}r)Pl=!qZGHQ*+`y@rrxMWpN09QVfgKCNjtjp(QWgJ+J1W0Mw zp!3`xjyfHh8gyK{>djVq$+To-B%y4&BDw(_g3C)QoX79*i7rkM{cgU?;bu86!-@>Y(<~>k zqQr8J(w{Tb45NUdCZ(b1hEh5BU(h*bSviSeCMPFdlOC6Dq!>;VMTT`VZZ{1Tv^kZv zd^%JK^X`SG$Nrv7I1mHB1HP?DB~k)mN2@ zCpTfF3!qhn0cntdbxg>BYX~4Wrdzr>rY}&k(p`YqsIa9a7XWDYENBCHZ2_CzQ?wP< zRB@^U5K25QZ8S8v{N;31S0?Q1>WzkAhfCE|iAyS;gqZZuqM8tB-YW{UpA|To_seeH z<5LnW>klvsrm3!~QmFQb&QI?F8xuL(dd8 zOingTU@zXFv%GpMJFG;tu>2*heoV4YR(w3C(u$(^Xg=w8({PL;&8t3zRoyI`5FpJu zdv#2(K%m&I{=aioXRl^2<3KLCezEjurllKGNQXTr`zRR(JLb2RJJQ-B$yNBlT`$Rs zeMp5&8Pd0*AZ^tl7aew?qM!lv#Vv$7`@%IQ$3Qj&Pi-H~dTG`-!g(cDka*AcS--@x z<)Ic-3nwx4q%|oUAe@35E>yft43tj|MyHL#-vi*prvm=FeTRb^er=*GK&luy?lbB6?ak;IKf*6JQ!OBQE={V4ve~G0BB(!v&bSwp#tDeSoDW3VI(reOQ*^ z?C+8l?XIcO7fJ&g6I@tCsDR)?X<%c53yTO9 z5L_q?Y)o)r5upNt3#EaL2`(%mR6uZ{G_Wzjg++u42riTcHYT{Rh)@B+h0?&r1Q!+& zDj>K}8rYcN!XiQi1Q$vJ8xveuM5ut^LTO-Qf(wfX6%bq~4QxzsVG*GMf(xaAjR`I+ zB2++dp)|1ZWpOoE-@*i0`0C{(e8;kFy4`-c)1mYX#VKmn^%S+|Hj4W1CHVVyike_4 z>f>z`B^{us>-2lJ9@{`sOPhP6;gS5wGbdl`ZyjvA@zV~gd(X?ywSU(2-ud;R+dk!X zw{QAg_f>6<$G^K}dd-0F%ZrC6KKSvo$rn!S?t3+!TzB-&fFA||g-#m8c#_l^< z`Hw$uYQ3TFz?BQABX5lH%PusX%lO+?-5OlIV)}buzW&Yw{l~U84c<5Vv*Ed}&NI*K zfAFPcpTB+c+_Rls9cNR^(!zJn%ydq#+)dqb&x@fAv$uY2|M6|9+1T*hBdM4@#DDA_ zTiSl-`-*QibxKYwHQOYtPdlwQ4VT@uw^Moii8G%Y#d<*{i+PBHa|$m%KFiVE3>0eKmOSw;lH` zr)>(~_*d)Qcw4$ZV&cs_7=ZTH%iEjHq= z(;tnz^3CSweki2YoW4(ZQjCN*Zs$jTvG0YIA0C!7cej7_<$?D*=cfBEeLTG5@!S9X z_4B`f0+w7cGp=tra{l4Sr6&2^+25@G^TkV_|A5+hi?Q*spFDcM{fcjItUr2i{kDDo E1Gzl_761SM literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_4@2x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_4@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..52a7e0d95830e3a0ca5443172287a5973bbe3e6d GIT binary patch literal 1255 zcmbVMU1%It6dsK&HLxODF?&fdA39h3R# z%#AzAOEr~9u@8kns|b=95%D3ECPqjeiVucrd}--R6tuoYY!v*VNU`-!l8u6)4-U-S zzwbNe-0z$-=Zk%Z6RpWsf*=z4UcH3J4*b@3Y{%cJi|Ge=*oBM=I_A|-!weviv%D%K z^N!gMOVG52&wL3x38E#k%N0~998rPiq|6wTiX0!a38M2*|}s(2o6GZeW7 zK?7N8J*Y~dNNQdHNimh70hg9ZNl9^{BJ;ull4rRL!zv6X&@892ipp~2#zSFmfmKsW zde4S0yvkB_gnX4@8jVJ(kxqF*Kf@`C!mvEU^E5`#;joL$h<3yFrUe~_Ah3O8doCGU zG^^ea%2GJe^(#1jp|EM#4L5|sk};9#GhB*g94Efl8ahNJ_)i#HqQmmA51A4Sy`cc$ zeAL>TWUSr89mPN#je0b&aZ=1d-2+1obWvWsa3uy^dSypb^*@~~|IfYk51!KE8&X97t#u~C9>R3oa)TJgj?}o^90c`rVvF{D8 z{7|l{1<*uZQ1-mRW)&3c9`eGv=aZTiXI&y+D44)@Ur)5D=Xu*;IYw;{w6|n;AeCz)z$l#!uxLp2KKFuv$lks%3 z8SrAWouG?*D8S9K_mxkV3F47$c|BK-zPYo^Ju%9*jhUak|M~fE&phe=P_1Oo9rlCn zEHAB9{feVIp;im^PPQH_V!*RbEA(v{#3_*Co7k8Z_iJI z`|QGp_I$@`(Rh*H{V{rLWO4GdrTJY&=hRN)*0$d|?|!tWVV%5WynJW;*W0T_30TWB z?}ep=IQzlD8(sSnvr})(eUFyU_P=}Txv`(hlgaebqd#8%c{cfKeWE=+&1m1Xy>xPM zp)GM@X7Kdb7uTdO9^0~O6%Jhy%RX4f-` f+2p;~FB2`q+0o4Xi9h#D#=oAt(Wg&$pC0`i$PTCe literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_4@3x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_4@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..12f50ef7fea50dcdc9becb84d54819a844a11ee6 GIT binary patch literal 15495 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 literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_6@2x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_6@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7e6c946a04a2760f36a0ddffdacb8a4de06d762c GIT binary patch literal 1291 zcmbVMTWs586n21?sZtr@X|06nI)E79TVgl1sae`MqZy>jvTO@cC(W_{G*0TvY?oYk zsVX&Nh)o@cm1=;>+G(Py_5fvqO$eca#A^|2yaSXrlkw)|U1b1VLJ3eNqyRkH9y#r5S#w$Af>vq0Nn^-MwbcEy*@OdQ>wD z(3ma{f+UdD%HhkP8$s?ZYpJxGjz2FbrcTHnhA8V6WFtuTjq0@v$g*saG(nNN?%it@?YK$sZy1}Rom9mFWD+>$ zu&uy+9Ul6raG!}ij2G}I$Ss3^y<5)?AZN}&cfW;m{FD4^k6 zgTB|f^j*0^#0Ii!+9}fK1%YVwJ zu?1_=n{G4%Tx_%xFklbauvzj=C%#1x-}ac)lPWJ?pAa7!rM5L4t2RGrTWS=)t*<;*dG*fKnX$Kj5Kq22J6qlL)vcqgVZ?XegBzdm@7k_a zZvK`%zjgG`%zR{W`NU=4nd^y#xtp2&q<`NX?)WG7NP9k?xbXeYTNdgoS2}+D^P4~i zadD|Q<*H+u+WA8Gz4pZE=J|5wrGc7YO+I?$wmZ2;c>ncGt%aRB=AAL-oJd3-KA61p z^sn`m&Lc!{SKI7T@4;E$jir&3h42TvGqo#LoBd(uz6m0z{`AFLUynRc2v4@xXRdZk z-#(l09~ii{C=&y@FY6>xJ2!H?5H7M)hksdi$mu^mT6}F`=)&UoyM*tJLipqM`tK|E c4>WB<=KktC6?ty@W$*VCi}p+BdJm2M17$$C&Hw-a literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_6@3x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_6@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..69859c28733a4de46ce6c67622c350c518c039c4 GIT binary patch literal 15619 zcmeI3c~BeI9mm%Pb}c5hI~a%5t*a=lOKdN@D`|DCg%vwz+gI4FS{$)=vY}= z8Hv_YS5Dfg(;-LGhInF%?RH$(2Q;(^KI+8I5I1eXq$vqCKIw$WZ91j{c3n?A>02G> zA%vI7h|J48LCjseqfV@|S5S=LDWF-Qkt+y!d_avLmW?4F&A2#G-N-fZ z-a^gIQ?F~(JX@&QLfUb=uY_yn%Ub>1=GICF)9PZ(tY)KCWeHIrfrk@mb;#rP2B=V> zCYF~1vDA!d)G>+ZD%2E71=V%-Ds_qA=hS3@0c8lCNo_P25Tx0p)vs4;al(M%W{l9I zI6>iN3MbTwKaEudB8#7OQq{IiiE`k-LQS(M`X~%*X=y2F(G>{(CX6tf%^0r5v|1D> z&_LKL(jn9vcqE=Ana9Qj7(ee5dBLle^3sh$P%PAFq(W1FiR<$C?DnZr-avvL;E082 zA4U}5n8$-J4TR zHQ^+I>P@s(uQM`@IBv3Fv!+R{szj*_B}lE!R%|v)>52)W)L3LI!Anhg(gs#^DQPn% z(?ix7Y0JFIoKQ7{-X|ohB`6(wohw zo;5N!tHtp~640DsPmKu_u*AFBPdisL?5XTY9MC1tTr6dLKotC8s6!f*bd+r7woh+O zcDVUDlAGcOc0ENi(jjFH(15-K1!_wTIqr}O#RZw5&uJmdu+LtjrJ3_u!KrOTaRZ7Q z9fX0x^%QAdhnpxIPYyMvnmtKCaEdLopDStt8_pWPO;jaM4RuM0bXzd0^X)Xld!?h~ z(PZA~#@P!n&9t|PW35=ym~2S5STJew-2C*pi?>dn(&YM>xdf!$O_lgL8Y~TmAh_pt zLFuN{$Wr+@8!d9vXpb& z!Dh6j>+7Tg%pHvBjo|dbag30@6IQr8-CBQtE8LxKO*w14ylB-Xs--nUF6q`4hp`zv zu5nfaN$N-omfoE1sNzGMyUxagJ6b?GNJwzp$2{pB8IAQRBS8ZGDJRsEaK`rv^kfy= zO7T|k+y)*Qv8iXq>AP&|`1*{4)Fpk!iQ#lg5txQ-tl*MG1Pc^gFb&yQ!6l0b7AUx2 z8nUs1OBN9mtMFa~JTrdsUSivQW2o@-~U>dTqf=d<=EKqR4G-P81 zmnh zhHR|hl0^gy6kIS3*;v6PiwG7dxL_Kxv4Tq$5iC$}!8By!`{Gii-ooU(;ML0(@Q&pz z{qh~){Y*7eR&7U+)~_PSuH6XozfZvL4Fn0|2=dQu2tu_Z$b-W3-|5?gAoB;xZAFgI z#g8sM{`9+F&pZF0E|+kiq42+>mk(~a`fOLx_Z~WvS7e*)R3G0HDd>&Vx`M9v58OM& zTiCYe*}Xs6*)hH<8XQ^nQpMPxE5G~jg}_PE(r9#f1%7s6&V9dnHnhHZeSBeb!@ZBc zw)^b0v5oW_!SfG}ZT-9B;}2Hc$_X_r8lir;^Ty~Xk##1RYgoHG+_$gh?9zSbYPs&! z<9WTK%WuD;+OeuPy4M=l3mod_+yl+|`* z+iNfPzw+4in(#B>b0h0F za@n`r{&3#1LOj+xSvNQ_eBlONb7{Wr+G$sJc=(+zhJJ7RKdSmC>W23(82%UjrGu*n z-^;!`Z+z|TJ>mT5yS||VuQ}E>$H?XW?$8srs|Vj1`si1kU2oO)ycp?t%h3K}?~ zBlV9)iM}nn8tVVDK6moqc)ine_UMX9y<_4e+MY!4@56hK<%+H$_p#1~BTiS=<*j7H zy6F18FaN%Kt#{-%PFHu$p8B4fk%8gs(Gx$4bacPD#Ir2x-ilCrBX^~x=oe2N?yZ;y zkM5~RWp)2b6;)0)j?NcY6wdUxhdzVOGZOUJ7Qd!GGf&kMp| r58kN_eX{Xf#{#U`SA1&V&IV*ne_ze`b0b~SYs%%NmA2!>+amu5aqD^; literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_7@2x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_7@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1d81b76625050e2da65124c06335512b6430054b GIT binary patch literal 1310 zcmbVMU2M}<6n54Q@zWv=_Q0ZQGA?36!tqby#I_QeHcn`Ov>^>!gfwlAebZQJ?991c zl1@zRCedyhQ{f>|s1O=dg=(zYLwSHr>MFzout{a`u;yh*XnhSD8Icx5n!#5e z0(mpllo*pjtG>|6N2DRli4;{R6dVPo!!Ua(Mi2ywW+|2>5rWK@bSM`|J>OclAc4GM zYB{JGI&N8%lSV)E5h&7?D`az#$eLk2zbX`xj4H}GigD0XHf!B$8J&kQ@NXFFqVw@m z4p1?WH~LKl+H zBuBd30!Q*R$B-^wW?fE?lB8+AZf89{$4XL%zy}ewgJFW6b}2vyc^4-kA%mRcsdK}6 z9?H4`>b^DPdzC9amn#NLAVb598%AHf3ZiKP8u_%5!vg^;>mK~|h^%P3wYkSi)XKdj zU~2CHHDnrDd|7ExTPF(HBP$*kqmqiEct}@@XGz{A2&7B(D74Dbbdo~~tnk(Ut00Af zqO5ZHPx;ihP)%CXwPrwzwRQqJ>LC*~OXKn33WnLdVW~Y{tUazow$A!@96!c~jC%=R zXZO$u%*?*nGJEqA$Nb%nOHkf8l# za%+6+mG4eoy9ui&L*+Z{^ab0On!m>$eFm0(W+%@dSSY^s>Nneef5i4&JbS6NIeoC< zK-zz%`{?e<}65 zW{>`{SX+E+qI?5<*7D#7Fwt~m(<6UFZEkR2=7W2Czr~vNAKrcc>exf;j};DfNmCu~ GeE1L00?6V3 literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_7@3x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_volume_7@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..63dff1d5e28c120af790e78ef5ae6adb5924fe5f GIT binary patch literal 15710 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 literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_warning@2x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_warning@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3162af250bb49793d81f5f6d5aa99227d718b306 GIT binary patch literal 1013 zcmaJ=PfXKL9Ij}PAP_E!8bV%5V!*JruiMyKsaV=gnou&w5*NK#+6QY!`%3$8g^Pa< zB*v5B%E24agC@qCCUWuMO>e}DCMKSY96TF+o!ju>Z1Vbh@8$P>zklC*P+Gh?*nhsC zVVFT*!OaCLU*@x7eBZVqi!Yia^dS~8Lhg$!XCbQ!vfb)*y~wSFar(M-1)5#Ep07U z?5(;jIqd9ZFcZs^z(d3WvA5<&a;&gTUYYKbYn}y77gAT)KS@>163}pnK$e?M*)W|4 zIf;W=DKBQGfGEIeUXXa0NeNIEBw2u<^|3Ts=&Z5}g z9!iqL3nDLyDe94mHhp5nDL)!-Gw3L?LpLBU_CdmEE#nQMur$*@C3r!H){k0kq7CC? zE8rm~Bqg;SP4oY*p4ah?NEsdF`%mJivKb)0j3T@d+H`O$<4LGM)Z1A52?7vj5B%qFl<9tEAhu~2XN@FFrZyK zxjyB83ir0(z8}vlJjRn>mbM2TjoQu*sil;$+UXZh&Vu2-6Fv8?w9Mz52dBR87D}#t v@O5;b-&cNI#JfMAj_iGS-gD>ICI472b6CIda(G9%kvv4Bu&6(qyLJCJBzQXM literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_warning@3x.png b/ChatKit/Class/Resources/LCCKRecordAudioHUD.bundle/chat_record_warning@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..513cd25473d814df1036a9b17384341262b182f6 GIT binary patch literal 1075 zcmaJ=O=#0l91n`J6$d-$VFNK{mrZT+(a(f-vunDoYHIBYmVvk|d22(LyexTJ(}{wL zhk*I5D6Qc=SZ6%eLGGqc;fDHOV zUWN5X$T06?gM5Sw93eS|4bcowvjH!|3JfnWELs039L-WEg{(MKkA+V$s)&#&&~&+6 z_LcoUXccId=XsjpXpZw@53gM@knDI3yQje*0$Z^(6KT*OT}F8V&Y&2DGu9}kNStO%7E9T=#ARkyLhmRMI1x``u;z|v-cI%GketQ9V3 zt#jd8^3}0w>sW~D(u!o)8t>m2pm}~Rb`|8^7HimfJ9X{TU-aT@kaVnV>9}JFP`UBPmUNZmy literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.h b/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.h old mode 100755 new mode 100644 index 172a38a0..b9ddea1a --- a/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.h +++ b/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.h @@ -9,9 +9,24 @@ #import @protocol Mp3RecorderDelegate -- (void)failRecord; -- (void)beginConvert; +/** + 失败 时间太短 + */ +- (void)tooShortFailRecord; + +/** + 成功 转换格式成功 + @param fileName 文件路径 + */ - (void)endConvertWithMP3FileName:(NSString *)fileName; +/** + 音量 变化 + + @param volume 音量 + */ +- (void)averagePowerWithVolume:(CGFloat)volume; +@optional +- (void)beginConvert; @end @interface Mp3Recorder : NSObject diff --git a/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.m b/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.m index fd0ba562..1f57a6d7 100755 --- a/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.m +++ b/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.m @@ -18,6 +18,7 @@ @interface Mp3Recorder() @property (nonatomic, strong) AVAudioSession *session; @property (nonatomic, strong) AVAudioRecorder *recorder; +@property (nonatomic, strong) NSTimer *timer; @end @implementation Mp3Recorder @@ -53,6 +54,14 @@ - (void)setRecorder //NSLog(@"%@",recorderSetupError); } _recorder.meteringEnabled = YES; + if(_timer) { + [_timer invalidate]; + _timer = nil; + } + _timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(levelTimerCallback:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes]; + + _recorder.delegate = self; [_recorder prepareToRecord]; } @@ -72,6 +81,8 @@ - (void)setSesstion - (void)startRecord { + if(_recorder && [_recorder isRecording]) return; + [self setSesstion]; [self setRecorder]; [_recorder record]; @@ -80,6 +91,8 @@ - (void)startRecord - (void)stopRecord { + if(!_recorder || ![_recorder isRecording] || !_timer) return; + double cTime = _recorder.currentTime; [_recorder stop]; @@ -88,17 +101,27 @@ - (void)stopRecord } else { [_recorder deleteRecording]; - - if ([_delegate respondsToSelector:@selector(failRecord)]) { - [_delegate failRecord]; + if(self.delegate && [self.delegate respondsToSelector:@selector(tooShortFailRecord)]) { + [self.delegate tooShortFailRecord]; } } + if(_timer) { + [_timer invalidate]; + _timer = nil; + } } - (void)cancelRecord { + if(!_recorder || ![_recorder isRecording] || !_timer) return; + [_recorder stop]; [_recorder deleteRecording]; + if(_timer) { + [_timer invalidate]; + _timer = nil; + } + } - (void)deleteMp3Cache @@ -127,9 +150,11 @@ - (void)audio_PCMtoMP3 NSString *mp3FilePath = [[self mp3Path] stringByAppendingPathComponent:[self randomMP3FileName]]; ////NSLog(@"MP3转换开始"); - if (_delegate && [_delegate respondsToSelector:@selector(beginConvert)]) { - [_delegate beginConvert]; + + if(self.delegate && [self.delegate respondsToSelector:@selector(beginConvert)]) { + [self.delegate beginConvert]; } + @try { int read, write; @@ -169,8 +194,8 @@ - (void)audio_PCMtoMP3 @finally { [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil]; //NSLog(@"MP3转换结束"); - if (_delegate && [_delegate respondsToSelector:@selector(endConvertWithMP3FileName:)]) { - [_delegate endConvertWithMP3FileName:mp3FilePath]; + if (self.delegate && [self.delegate respondsToSelector:@selector(endConvertWithMP3FileName:)]) { + [self.delegate endConvertWithMP3FileName:mp3FilePath]; } [self deleteCafCache]; } @@ -179,6 +204,45 @@ - (void)audio_PCMtoMP3 } #pragma mark - Path Utils + +/* 该方法确实会随环境音量变化而变化,但具体分贝值是否准确暂时没有研究 */ +- (void)levelTimerCallback:(NSTimer *)timer { + [self.recorder updateMeters]; + + float level; // The linear 0.0 .. 1.0 value we need. + float minDecibels = -80.0f; // Or use -60dB, which I measured in a silent room. + float decibels = [self.recorder averagePowerForChannel:0]; + + if (decibels < minDecibels) + { + level = 0.0f; + } + else if (decibels >= 0.0f) + { + level = 1.0f; + } + else + { + float root = 2.0f; + float minAmp = powf(10.0f, 0.05f * minDecibels); + float inverseAmpRange = 1.0f / (1.0f - minAmp); + float amp = powf(10.0f, 0.05f * decibels); + float adjAmp = (amp - minAmp) * inverseAmpRange; + + level = powf(adjAmp, 1.0f / root); + } + + /* + level 范围[0 ~ 1], 转为[0 ~120] 之间 + */ + + dispatch_async(dispatch_get_main_queue(), ^{ + if(self.delegate && [self.delegate respondsToSelector:@selector(averagePowerWithVolume:)]) { + [self.delegate averagePowerWithVolume:level*120]; + } + }); +} + - (NSString *)cafPath { NSString *cafPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"tmp.caf"]; return cafPath; @@ -198,4 +262,12 @@ - (NSString *)randomMP3FileName { return fileName; } +- (void)dealloc +{ + if(_timer) { + [_timer invalidate]; + _timer = nil; + } +} + @end