QMChatRoomVoiceCell.m 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. //
  2. // QMChatRoomVoiceCell.m
  3. // IMSDK-OC
  4. //
  5. // Created by HCF on 16/3/10.
  6. // Copyright © 2016年 HCF. All rights reserved.
  7. //
  8. #import "QMChatRoomVoiceCell.h"
  9. #import <AVFoundation/AVFoundation.h>
  10. #import <QMLineSDK/QMLineSDK.h>
  11. #import "QMAudioPlayer.h"
  12. #import "QMAudioAnimation.h"
  13. @interface QMChatRoomVoiceCell() <AVAudioPlayerDelegate>
  14. @end
  15. /**
  16. 语音消息
  17. */
  18. @implementation QMChatRoomVoiceCell
  19. {
  20. UIImageView *_voicePlayImageView;
  21. UILabel *_secondsLabel;
  22. AVAudioSession *_audioSession;
  23. NSString *_messageId;
  24. UIImageView *_badgeView;
  25. }
  26. - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
  27. self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  28. if (self) {
  29. [self createUI];
  30. }
  31. return self;
  32. }
  33. - (void)createUI {
  34. _voicePlayImageView = [[UIImageView alloc] init];
  35. _voicePlayImageView.animationDuration = 1.0;
  36. [self.chatBackgroudImage addSubview:_voicePlayImageView];
  37. _secondsLabel = [[UILabel alloc] init];
  38. _secondsLabel.backgroundColor = [UIColor clearColor];
  39. _secondsLabel.font = [UIFont systemFontOfSize:16];
  40. [self.chatBackgroudImage addSubview:_secondsLabel];
  41. _badgeView = [[UIImageView alloc] init];
  42. _badgeView.backgroundColor = [UIColor redColor];
  43. _badgeView.layer.cornerRadius = 4;
  44. _badgeView.layer.masksToBounds = YES;
  45. [_badgeView setHidden:YES];
  46. [self.contentView addSubview:_badgeView];
  47. _audioSession = [AVAudioSession sharedInstance];
  48. UILongPressGestureRecognizer * longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressTapGesture:)];
  49. [_voicePlayImageView addGestureRecognizer:longPressGesture];
  50. // 默认为听筒
  51. [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
  52. }
  53. - (void)setData:(CustomMessage *)message avater:(NSString *)avater {
  54. _messageId = message._id;
  55. self.message = message;
  56. [super setData:message avater:avater];
  57. UITapGestureRecognizer * tapPressGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapPressGesture:)];
  58. [self.chatBackgroudImage addGestureRecognizer:tapPressGesture];
  59. if ([message.fromType isEqualToString:@"0"]) {
  60. self.chatBackgroudImage.frame = CGRectMake(CGRectGetMinX(self.iconImage.frame)-10-125, CGRectGetMaxY(self.timeLabel.frame)+10, 125, 40);
  61. self.sendStatus.frame = CGRectMake(CGRectGetMinX(self.chatBackgroudImage.frame)-25, CGRectGetMaxY(self.chatBackgroudImage.frame)-32, 20, 20);
  62. _voicePlayImageView.frame = CGRectMake(125-35, 11, 13, 17);
  63. _voicePlayImageView.image = [UIImage imageNamed:@"SenderVoiceNodePlaying"];
  64. if ([message.status isEqualToString:@"0"]) {
  65. _secondsLabel.textColor = [UIColor whiteColor];
  66. _secondsLabel.frame = CGRectMake(CGRectGetMinX(_voicePlayImageView.frame)-50, 11, 40, 20);
  67. _secondsLabel.text = [NSString stringWithFormat:@"%@''",message.recordSeconds];
  68. _secondsLabel.textAlignment = NSTextAlignmentRight;
  69. _secondsLabel.hidden = NO;
  70. }else {
  71. _secondsLabel.hidden = YES;
  72. }
  73. self.sendStatus.frame = CGRectMake(CGRectGetMinX(self.chatBackgroudImage.frame)-25, CGRectGetMinY(self.chatBackgroudImage.frame)+10, 20, 20);
  74. [[QMAudioAnimation sharedInstance]setAudioAnimationPlay:YES and:_voicePlayImageView];
  75. [_badgeView setHidden:YES];
  76. }else {
  77. self.chatBackgroudImage.frame = CGRectMake(CGRectGetMaxX(self.iconImage.frame)+5, CGRectGetMaxY(self.timeLabel.frame)+10, 125, 40);
  78. _badgeView.frame = CGRectMake(CGRectGetMaxX(self.chatBackgroudImage.frame)+5, CGRectGetMaxY(self.timeLabel.frame)+15, 8, 8);
  79. _voicePlayImageView.frame = CGRectMake(22, 11, 13, 17);
  80. _voicePlayImageView.image = [UIImage imageNamed:@"ReceiverVoiceNodePlaying"];
  81. _secondsLabel.textColor = [UIColor blackColor];
  82. _secondsLabel.frame = CGRectMake(CGRectGetMaxX(_voicePlayImageView.frame)+10, 11, 40, 20);
  83. _secondsLabel.text = [NSString stringWithFormat:@"%@''",message.recordSeconds ? message.recordSeconds : 0];
  84. _secondsLabel.textAlignment = NSTextAlignmentLeft;
  85. [[QMAudioAnimation sharedInstance]setAudioAnimationPlay:NO and:_voicePlayImageView];
  86. CustomMessage *msg = [QMConnect getOneDataFromDatabase:message._id].firstObject;
  87. if ([msg.isRead isEqualToString:@"1"]) {
  88. [_badgeView setHidden:YES];
  89. }else {
  90. [_badgeView setHidden:NO];
  91. }
  92. }
  93. NSString *fileName;
  94. if ([self existFile:self.message.message]) {
  95. fileName = self.message.message;
  96. }else {
  97. fileName = self.message._id;
  98. }
  99. if ([[QMAudioPlayer sharedInstance] isPlaying:fileName] == true) {
  100. [[QMAudioAnimation sharedInstance]startAudioAnimation:_voicePlayImageView];
  101. }
  102. }
  103. - (void)longPressTapGesture:(UILongPressGestureRecognizer *)sender {
  104. if (sender.state == UIGestureRecognizerStateBegan) {
  105. [self becomeFirstResponder];
  106. UIMenuController *menu = [UIMenuController sharedMenuController];
  107. UIMenuItem *reciverMenu = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"button.receiver", nil) action:@selector(reciverMenu:)];
  108. UIMenuItem *speakerMenu = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"button.speaker", nil) action:@selector(speakerMenu:)];
  109. UIMenuItem *removeMenu = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"button.delete", nil) action:@selector(removeMenu:)];
  110. [menu setMenuItems:[NSArray arrayWithObjects:reciverMenu,speakerMenu,removeMenu, nil]];
  111. [menu setTargetRect:self.chatBackgroudImage.frame inView:self];
  112. [menu setMenuVisible:true animated:true];
  113. UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
  114. if ([window isKeyWindow] == NO) {
  115. [window becomeKeyWindow];
  116. [window makeKeyAndVisible];
  117. }
  118. }
  119. }
  120. - (BOOL)canBecomeFirstResponder {
  121. return YES;
  122. }
  123. - (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
  124. if (action == @selector(reciverMenu:) || action == @selector(speakerMenu:) || action == @selector(removeMenu:)) {
  125. return YES;
  126. }else {
  127. return NO;
  128. }
  129. }
  130. - (void)reciverMenu:(id)sendr {
  131. //听筒
  132. NSError *error = nil;
  133. if ([[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&error]) {
  134. }
  135. }
  136. - (void)speakerMenu:(id)sender {
  137. // 扬声器
  138. NSError *error = nil;
  139. [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
  140. }
  141. - (void)removeMenu:(id)sender {
  142. // 删除语音(只能删除本地数据库消息)
  143. // 删除文本消息
  144. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"title.prompt", nil) message:NSLocalizedString(@"title.statement", nil) preferredStyle:UIAlertControllerStyleAlert];
  145. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"button.cancel", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  146. }];
  147. UIAlertAction *sureAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"button.sure", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  148. [QMConnect removeDataFromDataBase:_messageId];
  149. [[NSNotificationCenter defaultCenter] postNotificationName:CHATMSG_RELOAD object:nil];
  150. }];
  151. [alertController addAction:cancelAction];
  152. [alertController addAction:sureAction];
  153. [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
  154. }
  155. - (void)tapPressGesture:(id)sender {
  156. NSLog(@"点击语音消息");
  157. [_badgeView setHidden:YES];
  158. [QMConnect changeAudioMessageStatus:_messageId];
  159. [[QMAudioAnimation sharedInstance] stopAudioAnimation:nil];
  160. [[QMAudioAnimation sharedInstance] startAudioAnimation:_voicePlayImageView];
  161. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((self.message.recordSeconds).intValue * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  162. [[QMAudioAnimation sharedInstance] stopAudioAnimation:_voicePlayImageView];
  163. });
  164. NSString *fileName;
  165. if ([self existFile:self.message.message]) {
  166. fileName = self.message.message;
  167. }else if ([self existFile:[NSString stringWithFormat:@"%@", self.message._id]]) {
  168. fileName = self.message._id;
  169. }else {
  170. NSString *playUrl = [NSString stringWithFormat:@"%@/%@/%@", NSHomeDirectory(), @"Documents", [NSString stringWithFormat:@"%@", self.message._id]];
  171. fileName = self.message._id;
  172. NSURL *fileUrl = [NSURL URLWithString:self.message.remoteFilePath];
  173. NSData *data = [NSData dataWithContentsOfURL:fileUrl];
  174. [data writeToFile:playUrl atomically:YES];
  175. }
  176. // 目前只能发送语音消息 不能接收
  177. [[QMAudioPlayer sharedInstance] startAudioPlayer:fileName withDelegate:self];
  178. }
  179. - (BOOL)existFile: (NSString *)name {
  180. NSString * filePath = [NSString stringWithFormat:@"%@/%@/%@", NSHomeDirectory(), @"Documents", name];
  181. NSFileManager *fileManager = [NSFileManager defaultManager];
  182. if ([fileManager fileExistsAtPath:filePath]) {
  183. return YES;
  184. }else {
  185. return NO;
  186. }
  187. }
  188. - (void)awakeFromNib {
  189. // Initialization code
  190. [super awakeFromNib];
  191. }
  192. - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
  193. [super setSelected:selected animated:animated];
  194. // Configure the view for the selected state
  195. }
  196. @end