桂欢 1 год назад
Родитель
Сommit
24d8aa6f2d

+ 14 - 4
SLAiELTS/SLAiELTS.xcodeproj/project.pbxproj

@@ -130,7 +130,6 @@
 		3D3BC1C72A25903700AEEE8E /* SLMomentsNewsVc.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3D3BC1C52A25903700AEEE8E /* SLMomentsNewsVc.xib */; };
 		3D3BC1CC2A25933400AEEE8E /* SLMomentsNewsCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D3BC1CA2A25933400AEEE8E /* SLMomentsNewsCell.m */; };
 		3D3BC1CD2A25933400AEEE8E /* SLMomentsNewsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3D3BC1CB2A25933400AEEE8E /* SLMomentsNewsCell.xib */; };
-		3D3BC34B2A25E73800AEEE8E /* icon_yb_bg.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 3D3BC34A2A25E73800AEEE8E /* icon_yb_bg.jpg */; };
 		3D3BC34F2A26D7D300AEEE8E /* SLAiSetVc.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D3BC34D2A26D7D300AEEE8E /* SLAiSetVc.m */; };
 		3D3BC3502A26D7D300AEEE8E /* SLAiSetVc.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3D3BC34E2A26D7D300AEEE8E /* SLAiSetVc.xib */; };
 		3D3BC3542A26E2B000AEEE8E /* SLMySpeedCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D3BC3522A26E2B000AEEE8E /* SLMySpeedCell.m */; };
@@ -143,6 +142,9 @@
 		3D58828B2A2976CD00F1B38E /* SLMsgBgSetVc.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D5882892A2976CD00F1B38E /* SLMsgBgSetVc.m */; };
 		3D58828C2A2976CD00F1B38E /* SLMsgBgSetVc.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3D58828A2A2976CD00F1B38E /* SLMsgBgSetVc.xib */; };
 		3D58829F2A29C17D00F1B38E /* SLMomentsNewsModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D58829E2A29C17D00F1B38E /* SLMomentsNewsModel.m */; };
+		3D5882A22A29DD2F00F1B38E /* icon_msg_yy_aw.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D5882A02A29DD2F00F1B38E /* icon_msg_yy_aw.png */; };
+		3D5882A32A29DD2F00F1B38E /* icon_msg_yy_ab.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D5882A12A29DD2F00F1B38E /* icon_msg_yy_ab.png */; };
+		3D5882A62A29E4B900F1B38E /* SLDecodeGifImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D5882A52A29E4B900F1B38E /* SLDecodeGifImage.m */; };
 		3D5BC38B29E3E77400748197 /* SLMoentsChatView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D5BC38A29E3E77400748197 /* SLMoentsChatView.m */; };
 		3D5BC38F29E3F87100748197 /* SLFriensInfoVc.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D5BC38D29E3F87100748197 /* SLFriensInfoVc.m */; };
 		3D5BC39029E3F87100748197 /* SLFriensInfoVc.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3D5BC38E29E3F87100748197 /* SLFriensInfoVc.xib */; };
@@ -510,7 +512,6 @@
 		3D3BC1C92A25933400AEEE8E /* SLMomentsNewsCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SLMomentsNewsCell.h; sourceTree = "<group>"; };
 		3D3BC1CA2A25933400AEEE8E /* SLMomentsNewsCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SLMomentsNewsCell.m; sourceTree = "<group>"; };
 		3D3BC1CB2A25933400AEEE8E /* SLMomentsNewsCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SLMomentsNewsCell.xib; sourceTree = "<group>"; };
-		3D3BC34A2A25E73800AEEE8E /* icon_yb_bg.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icon_yb_bg.jpg; sourceTree = "<group>"; };
 		3D3BC34C2A26D7D300AEEE8E /* SLAiSetVc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SLAiSetVc.h; sourceTree = "<group>"; };
 		3D3BC34D2A26D7D300AEEE8E /* SLAiSetVc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SLAiSetVc.m; sourceTree = "<group>"; };
 		3D3BC34E2A26D7D300AEEE8E /* SLAiSetVc.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SLAiSetVc.xib; sourceTree = "<group>"; };
@@ -529,6 +530,10 @@
 		3D58828A2A2976CD00F1B38E /* SLMsgBgSetVc.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SLMsgBgSetVc.xib; sourceTree = "<group>"; };
 		3D58829D2A29C17D00F1B38E /* SLMomentsNewsModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SLMomentsNewsModel.h; sourceTree = "<group>"; };
 		3D58829E2A29C17D00F1B38E /* SLMomentsNewsModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SLMomentsNewsModel.m; sourceTree = "<group>"; };
+		3D5882A02A29DD2F00F1B38E /* icon_msg_yy_aw.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_msg_yy_aw.png; sourceTree = "<group>"; };
+		3D5882A12A29DD2F00F1B38E /* icon_msg_yy_ab.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_msg_yy_ab.png; sourceTree = "<group>"; };
+		3D5882A42A29E4B900F1B38E /* SLDecodeGifImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SLDecodeGifImage.h; sourceTree = "<group>"; };
+		3D5882A52A29E4B900F1B38E /* SLDecodeGifImage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SLDecodeGifImage.m; sourceTree = "<group>"; };
 		3D5BC38929E3E77400748197 /* SLMoentsChatView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SLMoentsChatView.h; sourceTree = "<group>"; };
 		3D5BC38A29E3E77400748197 /* SLMoentsChatView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SLMoentsChatView.m; sourceTree = "<group>"; };
 		3D5BC38C29E3F87100748197 /* SLFriensInfoVc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SLFriensInfoVc.h; sourceTree = "<group>"; };
@@ -1316,6 +1321,8 @@
 				3D2DC3F029B191C80041A729 /* MessageModel.m */,
 				3DFEE70C29B5CB01000AA7D5 /* SLMikeSegmentModel.h */,
 				3DFEE70D29B5CB01000AA7D5 /* SLMikeSegmentModel.m */,
+				3D5882A42A29E4B900F1B38E /* SLDecodeGifImage.h */,
+				3D5882A52A29E4B900F1B38E /* SLDecodeGifImage.m */,
 			);
 			path = Models;
 			sourceTree = "<group>";
@@ -1323,8 +1330,9 @@
 		3D3BC1212A1DF58100AEEE8E /* 音波 */ = {
 			isa = PBXGroup;
 			children = (
+				3D5882A12A29DD2F00F1B38E /* icon_msg_yy_ab.png */,
+				3D5882A02A29DD2F00F1B38E /* icon_msg_yy_aw.png */,
 				3D3BC35C2A273E7400AEEE8E /* icon_yb_bg_01.jpg */,
-				3D3BC34A2A25E73800AEEE8E /* icon_yb_bg.jpg */,
 			);
 			path = "音波";
 			sourceTree = "<group>";
@@ -2002,7 +2010,6 @@
 				3D3BC1C22A2587E900AEEE8E /* SLNewMsgBgView.xib in Resources */,
 				3DF3DAB329B9B86200CAD3AB /* SLUserCenterViewController.xib in Resources */,
 				3DB97D6C29D6ABC100B12754 /* sdRefeshView_arrow@2x.png in Resources */,
-				3D3BC34B2A25E73800AEEE8E /* icon_yb_bg.jpg in Resources */,
 				3D25106129AC95A9000AE530 /* SLRetrievePWViewController.xib in Resources */,
 				3D8EBBC82A131FA40008B0C1 /* SLHomeMsgTableViewCell.xib in Resources */,
 				3DF3DAA829B9A6AA00CAD3AB /* SLBaseCellView.xib in Resources */,
@@ -2011,6 +2018,7 @@
 				3DF3DAD829BAD1BA00CAD3AB /* SLChangeMobileVc.xib in Resources */,
 				3D2D8BEE29DE55A9009392DA /* unicode_to_hanyu_pinyin.txt in Resources */,
 				3D58828C2A2976CD00F1B38E /* SLMsgBgSetVc.xib in Resources */,
+				3D5882A32A29DD2F00F1B38E /* icon_msg_yy_ab.png in Resources */,
 				3D1B987329BEB35B0008D01A /* SLHorScrBtnsCell.xib in Resources */,
 				3D25105729AC8FE1000AE530 /* SLRegistViewController.xib in Resources */,
 				3D8C9F8A29AC57F300678283 /* LaunchScreen.storyboard in Resources */,
@@ -2023,6 +2031,7 @@
 				3D3BC1CD2A25933400AEEE8E /* SLMomentsNewsCell.xib in Resources */,
 				3DF3DACA29B9D19600CAD3AB /* SLBaseTableViewCell.xib in Resources */,
 				3D8C9F8729AC57F300678283 /* Assets.xcassets in Resources */,
+				3D5882A22A29DD2F00F1B38E /* icon_msg_yy_aw.png in Resources */,
 				3D25108A29ADD490000AE530 /* SLRoleLabelView.xib in Resources */,
 				3DF3DAE029BAFA4B00CAD3AB /* SLMySpeedView.xib in Resources */,
 				3D5BC39029E3F87100748197 /* SLFriensInfoVc.xib in Resources */,
@@ -2209,6 +2218,7 @@
 				3D19CBF829E7ABFD0041A6B8 /* UITableView+CYLTableViewPlaceHolder.m in Sources */,
 				3DA5AF5C29B8843C009E4925 /* SLBaseTabBarController.m in Sources */,
 				3D2DC3E029B0991E0041A729 /* YMIMMessageCollectionView.m in Sources */,
+				3D5882A62A29E4B900F1B38E /* SLDecodeGifImage.m in Sources */,
 				3D1F17B22A0DE60100F030AD /* JZLocationConverter.m in Sources */,
 				3DB97D6D29D6ABC100B12754 /* UIView+SDExtension.m in Sources */,
 				3DF3DAFA29BB187D00CAD3AB /* SLHomeTopCollectionViewCell.m in Sources */,

+ 2 - 0
SLAiELTS/SLAiELTS/Tool/Extensions/UIImage+Extension.h

@@ -40,6 +40,8 @@ NS_ASSUME_NONNULL_BEGIN
 + (NSData *)resetSizeOfImageData:(UIImage *)sourceImage
                          maxSize:(NSInteger)maxSize;
 
++ (UIImage *)decodeGifImageByData:(NSData *)data;
+
 @end
 
 NS_ASSUME_NONNULL_END

+ 56 - 0
SLAiELTS/SLAiELTS/Tool/Extensions/UIImage+Extension.m

@@ -270,4 +270,60 @@
 }
 
 
+//解压gif的data为图片数组
++ (UIImage *)decodeGifImageByData:(NSData *)data {
+    //获取data资源器,这个可以直接操作图片data
+    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, nil);
+    //获取图片数量 size_t 类似于无符号int
+    size_t count = CGImageSourceGetCount(source);
+    UIImage * animationImage;
+    
+    //如果只有一张则直接解压
+    if (count <= 1) {
+        animationImage = [[UIImage alloc]initWithData:data];
+    }
+    else {
+        NSMutableArray * imageArray = [NSMutableArray arrayWithCapacity:count];
+        NSTimeInterval duration = 0.0f;
+        //遍历获取每一张图片
+        for (size_t i = 0; i < count; i++) {
+            //解析图片拿到图片画笔拿到图片画笔
+            CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL);
+            duration += [self imageDurationAtIndex:i source:source];
+            //scale:图片缩放因子 默认1  orientation:图片绘制方向 默认网上
+            [imageArray addObject:[UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
+            CGImageRelease(imageRef);
+        }
+        
+        //如果没有抓取到图片播放时间,则按照0.1秒一张的方式来了播放
+        if (!duration) {
+            duration = (1.0f / 10.0f) * count;
+        }
+        animationImage = [UIImage animatedImageWithImages:imageArray duration:duration];
+    }
+    
+    
+    CFRelease(source);
+    return animationImage;
+}
+
+//获取每一张图片的持续时间
++ (float)imageDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
+    float imageDuration = 0.1f;
+    //获取指定图像的属性信息 如宽、高、持续时间等都在里面 详情参考 CGImageProperties
+    CFDictionaryRef cfImageProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
+    if (!cfImageProperties) {
+        return imageDuration;
+    }
+    NSDictionary * imageProperties = (__bridge NSDictionary *) cfImageProperties;
+    //拿到gif图的属性信息 获取每一帧的时间
+    NSDictionary * gifProperties = [imageProperties valueForKey:(NSString *)kCGImagePropertyGIFDictionary];
+    NSNumber * delayTime = [gifProperties valueForKey:(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
+    if (delayTime != nil) {
+        return delayTime.floatValue;
+    }
+    
+    return imageDuration;
+}
+
 @end

BIN
SLAiELTS/SLAiELTS/Vendor/音波/icon_msg_yy_ab.png


BIN
SLAiELTS/SLAiELTS/Vendor/音波/icon_msg_yy_aw.png


BIN
SLAiELTS/SLAiELTS/Vendor/音波/icon_yb_bg.jpg


+ 3 - 0
SLAiELTS/SLAiELTS/ViewControllers/MessageVC/Models/MessageModel.h

@@ -28,6 +28,9 @@ NS_ASSUME_NONNULL_BEGIN
 /// 是否显示语音
 @property (nonatomic, assign) BOOL showMike;
 
+/// 正在播放
+@property (nonatomic, assign) BOOL onBroadcast;
+
 /// 是否显示text
 @property (nonatomic, assign) BOOL showText;
 

+ 24 - 0
SLAiELTS/SLAiELTS/ViewControllers/MessageVC/Models/SLDecodeGifImage.h

@@ -0,0 +1,24 @@
+//
+//  SLDecodeGifImage.h
+//  SLAiELTS
+//
+//  Created by Gusont on 2023/6/2.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SLDecodeGifImage : NSObject
+
++ (instancetype)SharedInstance;
+
+@property (nonatomic, strong) UIImage *msgYyAb;
+
+@property (nonatomic, strong) UIImage *msgYyAw;
+
+@property (nonatomic, strong) UIImage *msgYyBg;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 38 - 0
SLAiELTS/SLAiELTS/ViewControllers/MessageVC/Models/SLDecodeGifImage.m

@@ -0,0 +1,38 @@
+//
+//  SLDecodeGifImage.m
+//  SLAiELTS
+//
+//  Created by Gusont on 2023/6/2.
+//
+
+#import "SLDecodeGifImage.h"
+
+@implementation SLDecodeGifImage
+
++ (instancetype)SharedInstance
+{
+    static SLDecodeGifImage *decodeGifImage = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        decodeGifImage = [[SLDecodeGifImage alloc] init];
+        {
+            NSString *dataPath = [[NSBundle mainBundle]pathForResource:@"icon_msg_yy_ab" ofType:@"png"];
+            NSData *data = [NSData dataWithContentsOfFile:dataPath];
+            decodeGifImage.msgYyAb = [UIImage decodeGifImageByData:data];
+        }
+        {
+            NSString *dataPath = [[NSBundle mainBundle]pathForResource:@"icon_msg_yy_aw" ofType:@"png"];
+            NSData *data = [NSData dataWithContentsOfFile:dataPath];
+            decodeGifImage.msgYyAw = [UIImage decodeGifImageByData:data];
+        }
+        {
+            NSString *dataPath = [[NSBundle mainBundle]pathForResource:@"icon_yb_bg_01" ofType:@"jpg"];
+            NSData *data = [NSData dataWithContentsOfFile:dataPath];
+            decodeGifImage.msgYyBg = [UIImage decodeGifImageByData:data];
+        }
+    });
+    return decodeGifImage;
+}
+
+
+@end

+ 2 - 0
SLAiELTS/SLAiELTS/ViewControllers/MessageVC/SLMessageViewController.h

@@ -23,6 +23,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 @property (nonatomic, strong) SLFriendsModel *friendModel;
 
+- (void)stopNuisdkPlay;
+
 @end
 
 NS_ASSUME_NONNULL_END

+ 18 - 2
SLAiELTS/SLAiELTS/ViewControllers/MessageVC/SLMessageViewController.m

@@ -40,6 +40,16 @@
     [self navPushViewController:vc animated:YES];
 }
 
+- (void)stopNuisdkPlay {
+    [self.nuisdkPlay stopNuisdkPlay];
+    [self.chatServiceView.messageView.chatDataManager enumerateObjectsUsingBlock:^(MessageModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        if (obj.onBroadcast) {
+            obj.onBroadcast = NO;
+            [self.chatServiceView.messageView.messageCollectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:idx inSection:0]]];
+        }
+    }];
+}
+
 - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view from its nib.
@@ -51,6 +61,7 @@
             dispatch_async(dispatch_get_main_queue(), ^{
                 NSArray *models = [MessageModel mj_objectArrayWithKeyValuesArray:arr];
                 [models enumerateObjectsUsingBlock:^(MessageModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+                    obj.onBroadcast = NO;
                     if (obj.showMike) {
                         obj.showText = NO;
                     }
@@ -85,13 +96,18 @@
     }];
 //
     self.chatServiceView.messageView.broadcastBlock = ^(MessageModel * _Nonnull msgModel) {
+        NSInteger idx = [weakSelf.chatServiceView.messageView.chatDataManager indexOfObject:msgModel];
         if (!msgModel.isReceive && msgModel.showMike) {
-            [weakSelf.nuisdkPlay playSendVoice:msgModel];
+            [weakSelf.nuisdkPlay playSendVoice:msgModel finshBlock:^{
+                msgModel.onBroadcast = NO;
+                [weakSelf.chatServiceView.messageView.messageCollectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:idx inSection:0]]];
+            }];
         }else {
             RoleModel *model = [RoleModel mj_objectWithKeyValues:[[SLGlobalInfo SharedInstance].roleModel mj_JSONObject]];
             model.aiSex = weakSelf.friendModel.sex;
             [weakSelf.nuisdkPlay startTTSWith:msgModel.sendText roleModel:model finshBlock:^{
-
+                msgModel.onBroadcast = NO;
+                [weakSelf.chatServiceView.messageView.messageCollectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:idx inSection:0]]];
             }];
         }
     };

+ 1 - 1
SLAiELTS/SLAiELTS/ViewControllers/MessageVC/Views/IMMessageView/YMIMBaseMessageCell.h

@@ -4,7 +4,7 @@
 #import "MessageModel.h"
 
 
-typedef void(^MikeSegmentSelBlock)(SLMikeSegmentModel * _Nullable sModel);
+typedef void(^MikeSegmentSelBlock)(SLMikeSegmentModel * _Nullable sModel, MessageModel *_Nullable mModel);
 
 NS_ASSUME_NONNULL_BEGIN
 

+ 15 - 3
SLAiELTS/SLAiELTS/ViewControllers/MessageVC/Views/IMMessageView/YMIMBaseMessageCell.m

@@ -3,6 +3,7 @@
 #import "SLMikeSegment.h"
 #import "SLMessageViewController.h"
 #import "SLMikeSegmentModel.h"
+#import "SLDecodeGifImage.h"
 
 @interface YMIMBaseMessageCell()
 
@@ -105,6 +106,9 @@
         _sendFailImageView = nil;
     }
     
+    [self.mikeImageView stopAnimating];
+    
+    
     CGFloat topHeight = msgModel.showMike ? 46 : 0;
     CGFloat topMikeBg = (topHeight ? 6 : 0) + topTimeHeight;
     if (msgModel.isReceive) {
@@ -121,6 +125,10 @@
             self.mikeLabelBgView.backgroundColor = [UIColor whiteColor];
             self.messageLabelBgView.backgroundColor = [UIColor whiteColor];
             self.mikeImageView.image = ImageName(@"icon_msg_yy");
+            if (msgModel.onBroadcast) {
+                self.mikeImageView.image = [SLDecodeGifImage SharedInstance].msgYyAb;
+                [self.mikeImageView startAnimating];
+            }
             NSString *headUrl = [NSString stringWithFormat:@"%@%@",[SLHttpCenter SharedInstance].serverUrl, img];
             [self.msgHeaderView sd_setImageWithURL:[NSURL URLWithString:headUrl] placeholderImage:ImageName(@"icon_ellipse")];
             self.mikeLabel.text = [NSString stringWithFormat:@"%ld″",timeLong];
@@ -200,6 +208,10 @@
         self.mikeLabelBgView.backgroundColor = SLColor(@"#448AF7");
         self.messageLabelBgView.backgroundColor = SLColor(@"#448AF7");
         self.mikeImageView.image = ImageName(@"icon_msg_yy_w");
+        if (msgModel.onBroadcast) {
+            self.mikeImageView.image = [SLDecodeGifImage SharedInstance].msgYyAw;
+            [self.mikeImageView startAnimating];
+        }
         NSString *headUrl = [NSString stringWithFormat:@"%@%@",[SLHttpCenter SharedInstance].serverUrl, [SLGlobalInfo SharedInstance].loginInfo.user.userHead];
         [self.msgHeaderView sd_setImageWithURL:[NSURL URLWithString:headUrl] placeholderImage:ImageName(@"icon_ellipse")];
         NSInteger timeLong = ceil(msgModel.audioDuration);
@@ -323,7 +335,7 @@
 - (void)mikeHandleTap:(UITapGestureRecognizer *)tap {
     SLMikeSegmentModel *model = [SLMikeSegmentModel initWithSegTitle:@"播放" segImage:@"icon_mike_translate" mikeType:SLMikeInputBroadcast];
     if (self.segmentBlock) {
-        self.segmentBlock(model);
+        self.segmentBlock(model,self.msgModel);
     }
 }
 
@@ -397,7 +409,7 @@
         mikeSegment.mikeSegmentBlock = ^(SLMikeSegmentModel *model) {
             [bView removeFromSuperview];
             if (weakSelf.segmentBlock) {
-                weakSelf.segmentBlock(model);
+                weakSelf.segmentBlock(model,self.msgModel);
             }
         };
         [bView addSubview:mikeSegment];
@@ -543,7 +555,7 @@
         [_sendFailImageView addTapWithBlock:^{
             SLMikeSegmentModel *model = [SLMikeSegmentModel initWithSegTitle:@"重发" segImage:@"" mikeType:SLMsgRepeat];
             if (weakSelf.segmentBlock) {
-                weakSelf.segmentBlock(model);
+                weakSelf.segmentBlock(model,self.messageLabel);
             }
         }];
         [self.contentView addSubview:_sendFailImageView];

+ 34 - 24
SLAiELTS/SLAiELTS/ViewControllers/MessageVC/Views/IMMessageView/YMIMMessageCollectionView.m

@@ -195,57 +195,67 @@
 {
     YMIMBaseMessageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass(YMIMBaseMessageCell.class) forIndexPath:indexPath];
 
-    MessageModel *model = [self.chatDataManager objectAtIndex:indexPath.item];
-    [cell confignBaseMessageContentWith:model receiveHeardImg:self.friendModel.userHead];
-    [cell setCellLayerCornerRadiusWith:model];
+    MessageModel *rowModel = [self.chatDataManager objectAtIndex:indexPath.item];
+    [cell confignBaseMessageContentWith:rowModel receiveHeardImg:self.friendModel.userHead];
+    [cell setCellLayerCornerRadiusWith:rowModel];
     WS(weakSelf);
-    cell.segmentBlock = ^(SLMikeSegmentModel * _Nullable sModel) {
+    cell.segmentBlock = ^(SLMikeSegmentModel * _Nullable sModel, MessageModel * _Nullable mModel) {
 //        MessageModel *models = [MessageModel initWithSendText:model.sendText isReceive:model.isReceive showMike:model.showMike showText:model.showText isMike:model.isMike showTime:model.showTime sendTime:model.sendTime voicePath:model.voicePath sendFailure:model.sendFailure sendTextTrans:model.sendTextTrans];
-        MessageModel *models = [MessageModel mj_objectWithKeyValues:[model mj_JSONObject]];
+        MessageModel *newModel = [MessageModel mj_objectWithKeyValues:[mModel mj_JSONObject]];
         switch (sModel.mikeType) {
             case SLMikeInputDelete:
             {
-                [weakSelf removeMessage:model];
+                [weakSelf removeMessage:newModel];
             }
                 break;
             case SLMikeInputLook:
             {
-                models.showText = YES;
-                models.showTrans = NO;
-                [weakSelf updateMessage:models idx:indexPath.row];
+                newModel.showText = YES;
+                newModel.showTrans = NO;
+                [weakSelf updateMessage:newModel idx:indexPath.row];
             }
                 break;
             case SLMikeInputBroadcast:
             {
+                [weakSelf.chatDataManager enumerateObjectsUsingBlock:^(MessageModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+                    if (obj.onBroadcast) {
+                        obj.onBroadcast = NO;
+                        [weakSelf.messageCollectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:idx inSection:0]]];
+                    }
+                    if ([obj isEqual:mModel]) {
+                        obj.onBroadcast = YES;
+                        [weakSelf.messageCollectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:idx inSection:0]]];
+                    }
+                }];
                 if (weakSelf.broadcastBlock) {
-                    weakSelf.broadcastBlock(models);
+                    weakSelf.broadcastBlock(mModel);
                 }
             }
                 break;
             case SLMikeInputHidden:
             {
-                models.showText = NO;
-                models.showTrans = NO;
-                [weakSelf updateMessage:models idx:indexPath.row];
+                newModel.showText = NO;
+                newModel.showTrans = NO;
+                [weakSelf updateMessage:newModel idx:indexPath.row];
             }
                 break;
             case SLMikeInputTransHidden:
             {
-                models.showTrans = NO;
-                [weakSelf updateMessage:models idx:indexPath.row];
+                newModel.showTrans = NO;
+                [weakSelf updateMessage:newModel idx:indexPath.row];
             }
                 break;
             case SLMikeInputTrans:
             {
-                models.showText = YES;
-                models.showTrans = !model.showTrans;
-                if (!model.sendTextTrans) {
+                newModel.showText = YES;
+                newModel.showTrans = !newModel.showTrans;
+                if (!newModel.sendTextTrans) {
                     //百度智能云
                     [[SLHttpCenter SharedInstance] getWithUrl:@"https://aip.baidubce.com/oauth/2.0/token" parameter:@{@"grant_type":@"client_credentials", @"client_id":@"0VhDeLqdcbLamGENfw4c24aq", @"client_secret": @"92qphFKyc0uXGktqFLtfdmqlojt9MsgG"} success:^(id responseObject) {
                         NSString *accessToken = [responseObject objectForKey:@"access_token"];
                         if (accessToken) {
                             NSString *bdUrl = [NSString stringWithFormat:@"https://aip.baidubce.com/rpc/2.0/mt/texttrans/v1?access_token=%@",accessToken];
-                            NSDictionary *dict = @{@"q":model.sendText,
+                            NSDictionary *dict = @{@"q":newModel.sendText,
                                                    @"from":@"auto",
                                                    @"to":@"zh"};
                             [[SLHttpCenter SharedInstance] postWithUrl:bdUrl parameter:dict success:^(id responseObject) {
@@ -254,8 +264,8 @@
                                 if (arr && arr.count) {
                                     NSDictionary *resultDict = arr.firstObject;
                                     NSString *dst = [resultDict objectForKey:@"dst"];
-                                    models.sendTextTrans = dst;
-                                    [weakSelf updateMessage:models idx:indexPath.row];
+                                    newModel.sendTextTrans = dst;
+                                    [weakSelf updateMessage:newModel idx:indexPath.row];
                                 }else {
                                     [ZFToast ShowWithMessage:@"翻译失败"];
                                 }
@@ -269,18 +279,18 @@
                         [ZFToast ShowWithMessage:@"翻译失败"];
                     }];
                 }else {
-                    [weakSelf updateMessage:models idx:indexPath.row];
+                    [weakSelf updateMessage:newModel idx:indexPath.row];
                 }
             }
                 break;
             case SLMsgRepeat:
             {
-                [weakSelf resultsRequestWith:model];
+                [weakSelf resultsRequestWith:newModel];
             }
                 break;
             case SLMsgCopy:
             {
-                [[UIPasteboard generalPasteboard] setString:model.sendText];
+                [[UIPasteboard generalPasteboard] setString:newModel.sendText];
             }
                 break;
             default:

+ 4 - 58
SLAiELTS/SLAiELTS/ViewControllers/MessageVC/Views/SLMikeInputView.m

@@ -7,6 +7,8 @@
 
 #import "SLMikeInputView.h"
 #import "SLMessageViewController.h"
+#import "SLDecodeGifImage.h"
+
 @interface SLMikeInputView()
 
 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *imgHeightConst;
@@ -54,71 +56,14 @@
     //动画时间
     //循环次数
     self.mikeTipImageView.animationRepeatCount = 0;
+    self.mikeTipImageView.image = [SLDecodeGifImage SharedInstance].msgYyBg;
     //启动动画
     [self.mikeTipImageView startAnimating];
-    NSString *dataPath = [[NSBundle mainBundle]pathForResource:@"icon_yb_bg_01" ofType:@"jpg"];
-    NSData *data = [NSData dataWithContentsOfFile:dataPath];
-    self.mikeTipImageView.image = [self decodeGifImageByData:data];
     self.nuiSpeechRecognizer.onVolumeChangedBlock = ^(CGFloat volume) {
 
 
     };
 }
-//解压gif的data为图片数组
--(UIImage *)decodeGifImageByData:(NSData *)data {
-    //获取data资源器,这个可以直接操作图片data
-    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, nil);
-    //获取图片数量 size_t 类似于无符号int
-    size_t count = CGImageSourceGetCount(source);
-    UIImage * animationImage;
-    
-    //如果只有一张则直接解压
-    if (count <= 1) {
-        animationImage = [[UIImage alloc]initWithData:data];
-    }
-    else {
-        NSMutableArray * imageArray = [NSMutableArray arrayWithCapacity:count];
-        NSTimeInterval duration = 0.0f;
-        //遍历获取每一张图片
-        for (size_t i = 0; i < count; i++) {
-            //解析图片拿到图片画笔拿到图片画笔
-            CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL);
-            duration += [self imageDurationAtIndex:i source:source];
-            //scale:图片缩放因子 默认1  orientation:图片绘制方向 默认网上
-            [imageArray addObject:[UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
-            CGImageRelease(imageRef);
-        }
-        
-        //如果没有抓取到图片播放时间,则按照0.1秒一张的方式来了播放
-        if (!duration) {
-            duration = (1.0f / 10.0f) * count;
-        }
-        animationImage = [UIImage animatedImageWithImages:imageArray duration:duration];
-    }
-    
-    
-    CFRelease(source);
-    return animationImage;
-}
-
-//获取每一张图片的持续时间
--(float)imageDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
-    float imageDuration = 0.1f;
-    //获取指定图像的属性信息 如宽、高、持续时间等都在里面 详情参考 CGImageProperties
-    CFDictionaryRef cfImageProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
-    if (!cfImageProperties) {
-        return imageDuration;
-    }
-    NSDictionary * imageProperties = (__bridge NSDictionary *) cfImageProperties;
-    //拿到gif图的属性信息 获取每一帧的时间
-    NSDictionary * gifProperties = [imageProperties valueForKey:(NSString *)kCGImagePropertyGIFDictionary];
-    NSNumber * delayTime = [gifProperties valueForKey:(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
-    if (delayTime != nil) {
-        return delayTime.floatValue;
-    }
-    
-    return imageDuration;
-}
 
 
 - (void)handleLongPressGestures:(UILongPressGestureRecognizer *)paramSender {
@@ -154,6 +99,7 @@
         [generator impactOccurred];
         SLMessageViewController *vc = (SLMessageViewController *)self.viewController;
         if ([vc isKindOfClass:SLMessageViewController.class]) {
+            [vc stopNuisdkPlay];
             UIView *view = [vc.view viewWithTag:SLImHintLabelTag];
             view.backgroundColor = [[UIColor grayColor] colorWithAlphaComponent:0.5];
         }

+ 0 - 3
SLAiELTS/SLAiELTS/ViewControllers/Moments/MomentsVc/SLMomentsNewsVc.m

@@ -29,9 +29,6 @@
     } else {
         self.automaticallyAdjustsScrollViewInsets = NO;
     }
-//    YMBarButtonItem *rightBarItem = [[YMBarButtonItem alloc] initWithTitle:@"清空  " target:self action:@selector(rightBarBtnClick)];
-//    rightBarItem.titleInsets = UIEdgeInsetsMake(0, 0, 0, 20);
-//    self.navigationBar.rightBarButtonItem = rightBarItem;
     [self.tableView registerNibCellWithReuseIdentifierClass:SLMomentsNewsCell.class];
     [[SLHttpCenter SharedInstance] getWithUrl:@"/api/Friend/MessageItemFriend" parameter:@{} success:^(id responseObject) {
         NSDictionary *dataArr = [responseObject objectForKey:@"data"];

+ 1 - 1
SLAiELTS/SLAiELTS/ViewControllers/RoleLabelVC/Models/SLNuisdkPlay.h

@@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
 
 - (void)startTTSWith:(NSString *)ttString roleModel:(RoleModel *)roleModel finshBlock:(SLNuisdkPlayFinshBlock)finshBlock;
 
-- (void)playSendVoice:(MessageModel *)model;
+- (void)playSendVoice:(MessageModel *)model finshBlock:(SLNuisdkPlayFinshBlock)finshBlock;
 
 - (void)stopNuisdkPlay;
 

+ 4 - 1
SLAiELTS/SLAiELTS/ViewControllers/RoleLabelVC/Models/SLNuisdkPlay.m

@@ -129,8 +129,9 @@ static BOOL loop_flag = NO;
     return jsonStr;
 }
 
-- (void)playSendVoice:(MessageModel *)model {
+- (void)playSendVoice:(MessageModel *)model finshBlock:(SLNuisdkPlayFinshBlock)finshBlock {
     [self stopNuisdkPlay];
+    self.finshBlock = finshBlock;
     NSError *error;
     NSString *urlStr = [model.voicePath componentsSeparatedByString:@"Documents"].lastObject;
     NSString *voicePath = [YMPath_DOCUMENT stringByAppendingFormat:@"%@", urlStr];
@@ -241,6 +242,7 @@ static BOOL loop_flag = NO;
     if (player == _audioPlayer && flag) {
         [_audioPlayer pause];
         _audioPlayer = nil;
+        self.finshBlock();
         NSLog(@"----audioPlayerDidFinishPlaying");
     }
 }
@@ -250,6 +252,7 @@ static BOOL loop_flag = NO;
         NSLog(@"播放被中断");
         [_audioPlayer pause];
         _audioPlayer = nil;
+        self.finshBlock();
         NSLog(@"----audioPlayerDidFinishPlaying");
     }
 }