Commit 45591957daf3701d38c3f935e54af931dea15bbc

Authored by 朱林
1 parent e98d288e

完成弹幕逻辑,修改AppId

Showing 26 changed files with 694 additions and 1012 deletions
LiveVideoCloud/LiveVideoCloud.xcodeproj/project.pbxproj
... ... @@ -26,10 +26,8 @@
26 26 811BB6851E8106AF005C6291 /* CNLivePlayerSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 811BB6821E8106A2005C6291 /* CNLivePlayerSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
27 27 811BB6881E8107B4005C6291 /* LVCChatViewTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 811BB6871E8107B4005C6291 /* LVCChatViewTableViewCell.m */; };
28 28 811BB68E1E8116C8005C6291 /* NSString+StringSize.m in Sources */ = {isa = PBXBuildFile; fileRef = 811BB68D1E8116C8005C6291 /* NSString+StringSize.m */; };
29   - 8128E26E1E8A3AFE00B40E75 /* LVCDanmuUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 8128E26D1E8A3AFE00B40E75 /* LVCDanmuUtil.m */; };
30   - 8128E2711E8A3BF000B40E75 /* LVCDanmuView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8128E2701E8A3BF000B40E75 /* LVCDanmuView.m */; };
31   - 8128E2741E8A3C1900B40E75 /* LVCDanmuLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8128E2731E8A3C1900B40E75 /* LVCDanmuLabel.m */; };
32   - 8128E2771E8A3CD700B40E75 /* LVCDanmuManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8128E2761E8A3CD700B40E75 /* LVCDanmuManager.m */; };
  29 + 8128E2881E8A6A3600B40E75 /* CNBarrageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8128E2851E8A6A3600B40E75 /* CNBarrageManager.m */; };
  30 + 8128E2891E8A6A3600B40E75 /* CNBarrageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8128E2871E8A6A3600B40E75 /* CNBarrageView.m */; };
33 31 8130911E1E84C0F0005F0BFF /* LVCMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 8130911D1E84C0F0005F0BFF /* LVCMessage.m */; };
34 32 81A1B9A91E8277410079FF5F /* LVCInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A1B9A81E8277410079FF5F /* LVCInputView.m */; };
35 33 81A482F51E88ACC80097A80A /* LVCTelevisionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A482F41E88ACC80097A80A /* LVCTelevisionView.m */; };
... ... @@ -282,14 +280,10 @@
282 280 811BB6871E8107B4005C6291 /* LVCChatViewTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCChatViewTableViewCell.m; sourceTree = "<group>"; };
283 281 811BB68C1E8116C8005C6291 /* NSString+StringSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+StringSize.h"; sourceTree = "<group>"; };
284 282 811BB68D1E8116C8005C6291 /* NSString+StringSize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+StringSize.m"; sourceTree = "<group>"; };
285   - 8128E26C1E8A3AFE00B40E75 /* LVCDanmuUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCDanmuUtil.h; sourceTree = "<group>"; };
286   - 8128E26D1E8A3AFE00B40E75 /* LVCDanmuUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCDanmuUtil.m; sourceTree = "<group>"; };
287   - 8128E26F1E8A3BF000B40E75 /* LVCDanmuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCDanmuView.h; sourceTree = "<group>"; };
288   - 8128E2701E8A3BF000B40E75 /* LVCDanmuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCDanmuView.m; sourceTree = "<group>"; };
289   - 8128E2721E8A3C1900B40E75 /* LVCDanmuLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCDanmuLabel.h; sourceTree = "<group>"; };
290   - 8128E2731E8A3C1900B40E75 /* LVCDanmuLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCDanmuLabel.m; sourceTree = "<group>"; };
291   - 8128E2751E8A3CD700B40E75 /* LVCDanmuManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCDanmuManager.h; sourceTree = "<group>"; };
292   - 8128E2761E8A3CD700B40E75 /* LVCDanmuManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCDanmuManager.m; sourceTree = "<group>"; };
  283 + 8128E2841E8A6A3600B40E75 /* CNBarrageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNBarrageManager.h; sourceTree = "<group>"; };
  284 + 8128E2851E8A6A3600B40E75 /* CNBarrageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNBarrageManager.m; sourceTree = "<group>"; };
  285 + 8128E2861E8A6A3600B40E75 /* CNBarrageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNBarrageView.h; sourceTree = "<group>"; };
  286 + 8128E2871E8A6A3600B40E75 /* CNBarrageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNBarrageView.m; sourceTree = "<group>"; };
293 287 8130911C1E84C0F0005F0BFF /* LVCMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCMessage.h; sourceTree = "<group>"; };
294 288 8130911D1E84C0F0005F0BFF /* LVCMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCMessage.m; sourceTree = "<group>"; };
295 289 81A1B9A71E8277410079FF5F /* LVCInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCInputView.h; sourceTree = "<group>"; };
... ... @@ -725,19 +719,15 @@
725 719 path = ../ChatView;
726 720 sourceTree = "<group>";
727 721 };
728   - 8128E26B1E8A3AD400B40E75 /* Danmu */ = {
  722 + 8128E2831E8A6A3600B40E75 /* Barrage */ = {
729 723 isa = PBXGroup;
730 724 children = (
731   - 8128E26C1E8A3AFE00B40E75 /* LVCDanmuUtil.h */,
732   - 8128E26D1E8A3AFE00B40E75 /* LVCDanmuUtil.m */,
733   - 8128E26F1E8A3BF000B40E75 /* LVCDanmuView.h */,
734   - 8128E2701E8A3BF000B40E75 /* LVCDanmuView.m */,
735   - 8128E2721E8A3C1900B40E75 /* LVCDanmuLabel.h */,
736   - 8128E2731E8A3C1900B40E75 /* LVCDanmuLabel.m */,
737   - 8128E2751E8A3CD700B40E75 /* LVCDanmuManager.h */,
738   - 8128E2761E8A3CD700B40E75 /* LVCDanmuManager.m */,
  725 + 8128E2841E8A6A3600B40E75 /* CNBarrageManager.h */,
  726 + 8128E2851E8A6A3600B40E75 /* CNBarrageManager.m */,
  727 + 8128E2861E8A6A3600B40E75 /* CNBarrageView.h */,
  728 + 8128E2871E8A6A3600B40E75 /* CNBarrageView.m */,
739 729 );
740   - path = Danmu;
  730 + path = Barrage;
741 731 sourceTree = "<group>";
742 732 };
743 733 812E504E1E7699B9004F5FCD /* CNLiveSDK */ = {
... ... @@ -1667,7 +1657,7 @@
1667 1657 D2888DAA1E6EC014003A77C8 /* View */ = {
1668 1658 isa = PBXGroup;
1669 1659 children = (
1670   - 8128E26B1E8A3AD400B40E75 /* Danmu */,
  1660 + 8128E2831E8A6A3600B40E75 /* Barrage */,
1671 1661 811BB67B1E80F858005C6291 /* ChatView */,
1672 1662 810B64DE1E779AE900133E15 /* LVCPlayer.h */,
1673 1663 810B64DF1E779AE900133E15 /* LVCPlayer.m */,
... ... @@ -1922,7 +1912,6 @@
1922 1912 D2029D011E6EAE2E0027CD92 /* UIColor+HexString.m in Sources */,
1923 1913 D2029CA41E6EADE10027CD92 /* MJRefreshComponent.m in Sources */,
1924 1914 D2575C7A1E76A4F300E3A8FC /* NHCarViews.m in Sources */,
1925   - 8128E26E1E8A3AFE00B40E75 /* LVCDanmuUtil.m in Sources */,
1926 1915 D2029CBC1E6EADE10027CD92 /* SDWebImageDownloaderOperation.m in Sources */,
1927 1916 D2029CA51E6EADE10027CD92 /* MJRefreshFooter.m in Sources */,
1928 1917 D22830FC1E77C2D900627701 /* BottomToolView.m in Sources */,
... ... @@ -1933,6 +1922,7 @@
1933 1922 D2029CD01E6EADE10027CD92 /* SearchPresenter.m in Sources */,
1934 1923 D2888DB71E6EC1B8003A77C8 /* LVCMyViewController.m in Sources */,
1935 1924 D2029CBE1E6EADE10027CD92 /* SDWebImagePrefetcher.m in Sources */,
  1925 + 8128E2891E8A6A3600B40E75 /* CNBarrageView.m in Sources */,
1936 1926 D2A803081E80BD6F009D6F1C /* TopToolView.m in Sources */,
1937 1927 D2B7B2571E8261EF00ED084E /* ChatBarrOperation.m in Sources */,
1938 1928 810B65011E779B1F00133E15 /* MASLayoutConstraint.m in Sources */,
... ... @@ -1970,6 +1960,7 @@
1970 1960 D2029CB61E6EADE10027CD92 /* MKAnnotationView+WebCache.m in Sources */,
1971 1961 D2B2ED801E88FC5200F7538A /* LVCUGCLiveEndView.m in Sources */,
1972 1962 810B64FE1E779B1F00133E15 /* MASCompositeConstraint.m in Sources */,
  1963 + 8128E2881E8A6A3600B40E75 /* CNBarrageManager.m in Sources */,
1973 1964 D2029C981E6EADE10027CD92 /* MJExtensionConst.m in Sources */,
1974 1965 D2575C671E76A25400E3A8FC /* LVCInteractionController.m in Sources */,
1975 1966 D2029CAE1E6EADE10027CD92 /* MJRefreshNormalHeader.m in Sources */,
... ... @@ -1978,7 +1969,6 @@
1978 1969 D2029CC61E6EADE10027CD92 /* SSKeychain.m in Sources */,
1979 1970 811BB68E1E8116C8005C6291 /* NSString+StringSize.m in Sources */,
1980 1971 D2029C8B1E6EADE10027CD92 /* AFURLResponseSerialization.m in Sources */,
1981   - 8128E2711E8A3BF000B40E75 /* LVCDanmuView.m in Sources */,
1982 1972 D2029C921E6EADE10027CD92 /* UIImageView+AFNetworking.m in Sources */,
1983 1973 D224B1971E826ED800CC61D0 /* ChatBarrageAnimAction.m in Sources */,
1984 1974 D2029C9E1E6EADE10027CD92 /* NSObject+MJCoding.m in Sources */,
... ... @@ -1997,7 +1987,6 @@
1997 1987 D2888DB11E6EC05F003A77C8 /* TempViewController.m in Sources */,
1998 1988 81A483011E88B0130097A80A /* LVCBannerModel.m in Sources */,
1999 1989 810B65021E779B1F00133E15 /* MASViewAttribute.m in Sources */,
2000   - 8128E2771E8A3CD700B40E75 /* LVCDanmuManager.m in Sources */,
2001 1990 D2B7B2511E8247D400ED084E /* ChatBarrageManager.m in Sources */,
2002 1991 D2029CAC1E6EADE10027CD92 /* MJRefreshBackStateFooter.m in Sources */,
2003 1992 D2029CB11E6EADE10027CD92 /* MJRefreshConst.m in Sources */,
... ... @@ -2007,7 +1996,6 @@
2007 1996 D2029D051E6EAE2E0027CD92 /* UILabel+labelFitSize.m in Sources */,
2008 1997 D2029CB21E6EADE10027CD92 /* UIScrollView+MJExtension.m in Sources */,
2009 1998 D29D88481E88C53300543A03 /* LVCUGCLivePrepareView.m in Sources */,
2010   - 8128E2741E8A3C1900B40E75 /* LVCDanmuLabel.m in Sources */,
2011 1999 D2029D091E6EAE2E0027CD92 /* Foundation+Log.m in Sources */,
2012 2000 D2029C8E1E6EADE10027CD92 /* AFImageDownloader.m in Sources */,
2013 2001 81A483201E88F4BF0097A80A /* LVCProgramModel.m in Sources */,
... ... @@ -2217,7 +2205,7 @@
2217 2205 "$(inherited)",
2218 2206 "$(PROJECT_DIR)/LiveVideoCloud/Classes/Sections/InteractionSections/Gift/GiftResource",
2219 2207 );
2220   - PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.video;
  2208 + PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.shixunyun;
2221 2209 PRODUCT_NAME = "$(TARGET_NAME)";
2222 2210 };
2223 2211 name = Debug;
... ... @@ -2240,7 +2228,7 @@
2240 2228 "$(inherited)",
2241 2229 "$(PROJECT_DIR)/LiveVideoCloud/Classes/Sections/InteractionSections/Gift/GiftResource",
2242 2230 );
2243   - PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.video;
  2231 + PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.shixunyun;
2244 2232 PRODUCT_NAME = "$(TARGET_NAME)";
2245 2233 };
2246 2234 name = Release;
... ...
LiveVideoCloud/LiveVideoCloud/AppDelegate/AppDelegate.m
... ... @@ -23,23 +23,28 @@
23 23 self.window.rootViewController = [[ZXTabBarController alloc] init];
24 24  
25 25 //初始化直播SDK
26   -// [[CNLiveWebcastManager manager] initWithAppId:AppId appKey:AppKey];
  26 + [[CNLiveWebcastManager manager] initWithAppId:AppId appKey:AppKey];
27 27  
28 28 //初始化聊天SDK并连接服务器
29 29 [[CNLiveChatManager sharedCNLiveChatManager] initWithAppKey:AppKey appId:AppId];
30   -// [[CNLiveChatManager sharedCNLiveChatManager] connectServerSuccess:^{
31   -// NSLog(@"连接服务器-----success");
32   -// } error:^(CNLiveChatConnectErrorCode errors) {
33   -// NSLog(@"连接服务器失败-----%ld", errors);
34   -// }];
35   - // 20170327 20170328
36   - CNLiveChatUserInfo *userInfo = [[CNLiveChatUserInfo alloc] initWithUserId:@"20170328" name:@"20170328" portrait:@""];
37   - [[CNLiveChatManager sharedCNLiveChatManager] loginServer:userInfo success:^(NSString *userId) {
38   - NSLog(@"连接服务器-----success");
39   -
  30 +
  31 + [[CNLiveChatManager sharedCNLiveChatManager] connectServerSuccess:^{
  32 + NSLog(@"连接服务器-----success");
40 33 } error:^(CNLiveChatConnectErrorCode errors) {
41 34 NSLog(@"连接服务器失败-----%ld", errors);
42 35 }];
  36 + /*
  37 + */
  38 + // 20170327 20170328
  39 + /*
  40 + CNLiveChatUserInfo *userInfo = [[CNLiveChatUserInfo alloc] initWithUserId:@"20170328" name:@"20170328" portrait:@""];
  41 + [[CNLiveChatManager sharedCNLiveChatManager] loginServer:userInfo success:^(NSString *userId) {
  42 + NSLog(@"连接服务器-----success");
  43 +
  44 + } error:^(CNLiveChatConnectErrorCode errors) {
  45 + NSLog(@"连接服务器失败-----%ld", errors);
  46 + }];
  47 + */
43 48 [self.window makeKeyAndVisible];
44 49  
45 50 return YES;
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/LiveSections/Controller/LVCLiveViewController.m
... ... @@ -14,10 +14,6 @@
14 14 #import "LiveBaseView.h"
15 15 #import "LVCUGCLiveEndView.h"
16 16  
17   -
18   -#define KAppId @"60_irn9edco29"
19   -#define KAppKey @"69fe70bda67e059286ad509d9f5377f815955645b52f94"
20   -
21 17 @interface LVCLiveViewController ()<UIGestureRecognizerDelegate> {
22 18  
23 19 BOOL _isStreaming;
... ... @@ -61,8 +57,6 @@
61 57 [self.view addSubview:self.openFlashButton];
62 58 [self.view addSubview:self.filterView];
63 59  
64   - [[CNLiveWebcastManager manager] initWithAppId:KAppId appKey:KAppKey];
65   -
66 60 // 初始化推流
67 61 NSString *activityId = [NSString stringWithFormat:@"%d%d%d%d%d",arc4random()%9,arc4random()%9,arc4random()%9,arc4random()%9,arc4random()%9];
68 62  
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/ChatView/LVCChatView.h
... ... @@ -7,9 +7,18 @@
7 7 //
8 8  
9 9 #import <UIKit/UIKit.h>
  10 +#import "chatMsgModel.h"
  11 +
  12 +@class LVCChatView;
  13 +@protocol LVCChatViewDelegate <NSObject>
  14 +
  15 +- (void)lvcChatView:(LVCChatView *)chatView sendBarrageWithModel:(chatMsgModel *)model;
  16 +
  17 +@end
10 18  
11 19 @interface LVCChatView : UIView
12 20 @property (nonatomic, strong) UITableView *tableView;
  21 +@property (nonatomic, assign) id<LVCChatViewDelegate> delegate;
13 22  
14 23 - (instancetype)initWithFrame:(CGRect)frame roomId:(NSString *)roomId;
15 24  
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/ChatView/LVCChatView.m
... ... @@ -69,16 +69,23 @@
69 69 {
70 70 [[CNLiveChatManager sharedCNLiveChatManager] sendMessage:message type:CNLive_ConversationType_CHATROOM targetId:_roomId success:^(CNLiveChatMessage *message) {
71 71  
72   - LVCMessage *msg = [LVCMessage messageWihtContent:message isRight:YES];
  72 + chatMsgModel *model = [[chatMsgModel alloc] init];
  73 + model.content = message.messageContent;
  74 + model.isMine = YES;
73 75  
  76 + LVCMessage *msg = [LVCMessage messageWihtContent:message isRight:YES];
74 77 dispatch_sync(dispatch_get_main_queue(), ^{
75 78 [self addData:msg];
  79 + if (self.delegate && [self.delegate respondsToSelector:@selector(lvcChatView:sendBarrageWithModel:)]) {
  80 + [self.delegate lvcChatView:self sendBarrageWithModel:model];
  81 + }
76 82 });
77 83  
78 84 NSLog(@"电视台--发送消息---success-(%@)",msg.content);
79 85  
80 86 } error:^(CNLiveChatErrorCode errors, NSString *messageId, NSString *targetId) {
81 87 NSLog(@"电视台--发送消息---failed-(%ld)",(long)errors);
  88 +
82 89 }];
83 90 }
84 91  
... ... @@ -100,8 +107,16 @@
100 107 dispatch_queue_t globalQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
101 108 dispatch_async(globalQueue, ^{
102 109 LVCMessage *msg = [LVCMessage messageWihtContent:message isRight:NO];
  110 +
  111 + chatMsgModel *model = [[chatMsgModel alloc] init];
  112 + model.content = message.messageContent;
  113 + model.isMine = NO;
  114 +
103 115 dispatch_sync(dispatch_get_main_queue(), ^{
104 116 [self addData:msg];
  117 + if (self.delegate && [self.delegate respondsToSelector:@selector(lvcChatView:sendBarrageWithModel:)]) {
  118 + [self.delegate lvcChatView:self sendBarrageWithModel:model];
  119 + }
105 120 });
106 121 });
107 122 }
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/ChatView/LVCInputView.m
... ... @@ -45,7 +45,7 @@
45 45 [self.delegate lvcInputView:self sendMessage:_inputTextField.text];
46 46 }
47 47  
48   -// [self endEditing:YES];
  48 + [self endEditing:YES];
49 49 _inputTextField.text = @"";
50 50  
51 51 }
... ... @@ -64,7 +64,7 @@
64 64 [self.delegate lvcInputView:self sendMessage:_inputTextField.text];
65 65 }
66 66  
67   -// [self endEditing:YES];
  67 + [self endEditing:YES];
68 68 textField.text = @"";
69 69 return YES;
70 70 }
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/ChatView/LVCMessage.m
... ... @@ -39,7 +39,9 @@
39 39 msg.nikename = content.userInfo.name;
40 40 msg.portraits = content.userInfo.portraitUri;
41 41  
42   - CGRect rect = [msg.content boundingRectWithSize:CGSizeMake((SCREEN_WIDTH-60)*0.8, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14]} context:nil];
  42 + CGFloat width = SCREEN_WIDTH > SCREEN_HEIGHT ? SCREEN_HEIGHT : SCREEN_WIDTH;
  43 +
  44 + CGRect rect = [msg.content boundingRectWithSize:CGSizeMake((width-60)*0.8, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14]} context:nil];
43 45 CGRect frameOfLabel = CGRectZero;
44 46  
45 47 frameOfLabel.size = rect.size;
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/Controller/LVCLivePlayerController.h
... ... @@ -7,7 +7,10 @@
7 7 //
8 8  
9 9 #import "BaseViewController.h"
  10 +#import "LVCChannelDetailsModel.h"
10 11  
11 12 @interface LVCLivePlayerController : BaseViewController
12 13  
  14 +@property (nonatomic, strong) LVCChannelDetailsModel *model;
  15 +
13 16 @end
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/Controller/LVCLivePlayerController.m
... ... @@ -12,7 +12,11 @@
12 12 #import "LVCInputView.h"
13 13 #import "LVCChatView.h"
14 14  
15   -@interface LVCLivePlayerController ()<LVCPlayerDelegate,LVCInputViewDelegate>
  15 +#import "CNBarrageManager.h"
  16 +#import "CNBarrageView.h"
  17 +#import "chatMsgModel.h"
  18 +
  19 +@interface LVCLivePlayerController ()<LVCPlayerDelegate,LVCInputViewDelegate,LVCChatViewDelegate>
16 20 {
17 21 BOOL isHiddenStatusBar; //记录状态的隐藏显示
18 22 CGRect playerFrame; //播放器原始位置
... ... @@ -29,6 +33,9 @@
29 33 @property (nonatomic, strong) NSTimer *timer;
30 34 @property (nonatomic, assign) NSTimeInterval countTime;
31 35  
  36 +@property (nonatomic, strong) CNBarrageManager *barrageManager; //弹幕管理者
  37 +@property (nonatomic ,strong) UIView *barrageBaseView; //弹幕总View
  38 +
32 39 @end
33 40  
34 41 @implementation LVCLivePlayerController
... ... @@ -73,14 +80,20 @@
73 80 };
74 81  
75 82 [self makeConstraints];
76   -
77 83 [_player autoHideControlView]; //自动隐藏工具条
78   -
79 84  
  85 + self.barrageManager.generateBarrageBlock = ^(CNBarrageView *barrageView) {
  86 + [weakSelf addBarrageView:barrageView];
  87 + };
80 88  
  89 + [self.player.contentView addSubview:self.barrageBaseView];
81 90  
82 91 }
83   -
  92 +- (void)addBarrageView:(CNBarrageView *)barrageView {
  93 + barrageView.frame = CGRectMake(self.player.width+50, barrageView.trajectory, barrageView.width, barrageView.height);
  94 + [self.barrageBaseView addSubview:barrageView];
  95 + [barrageView startAnimation];
  96 +}
84 97  
85 98 - (void)addObservers
86 99 {
... ... @@ -148,11 +161,16 @@
148 161 //当键盘出现
149 162 - (void)keyboardWillShow:(NSNotification *)aNotification{
150 163 //获取键盘的高度
151   -
  164 + NSDictionary *userInfo = [aNotification userInfo];
  165 + NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
  166 + CGRect keyboardRect = [aValue CGRectValue];
  167 + int height = keyboardRect.size.height;
  168 + _inputView.frame = CGRectMake(0, SCREEN_HEIGHT-49-height, SCREEN_WIDTH, 49);
  169 +
152 170 }
153 171  
154 172 - (void)keyboardWillHide:(NSNotification *)aNotification{
155   - _inputView.frame = CGRectMake(0, SCREEN_HEIGHT-50, SCREEN_WIDTH, 50);
  173 + _inputView.frame = CGRectMake(0, SCREEN_HEIGHT-49, SCREEN_WIDTH, 49);
156 174 }
157 175  
158 176 #pragma mark -
... ... @@ -177,6 +195,18 @@
177 195 [UIView animateWithDuration:0.3 animations:^{
178 196 self.player.transform = CGAffineTransformMakeRotation(0);
179 197 }];
  198 +
  199 + //是否显示弹幕
  200 + if ([_player displayBarrage]) {
  201 + [self.player.contentView addSubview:self.barrageBaseView];
  202 + [self.player.contentView insertSubview:self.barrageBaseView atIndex:1];
  203 + self.barrageManager.isStopBarrage = NO;
  204 + } else {
  205 + self.barrageManager.isStopBarrage = YES;
  206 + [self.barrageManager stopBarrage];
  207 + [self.barrageBaseView removeFromSuperview];
  208 + }
  209 +
180 210 }];
181 211  
182 212 }
... ... @@ -198,9 +228,24 @@
198 228 [UIView animateWithDuration:0.3 animations:^{
199 229 self.player.transform = CGAffineTransformMakeRotation(0);
200 230 }];
  231 +
  232 + self.barrageManager.isStopBarrage = YES;
  233 + [self.barrageManager stopBarrage];
  234 + [self.barrageBaseView removeFromSuperview];
  235 +
201 236 }];
202 237 }
203 238  
  239 +
  240 +#pragma mark -
  241 +#pragma mark - LVCChatViewDelegate
  242 +- (void)lvcChatView:(LVCChatView *)chatView sendBarrageWithModel:(chatMsgModel *)model
  243 +{
  244 + if (_player.isFullScreen) {
  245 + [self.barrageManager startBarrageWithNewArray:[NSMutableArray arrayWithObject:model]];
  246 + }
  247 +}
  248 +
204 249 #pragma mark -
205 250 #pragma mark - LVCPlayerDelegate
206 251 - (void)lvcPlayer:(LVCPlayer *)player clickedBackBtn:(UIButton *)backBtn
... ... @@ -220,7 +265,7 @@
220 265 }
221 266 }
222 267  
223   -- (void)lvcPlayer:(LVCPlayer *)player clicketullScreenBtn:(UIButton *)fullScreenBtn
  268 +- (void)lvcPlayer:(LVCPlayer *)player clickedFullScreenBtn:(UIButton *)fullScreenBtn
224 269 {
225 270 if (_player.isFullScreen) {//全屏
226 271 [self toHalfScreenWithrotationAngle:M_PI_2];
... ... @@ -236,13 +281,28 @@
236 281  
237 282 }
238 283  
  284 +- (void)lvcPlayer:(LVCPlayer *)player barrageSwitch:(BOOL)on
  285 +{
  286 + if (on) { //开启弹幕
  287 + [self.player.contentView addSubview:self.barrageBaseView];
  288 + [self.player.contentView insertSubview:self.barrageBaseView atIndex:1];
  289 + self.barrageManager.isStopBarrage = NO;
  290 +
  291 + } else { //关闭弹幕
  292 + self.barrageManager.isStopBarrage = YES;
  293 + [self.barrageManager stopBarrage];
  294 + [self.barrageBaseView removeFromSuperview];
  295 + }
  296 +}
  297 +
239 298 #pragma mark -
240 299 #pragma mark - LVCInputViewDelegate
241 300 - (void)lvcInputView:(LVCInputView *)inputView sendMessage:(NSString *)message
242 301 {
243   - NSLog(@"发送消息(%@)",message);
  302 + [_chatView sendMsgWithMessage:message];
244 303  
245   -// [_chatView sendMsgWithMessage:message];
  304 + if (!_player.isFullScreen) return;
  305 + inputView.hidden = YES;
246 306 }
247 307  
248 308 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
... ... @@ -273,6 +333,7 @@
273 333 }];
274 334 _inputView.frame = CGRectMake(0, SCREEN_HEIGHT-50, SCREEN_WIDTH, 49);
275 335  
  336 + _barrageBaseView.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
276 337 } else { //半屏
277 338 [self.player mas_remakeConstraints:^(MASConstraintMaker *make) {
278 339 make.top.mas_equalTo(20);
... ... @@ -289,7 +350,7 @@
289 350 - (LVCPlayer *)player
290 351 {
291 352 if (!_player) {
292   - _player = [[LVCPlayer alloc] init];
  353 + _player = [[LVCPlayer alloc] initWithFrame:CGRectZero playerModel:self.model];
293 354 _player.delegate = self;
294 355 }
295 356 return _player;
... ... @@ -316,10 +377,29 @@
316 377 {
317 378 if (!_chatView) {
318 379 _chatView = [[LVCChatView alloc] initWithFrame:CGRectMake(0, SCREEN_WIDTH*9/16+20, SCREEN_WIDTH, SCREEN_HEIGHT-SCREEN_WIDTH*9/16-20-49) roomId:_roomId];
  380 + _chatView.delegate = self;
319 381 }
320 382 return _chatView;
321 383 }
322 384  
  385 +- (UIView *)barrageBaseView
  386 +{
  387 + if (!_barrageBaseView) {
  388 + _barrageBaseView = [[UIView alloc] init];
  389 + _barrageBaseView.backgroundColor = [UIColor clearColor];
  390 + [self.view addSubview:_barrageBaseView];
  391 + }
  392 + return _barrageBaseView;
  393 +}
  394 +
  395 +- (CNBarrageManager *)barrageManager
  396 +{
  397 + if (!_barrageManager)
  398 + {
  399 + self.barrageManager = [[CNBarrageManager alloc] init];
  400 + }
  401 + return _barrageManager;
  402 +}
323 403  
324 404 - (void)didReceiveMemoryWarning {
325 405 [super didReceiveMemoryWarning];
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Barrage/CNBarrageManager.h 0 → 100644
  1 +//
  2 +// CNBarrageManager.h
  3 +// personalXmppChatDemo
  4 +//
  5 +// Created by 张旭 on 2016/12/10.
  6 +// Copyright © 2016年 cnlive. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import "chatMsgModel.h"
  11 +
  12 +@class CNBarrageView;
  13 +
  14 +@interface CNBarrageManager : NSObject
  15 +
  16 +@property (nonatomic, copy) void(^generateBarrageBlock)(CNBarrageView *view);//生成弹幕View回调
  17 +@property (nonatomic) BOOL isStopBarrage;//是否关闭了弹幕
  18 +/**
  19 + 开始弹幕根据新消息数组
  20 +
  21 + @param newBarrageArray 新消息数组
  22 + */
  23 +- (void)startBarrageWithNewArray:(NSMutableArray <chatMsgModel *>*)newBarrageArray;
  24 +
  25 +/**
  26 + 停止弹幕
  27 + */
  28 +- (void)stopBarrage;
  29 +
  30 +
  31 +
  32 +@end
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Barrage/CNBarrageManager.m 0 → 100644
  1 +//
  2 +// CNBarrageManager.m
  3 +// personalXmppChatDemo
  4 +//
  5 +// Created by 张旭 on 2016/12/10.
  6 +// Copyright © 2016年 cnlive. All rights reserved.
  7 +//
  8 +
  9 +#import "CNBarrageManager.h"
  10 +#import "CNBarrageView.h"
  11 +
  12 +#define MAX_OVERLAP_COUNT 100
  13 +
  14 +@interface CNBarrageManager ()
  15 +
  16 +@property (nonatomic, strong) NSMutableArray *_Nullable allComments;//所有评论
  17 +@property (nonatomic, strong) NSMutableArray *_Nullable tmpComments;//临时评论
  18 +@property (nonatomic ,strong) NSMutableArray *_Nullable barrageQueue;//评论管理队列数组
  19 +@property (nonatomic ,strong) NSMutableArray *_Nullable trajectoryArr;//弹幕轨迹数组
  20 +
  21 +@property BOOL isStarted;//标记是否开始弹幕
  22 +@property BOOL isStopAnimation;//标记是否停止弹幕
  23 +
  24 +@end
  25 +
  26 +@implementation CNBarrageManager
  27 +
  28 +/**
  29 + 开始弹幕根据新消息数组
  30 +
  31 + @param newBarrageArray 新消息数组
  32 + */
  33 +- (void)startBarrageWithNewArray:(NSMutableArray <chatMsgModel *>*)newBarrageArray
  34 +{
  35 + if (self.isStopAnimation && _isStopBarrage) {
  36 + return;
  37 + }
  38 + [self.allComments addObjectsFromArray:newBarrageArray];
  39 +
  40 + [self startBarrage];
  41 +}
  42 +
  43 +/**
  44 + 开始弹幕
  45 + */
  46 +- (void)startBarrage
  47 +{
  48 + if (self.tmpComments.count == 0) {
  49 + [self.tmpComments addObjectsFromArray:self.allComments];
  50 + [self.allComments removeAllObjects];
  51 + }
  52 +
  53 + self.isStarted = YES;
  54 + self.isStopAnimation = NO;
  55 + [self initBarrageCommentView];
  56 +}
  57 +
  58 +/**
  59 + 停止弹幕
  60 + */
  61 +- (void)stopBarrage
  62 +{
  63 + self.isStopAnimation = YES;
  64 +
  65 + [self.barrageQueue enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  66 + CNBarrageView *view = obj;
  67 + [view stopAnimation];
  68 + view = nil;
  69 + self.tmpComments = nil;
  70 + self.allComments = nil;
  71 + self.trajectoryArr = nil;
  72 + }];
  73 + self.barrageQueue = nil;
  74 +}
  75 +
  76 +/**
  77 + 初始化弹幕的评论View
  78 + */
  79 +- (void)initBarrageCommentView
  80 +{
  81 + if(self.isStopAnimation)return;
  82 + //初始化轨道位置随机
  83 + long count = self.tmpComments.count;
  84 + for (int i = 0; i < count; i ++) {
  85 + chatMsgModel *model = [self.tmpComments firstObject];
  86 + NSString *comment = model.content;
  87 + if (comment) {
  88 + [self.tmpComments removeObjectAtIndex:0];
  89 + //根据当前未发送弹幕数量生成轨迹
  90 + NSString *trajectory;
  91 + if (self.tmpComments.count > MAX_OVERLAP_COUNT)
  92 + {//数量较多轨迹可重叠
  93 + trajectory = [self trajectoryOverlap:YES];
  94 + }else
  95 + {//数量较少轨迹可能不重叠,但频率高会使轨迹数组已满,造成重叠
  96 + trajectory = [self trajectoryOverlap:NO];
  97 + }
  98 + [self createBarrageComment:comment trajectory:trajectory isMine:model.isMine];
  99 + }
  100 + else {
  101 + //当弹幕没有时跳出循环
  102 + break;
  103 + }
  104 + }
  105 +}
  106 +
  107 +/**
  108 + 评论弹幕轨迹
  109 +
  110 + @param isOverlap 是否重叠
  111 + @return 根据轨迹是否可重叠,生成对应的新轨迹
  112 + */
  113 +- (NSString *)trajectoryOverlap:(BOOL)isOverlap
  114 +{
  115 + NSString *trajectory = @"";
  116 + long arcIndex = arc4random() % MAX_BARRAGE_VERTICAL_COUNT;
  117 + CGFloat tra = arcIndex * BARRAGE_VERTICAL_HEIGHT + (arcIndex - 1) * BARRAGE_VERTICAL_MARGIN;
  118 + if (isOverlap) {
  119 + //生成可重叠的轨迹
  120 + trajectory = [NSString stringWithFormat:@"%f",tra];
  121 + [self.trajectoryArr addObject:trajectory];
  122 + return [NSString stringWithFormat:@"%f",tra];
  123 + }
  124 + //生成不重叠的轨迹
  125 + do {
  126 + arcIndex = arc4random() % MAX_BARRAGE_VERTICAL_COUNT;
  127 + tra = arcIndex * BARRAGE_VERTICAL_HEIGHT + (arcIndex - 1) * BARRAGE_VERTICAL_MARGIN;
  128 + trajectory = [NSString stringWithFormat:@"%f",tra];
  129 + if (self.trajectoryArr.count >= MAX_BARRAGE_VERTICAL_COUNT) break;
  130 +
  131 + } while ([self.trajectoryArr containsObject:trajectory]);
  132 + if (self.trajectoryArr.count >= MAX_BARRAGE_VERTICAL_COUNT)
  133 + {//当前轨迹数组已满,弹幕需要重叠显示
  134 +
  135 + }else
  136 + {//当前轨迹数组还没满,弹幕无需重叠
  137 + [self.trajectoryArr addObject:trajectory];
  138 + }
  139 + return trajectory;
  140 +}
  141 +
  142 +/**
  143 + 下一条评论
  144 +
  145 + @return 返回当前tmpComments的下一条评论数据
  146 + */
  147 +- (NSString *)nextComment {
  148 + chatMsgModel *model = [self.tmpComments firstObject];
  149 + if (model.content) {
  150 + [self.tmpComments removeObjectAtIndex:0];
  151 + }
  152 + return model.content;
  153 +}
  154 +
  155 +/**
  156 + 创建评论弹幕,根据评论内容和弹幕轨迹
  157 +
  158 + @param comment 评论内容
  159 + @param trajectory 弹幕轨迹
  160 + */
  161 +- (void)createBarrageComment:(NSString *)comment trajectory:(NSString *)trajectory isMine:(BOOL)isMine
  162 +{
  163 + if (self.isStopAnimation) {
  164 + return;
  165 + }
  166 + //创建一个弹幕view
  167 + CNBarrageView *view = [[CNBarrageView alloc] initWithContent:comment isMine:isMine];
  168 +
  169 + //设置运行轨迹
  170 + view.trajectory = [trajectory floatValue];
  171 + weakself
  172 + __weak CNBarrageView *weakBarrageView = view;
  173 + view.moveBlock = ^(CommentMoveState status){
  174 + strongself
  175 + if (self.isStopAnimation) {
  176 + return;
  177 + }
  178 + switch (status) {
  179 + case CommentMoveStateStart:
  180 + {
  181 + //弹幕开始,将view加入弹幕管理数组
  182 + [self.barrageQueue addObject:weakBarrageView];
  183 + }
  184 + break;
  185 + case CommentMoveStateEnter:
  186 + {
  187 + [self.trajectoryArr removeObject:trajectory];
  188 + //弹幕完全进入屏幕,判断接下来是否还有内容,如果有则在该弹幕轨迹队列中创建弹幕
  189 + NSString *comment = [self nextComment];
  190 + if (comment) {
  191 + [self createBarrageComment:comment trajectory:trajectory isMine:isMine];
  192 + }
  193 + else {
  194 + //没有评论了
  195 + }
  196 + }
  197 + break;
  198 + case CommentMoveStateEnd:
  199 + {
  200 + //弹幕飞出屏幕后从弹幕管理队列中删除
  201 + if ([self.barrageQueue containsObject:weakBarrageView]) {
  202 + [self.barrageQueue removeObject:weakBarrageView];
  203 + }
  204 + }
  205 + break;
  206 + default:
  207 + break;
  208 + }
  209 + };
  210 + //弹幕生成后,传到Controller进行页面展示
  211 + if (self.generateBarrageBlock) {
  212 + self.generateBarrageBlock(view);
  213 + }
  214 +}
  215 +
  216 +#pragma mark - getter
  217 +
  218 +- (NSMutableArray *)allComments {
  219 + if (!_allComments) {
  220 + _allComments = [NSMutableArray array];
  221 + }
  222 + return _allComments;
  223 +}
  224 +
  225 +- (NSMutableArray *)tmpComments {
  226 + if (!_tmpComments) {
  227 + _tmpComments = [NSMutableArray array];
  228 + }
  229 + return _tmpComments;
  230 +}
  231 +
  232 +- (NSMutableArray *)barrageQueue {
  233 + if (!_barrageQueue) {
  234 + _barrageQueue = [NSMutableArray array];
  235 + }
  236 + return _barrageQueue;
  237 +}
  238 +
  239 +- (NSMutableArray *)trajectoryArr {
  240 + if (!_trajectoryArr) {
  241 + _trajectoryArr = [NSMutableArray array];
  242 + }
  243 + return _trajectoryArr;
  244 +}
  245 +
  246 +@end
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Barrage/CNBarrageView.h 0 → 100644
  1 +//
  2 +// CNBarrageView.h
  3 +// personalXmppChatDemo
  4 +//
  5 +// Created by 张旭 on 2016/12/10.
  6 +// Copyright © 2016年 cnlive. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +
  11 +#define BARRAGE_VERTICAL_HEIGHT 25 //每个弹幕View在垂直方向上的高度
  12 +#define MAX_BARRAGE_VERTICAL_COUNT (long)[UIScreen mainScreen].bounds.size.height / BARRAGE_VERTICAL_HEIGHT //垂直方向上的弹幕最大数量
  13 +#define BARRAGE_VERTICAL_MARGIN ([UIScreen mainScreen].bounds.size.height - BARRAGE_VERTICAL_HEIGHT * MAX_BARRAGE_VERTICAL_COUNT) / (MAX_BARRAGE_VERTICAL_COUNT - 1) //垂直方向上弹幕之间的间隙
  14 +
  15 +typedef NS_ENUM(NSInteger, CommentMoveState){//弹幕移动的状态
  16 + CommentMoveStateStart = 0,//将要进入屏幕
  17 + CommentMoveStateEnter ,//完全进入
  18 + CommentMoveStateEnd //完全移除屏幕
  19 +};
  20 +
  21 +
  22 +@interface CNBarrageView : UIView
  23 +
  24 +@property (nonatomic ,copy) void (^moveBlock) (CommentMoveState state);//弹幕移动的状态
  25 +@property (nonatomic) CGFloat trajectory;//弹幕的移动轨迹
  26 +
  27 +/**
  28 + 初始化弹幕View根据评论内容,消息是否是自己发送
  29 +
  30 + @param content 评论内容
  31 + @param isMine 是否是自己的评论弹幕
  32 + @return 弹幕View
  33 + */
  34 +- (instancetype)initWithContent:(NSString *)content isMine:(BOOL)isMine;
  35 +
  36 +/**
  37 + 开始移动动画
  38 + */
  39 +- (void)startAnimation;
  40 +
  41 +/**
  42 + 停止移动动画
  43 + */
  44 +- (void)stopAnimation;
  45 +
  46 +@end
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Barrage/CNBarrageView.m 0 → 100644
  1 +
  2 +//
  3 +// CNBarrageView.m
  4 +// personalXmppChatDemo
  5 +//
  6 +// Created by 张旭 on 2016/12/10.
  7 +// Copyright © 2016年 cnlive. All rights reserved.
  8 +//
  9 +
  10 +#import "CNBarrageView.h"
  11 +
  12 +#define TotalDuration 5 //弹幕飘过总时间
  13 +#define BARRAGE_Horizontal_Margin 5 //弹幕间水平间隙
  14 +
  15 +#define LVCRandomColor LVCColor(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256))
  16 +#define LVCColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]
  17 +
  18 +
  19 +
  20 +@interface CNBarrageView ()
  21 +
  22 +@property (nonatomic ,strong) UILabel * _Nullable commentLabel;//评论Label
  23 +@property BOOL isDealloc;//标记资源是否已释放
  24 +
  25 +@end
  26 +
  27 +@implementation CNBarrageView
  28 +
  29 +/**
  30 + 销毁对象及动画
  31 + */
  32 +- (void)dealloc
  33 +{
  34 + [self stopAnimation];
  35 + self.moveBlock = nil;
  36 +}
  37 +
  38 +/**
  39 + 初始化弹幕View根据评论内容,消息是否是自己发送
  40 +
  41 + @param content 评论内容
  42 + @param isMine 是否是自己的评论弹幕
  43 + @return 弹幕View
  44 + */
  45 +- (instancetype)initWithContent:(NSString *)content isMine:(BOOL)isMine
  46 +{
  47 + if (self = [super init])
  48 + {
  49 + NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:17]};
  50 + float width = [content sizeWithAttributes:attributes].width;
  51 +// float height = [content sizeWithAttributes:attributes].height;
  52 +// NSLog(@"%f",height);//16.707031
  53 + self.bounds = CGRectMake(0, 0, width + BARRAGE_Horizontal_Margin * 2, BARRAGE_VERTICAL_HEIGHT);
  54 + self.commentLabel.text = content;
  55 + self.commentLabel.frame = CGRectMake(BARRAGE_Horizontal_Margin, 0, width, BARRAGE_VERTICAL_HEIGHT);
  56 + if(isMine)
  57 + {
  58 + self.commentLabel.textColor = [UIColor redColor];
  59 + }else
  60 + {
  61 + self.commentLabel.textColor = LVCRandomColor;
  62 + }
  63 +
  64 + }
  65 + return self;
  66 +}
  67 +
  68 +/**
  69 + 开始移动动画
  70 + */
  71 +- (void)startAnimation
  72 +{
  73 + CGFloat wholeWidth = self.width + SCREEN_WIDTH + 50;//总轨迹长度
  74 + CGFloat speed = wholeWidth / TotalDuration;//速度
  75 + CGFloat duration = (self.width + 50) / speed;//完全进入屏幕的时间
  76 +
  77 + if (self.moveBlock) {
  78 + //弹幕开始进入屏幕
  79 + self.moveBlock(CommentMoveStateStart);
  80 + }
  81 +
  82 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  83 + //避免重复,若资源已释放 不再操作
  84 + if (self.isDealloc) {
  85 + return;
  86 + }
  87 + //duration时间后弹幕完全进入屏幕
  88 + if (self.moveBlock) {
  89 + self.moveBlock(CommentMoveStateEnter);
  90 + }
  91 + });
  92 +
  93 + weakself
  94 + //弹幕完全离开屏幕
  95 + [UIView animateWithDuration:TotalDuration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
  96 + strongself
  97 + self.left = - self.width;
  98 + } completion:^(BOOL finished) {
  99 + if (self.moveBlock) {
  100 + self.moveBlock(CommentMoveStateEnd);
  101 + }
  102 + [self removeFromSuperview];
  103 + }];
  104 +
  105 +}
  106 +
  107 +/**
  108 + 停止移动动画
  109 + */
  110 +- (void)stopAnimation
  111 +{
  112 + self.isDealloc = YES;
  113 + [self.layer removeAllAnimations];
  114 + [self removeFromSuperview];
  115 +}
  116 +
  117 +#pragma mark getter
  118 +
  119 +- (UILabel *)commentLabel
  120 +{
  121 + if (!_commentLabel) {
  122 + _commentLabel = [[UILabel alloc] init];
  123 + _commentLabel.backgroundColor = [UIColor clearColor];
  124 + _commentLabel.font = [UIFont systemFontOfSize:17];
  125 + _commentLabel.textColor = [UIColor whiteColor];
  126 + [self addSubview:self.commentLabel];
  127 + }
  128 + return _commentLabel;
  129 +}
  130 +
  131 +/*
  132 +// Only override drawRect: if you perform custom drawing.
  133 +// An empty implementation adversely affects performance during animation.
  134 +- (void)drawRect:(CGRect)rect {
  135 + // Drawing code
  136 +}
  137 +*/
  138 +
  139 +@end
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Danmu/LVCDanmuLabel.h deleted 100644 → 0
1   -//
2   -// LVCDanmuLabel.h
3   -// LiveVideoCloud
4   -//
5   -// Created by iOS on 17/3/28.
6   -// Copyright © 2017年 cnlive. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -#import "LVCDanmuUtil.h"
11   -
12   -@interface LVCDanmuLabel : UILabel
13   -
14   -
15   -@property (nonatomic, strong, readonly) NSDictionary *info;
16   -@property (nonatomic, readonly) DanmuState danmuState;
17   -@property (nonatomic, readonly) CGFloat animationDuartion;
18   -@property (nonatomic, strong, readonly) NSDictionary *dicOptional;
19   -
20   -@property (nonatomic, readonly) CGFloat speed;
21   -@property (nonatomic, readonly) CGFloat currentRightX;
22   -
23   -@property (nonatomic, readonly) CGFloat startTime;
24   -
25   -
26   -@property (nonatomic, getter=isFontSizeBig, readonly) BOOL fontSizeBig;
27   -@property (nonatomic, getter=isFontSizeMiddle, readonly) BOOL fontSizeMiddle;
28   -@property (nonatomic, getter=isFontSizeSmall, readonly) BOOL fontSizeSmall;
29   -@property (nonatomic, getter=isMoveModeRolling, readonly) BOOL moveModeRolling;
30   -@property (nonatomic, getter=isPositionTop, readonly) BOOL positionTop;
31   -@property (nonatomic, getter=isPositionMiddle, readonly) BOOL positionMiddle;
32   -@property (nonatomic, getter=isPositionBottom, readonly) BOOL positionBottom;
33   -
34   -+ (instancetype)createWithInfo:(NSDictionary *)info inView:(UIView *)view;
35   -
36   -- (void)setDanmuChannel:(NSUInteger)channel offset:(CGFloat)xy;
37   -
38   -- (void)animationDanmuItem:(NSTimeInterval)waitTime;
39   -
40   -- (void)pause;
41   -
42   -- (void)resume:(NSTimeInterval)nowTime;
43   -
44   -- (void)removeDanmu;
45   -
46   -@end
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Danmu/LVCDanmuLabel.m deleted 100644 → 0
1   -//
2   -// LVCDanmuLabel.m
3   -// LiveVideoCloud
4   -//
5   -// Created by iOS on 17/3/28.
6   -// Copyright © 2017年 cnlive. All rights reserved.
7   -//
8   -
9   -#import "LVCDanmuLabel.h"
10   -
11   -static NSString * const DANMU_FONT_SIZE_BIG = @"l";
12   -static NSString * const DANMU_FONT_SIZE_MIDDLE = @"m";
13   -static NSString * const DANMU_FONT_SIZE_SMALL = @"s";
14   -
15   -static NSString * const DANMU_MOVE_MODE_ROLLING = @"l";
16   -
17   -static NSString * const DANMU_POSITION_TOP = @"t";
18   -static NSString * const DANMU_POSITION_MIDDLE = @"m";
19   -static NSString * const DANMU_POSITION_BOTTOM = @"b";
20   -
21   -#define ARC4RANDOM_MAX 0x100000000
22   -
23   -#define ROLL_ANIMATION_DURATION_TIME 5
24   -
25   -#define ANIMATION_DELAY_TIME 3
26   -
27   -@interface LVCDanmuLabel ()
28   -
29   -@property (nonatomic, strong, readwrite) NSDictionary *info;
30   -@property (nonatomic, readwrite) DanmuState danmuState;
31   -@property (nonatomic, readwrite) CGFloat animationDuartion;
32   -@property (nonatomic, strong, readwrite) NSDictionary *dicOptional;
33   -
34   -@property (nonatomic, readwrite) CGFloat speed;
35   -@property (nonatomic, readwrite) CGFloat currentRightX;
36   -
37   -@property (nonatomic) NSUInteger nChannel;
38   -@property (nonatomic, weak) UIView *superView;
39   -
40   -@property (nonatomic) CGFloat originalX;
41   -
42   -@end
43   -
44   -@implementation LVCDanmuLabel
45   -
46   -- (void)dealloc {
47   - _info = nil;
48   - _dicOptional = nil;
49   -}
50   -
51   -#pragma mark - Private
52   -
53   -- (void)p_initData {
54   - self.textColor = [UIColor blackColor];
55   - // 弹幕颜色
56   - // id optional = [self.info objectForKey:kDanmuOptionalKey];
57   - // if ([optional isKindOfClass:[NSString class]]) {
58   - // optional = [LVCDanmuUtil defaultOptions];
59   - // }
60   - id optional = [LVCDanmuUtil randomOptions];
61   - self.dicOptional = [NSDictionary dictionaryWithDictionary:optional];
62   -
63   - int color = [[optional objectForKey:@"c"] intValue];
64   - [self setTextColor:[LVCDanmuUtil colorFromARGB: color]];
65   -
66   - CGFloat fontsize = 15;
67   - if (self.isFontSizeBig) {
68   - fontsize = 19;
69   - }else if (self.isFontSizeMiddle) {
70   - fontsize = 17;
71   - }
72   -
73   - UIFont *font = [UIFont systemFontOfSize:fontsize];
74   - self.font = font;
75   -
76   - NSString *content = [_info objectForKey:kDanmuContentKey];
77   - self.text = content;
78   -}
79   -
80   -- (void)p_initFrame:(CGFloat)offsetX {
81   - NSString *content = [self.info objectForKey:kDanmuContentKey];
82   - CGSize size = [LVCDanmuUtil getSizeWithString:content withFont:self.font size:(CGSize){MAXFLOAT, CHANNEL_HEIGHT}];
83   - CGRect frame = (CGRect){(CGPoint){_superView.frame.size.width + offsetX, 0}, size};
84   - self.frame = frame;
85   - _originalX = frame.origin.x + frame.size.width;
86   -}
87   -
88   -- (void)p_rollAnimation:(CGFloat)time delay:(NSTimeInterval)waitTime {
89   - self.danmuState = DanmuStateAnimationing;
90   - [UIView animateWithDuration:time delay:waitTime options:UIViewAnimationOptionCurveLinear animations:^{
91   - CGRect frame = self.frame;
92   - frame.origin.x = -self.frame.size.width;
93   - self.frame = frame;
94   - } completion:^(BOOL finished) {
95   - if (finished)
96   - [self removeDanmu];
97   - }];
98   -}
99   -
100   -#pragma mark - Action
101   -
102   -+ (instancetype)createWithInfo:(NSDictionary *)info inView:(UIView *)view {
103   - LVCDanmuLabel *danmuLabel = [[LVCDanmuLabel alloc] init];
104   -
105   - danmuLabel.info = info;
106   - danmuLabel.superView = view;
107   - danmuLabel.nChannel = 0;
108   -
109   - [danmuLabel p_initData];
110   - [danmuLabel p_initFrame:0];
111   -
112   - return danmuLabel;
113   -}
114   -
115   -- (void)setDanmuChannel:(NSUInteger)channel offset:(CGFloat)xy {
116   - self.danmuState = DanmuStateStop;
117   - self.nChannel = channel;
118   - CGRect frame = self.frame;
119   - frame.origin.x += xy;
120   - frame.origin.y = CHANNEL_HEIGHT*_nChannel;
121   - self.frame = frame;
122   - _originalX = frame.origin.x + frame.size.width;
123   - [_superView addSubview:self];
124   -}
125   -
126   -- (void)animationDanmuItem:(NSTimeInterval)waitTime {
127   -
128   - [self p_rollAnimation:self.animationDuartion delay:waitTime];
129   -}
130   -
131   -- (void)pause {
132   - self.danmuState = DanmuStateStop;
133   - UIView *view = self;
134   - CALayer *layer = view.layer;
135   - CGRect rect = view.frame;
136   - if (layer.presentationLayer) {
137   - rect = ((CALayer *)layer.presentationLayer).frame;
138   - // rect.origin.x -= 1;
139   - }
140   - view.frame = rect;
141   - [view.layer removeAllAnimations];
142   -}
143   -
144   -- (void)resume:(NSTimeInterval)nowTime {
145   - CGFloat waitTime = self.startTime;
146   - if (waitTime > nowTime)
147   - waitTime = waitTime - nowTime;
148   - else
149   - waitTime = 0;
150   -
151   - CGFloat time = (self.frame.origin.x + self.frame.size.width)/self.speed;
152   - [self p_rollAnimation:time delay:waitTime];
153   -}
154   -
155   -- (void)removeDanmu {
156   - self.danmuState = DanmuStateFinish;
157   - [self.layer removeAllAnimations];
158   - [self removeFromSuperview];
159   -}
160   -
161   -
162   -#pragma mark - Get
163   -
164   -- (CGFloat)speed {
165   - _speed = _originalX/self.animationDuartion;
166   - return _speed;
167   -}
168   -
169   -- (CGFloat)animationDuartion {
170   - _animationDuartion = ROLL_ANIMATION_DURATION_TIME;
171   - return _animationDuartion;
172   -}
173   -
174   -- (CGFloat)currentRightX {
175   - switch (self.danmuState) {
176   - case DanmuStateStop: {
177   - _currentRightX = CGRectGetMaxX(self.frame) - _superView.frame.size.width;
178   - break;
179   - }
180   - case DanmuStateAnimationing: {
181   - CALayer *layer = self.layer;
182   - _currentRightX = _originalX;
183   - if (layer.presentationLayer)
184   - _currentRightX = ((CALayer *)layer.presentationLayer).frame.origin.x + self.frame.size.width;
185   - _currentRightX -= _superView.frame.size.width;
186   - break;
187   - }
188   - case DanmuStateFinish: {
189   - _currentRightX = -_superView.frame.size.width;
190   - break;
191   - }
192   - default: {
193   - break;
194   - }
195   - }
196   - return _currentRightX;
197   -}
198   -
199   -#pragma mark -
200   -
201   -- (CGFloat)startTime {
202   - return [[self.info valueForKey:kDanmuTimeKey] floatValue];
203   -}
204   -
205   -- (NSString *)fontSize {
206   - return [self.dicOptional valueForKey: @"s"];
207   -}
208   -
209   -- (NSString *)moveMode {
210   - return [self.dicOptional valueForKey: @"m"];
211   -}
212   -
213   -- (NSString *)position {
214   - return [self.dicOptional valueForKey: @"p"];
215   -}
216   -
217   -- (BOOL)isFontSizeBig {
218   - return [[self fontSize] isEqualToString: DANMU_FONT_SIZE_BIG];
219   -}
220   -
221   -- (BOOL)isFontSizeMiddle {
222   - return [[self fontSize] isEqualToString: DANMU_FONT_SIZE_MIDDLE];
223   -}
224   -
225   -- (BOOL)isFontSizeSmall {
226   - return [[self fontSize] isEqualToString: DANMU_FONT_SIZE_SMALL];
227   -}
228   -
229   -- (BOOL)isMoveModeRolling {
230   - return [[self moveMode] isEqualToString: DANMU_MOVE_MODE_ROLLING];
231   -}
232   -
233   -- (BOOL)isPositionTop {
234   - return [[self position] isEqualToString: DANMU_POSITION_TOP];
235   -}
236   -
237   -- (BOOL)isPositionMiddle {
238   - return [[self position] isEqualToString: DANMU_POSITION_MIDDLE];
239   -}
240   -
241   -- (BOOL)isPositionBottom {
242   - return [[self position] isEqualToString: DANMU_POSITION_BOTTOM];
243   -}
244   -
245   -/*
246   -// Only override drawRect: if you perform custom drawing.
247   -// An empty implementation adversely affects performance during animation.
248   -- (void)drawRect:(CGRect)rect {
249   - // Drawing code
250   -}
251   -*/
252   -
253   -@end
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Danmu/LVCDanmuManager.h deleted 100644 → 0
1   -//
2   -// LVCDanmuManager.h
3   -// LiveVideoCloud
4   -//
5   -// Created by iOS on 17/3/28.
6   -// Copyright © 2017年 cnlive. All rights reserved.
7   -//
8   -
9   -#import <Foundation/Foundation.h>
10   -#import <UIKit/UIKit.h>
11   -#import "LVCDanmuUtil.h"
12   -
13   -/**
14   - * 弹幕状态
15   - */
16   -typedef NS_ENUM(NSUInteger, DanmuManagerState) {
17   - /**
18   - * 弹幕准备
19   - */
20   - DanmuManagerStateWait = 1,
21   - /**
22   - * 弹幕关闭
23   - */
24   - DanmuManagerStateStop,
25   - /**
26   - * 弹幕运动
27   - */
28   - DanmuManagerStateAnimationing,
29   - /**
30   - * 弹幕暂停
31   - */
32   - DanmuManagerStatePause
33   -};
34   -
35   -@interface LVCDanmuManager : NSObject
36   -
37   -/**
38   - * 弹幕添加的UIView
39   - */
40   -@property (nonatomic, strong, readonly) UIView *danmuView;
41   -/**
42   - * 弹幕状态
43   - */
44   -@property (nonatomic, readonly) DanmuManagerState danmuManagerState;
45   -/**
46   - * 创建弹幕管理对象
47   - *
48   - * @param frame 弹幕显示的frame
49   - * @param infos 弹幕信息,数组集合
50   - * @param view 弹幕添加的UIView
51   - * @param time 弹幕刷新的间隔时间,一般1秒
52   - *
53   - * @return
54   - */
55   -- (instancetype)initWithFrame:(CGRect)frame data:(NSArray *)infos inView:(UIView *)view durationTime:(NSUInteger)time;
56   -/**
57   - * 弹幕初始化创建
58   - */
59   -- (void)initStart;
60   -/**
61   - * 弹幕滚动
62   - *
63   - * @param startTime 目前的时间点
64   - */
65   -- (void)rollDanmu:(NSTimeInterval)startTime;
66   -/**
67   - * 弹幕关闭
68   - */
69   -- (void)stop;
70   -/**
71   - * 弹幕暂停
72   - */
73   -- (void)pause;
74   -/**
75   - * 弹幕继续
76   - *
77   - * @param nowTime 现在的时间点
78   - */
79   -- (void)resume:(NSTimeInterval)nowTime;
80   -/**
81   - * 弹幕重新恢复
82   - */
83   -- (void)restart;
84   -/**
85   - * 发射弹幕
86   - *
87   - * @param info 弹幕信息,字典集合
88   - */
89   -- (void)insertDanmu:(NSDictionary *)info;
90   -/**
91   - * 重置弹幕
92   - *
93   - * @param frame 弹幕显示的frame
94   - * @param infos 弹幕信息,数组集合
95   - * @param view 弹幕添加的UIView
96   - * @param time 弹幕刷新的间隔时间,一般1秒
97   - */
98   -- (void)resetDanmuWithFrame:(CGRect)frame data:(NSArray *)infos inView:(UIView *)view durationTime:(NSUInteger)time;
99   -/**
100   - * 重置弹幕
101   - *
102   - * @param frame 弹幕显示的frame
103   - */
104   -- (void)resetDanmuWithFrame:(CGRect)frame;
105   -
106   -
107   -@end
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Danmu/LVCDanmuManager.m deleted 100644 → 0
1   -//
2   -// LVCDanmuManager.m
3   -// LiveVideoCloud
4   -//
5   -// Created by iOS on 17/3/28.
6   -// Copyright © 2017年 cnlive. All rights reserved.
7   -//
8   -
9   -#import "LVCDanmuManager.h"
10   -
11   -#import "LVCDanmuLabel.h"
12   -#import "LVCDanmuView.h"
13   -
14   -#define CHANNEL_WIDTH_MAX 120
15   -#define CHANNEL_SPACE 10
16   -
17   -struct DanmuPositionStruct {
18   - NSInteger start;
19   - NSInteger length;
20   -};
21   -typedef struct DanmuPositionStruct DanmuPositionStruct;
22   -
23   -@interface LVCDanmuManager ()
24   -
25   -@property (nonatomic, strong, readwrite) UIView *danmuView;
26   -@property (nonatomic, readwrite) DanmuManagerState danmuManagerState;
27   -
28   -@property (nonatomic) CGRect frame;
29   -@property (nonatomic, strong) NSArray *infos;
30   -@property (nonatomic, weak) UIView *superView;
31   -@property (nonatomic) NSUInteger durationTime;//添加弹幕的间隔时间
32   -@property (nonatomic) NSUInteger currentIndex;
33   -
34   -@property (nonatomic, strong) NSMutableArray *arRollChannelInfo;
35   -@property (nonatomic) NSUInteger countChannel;
36   -
37   -@property (nonatomic) DanmuPositionStruct upPosition;
38   -@property (nonatomic) DanmuPositionStruct middlePosition;
39   -@property (nonatomic) DanmuPositionStruct downPosition;
40   -
41   -@end
42   -
43   -@implementation LVCDanmuManager
44   -
45   -- (void)dealloc {
46   - _infos = nil;
47   - _danmuView = nil;
48   - _arRollChannelInfo = nil;
49   -}
50   -
51   -- (instancetype)initWithFrame:(CGRect)frame data:(NSArray *)infos inView:(UIView *)view durationTime:(NSUInteger)time {
52   - self = [super init];
53   - if (self) {
54   - self.frame = frame;
55   - self.infos = infos;
56   - self.superView = view;
57   - self.durationTime = time;
58   -
59   - [self p_initInfo];
60   - }
61   - return self;
62   -}
63   -
64   -#pragma mark - Private
65   -
66   -- (void)p_initInfo {
67   - _countChannel = self.frame.size.height/CHANNEL_HEIGHT;
68   -
69   - self.arRollChannelInfo = [NSMutableArray arrayWithCapacity:_countChannel];
70   -
71   - NSUInteger sectionLines = nearbyintf((CGFloat)_countChannel / 3);
72   - NSUInteger firstLines = MAX(_countChannel - sectionLines*2, sectionLines);
73   - //滚动航道布局
74   - //上中下,假设10,上:0-3,中:4-6,下:7-9
75   - _upPosition = (DanmuPositionStruct){0, firstLines};
76   - _middlePosition = (DanmuPositionStruct){_upPosition.length, sectionLines};
77   - _downPosition = (DanmuPositionStruct){_middlePosition.start + _middlePosition.length, _countChannel - _middlePosition.start - _middlePosition.length};
78   -
79   - _danmuManagerState = DanmuManagerStateWait;
80   -}
81   -
82   -- (void)p_initData {
83   - [self.arRollChannelInfo removeAllObjects];
84   -
85   - for (int i = 0; i < _countChannel; i++) {
86   - [self.arRollChannelInfo addObject:[NSNumber numberWithInt:i]];
87   - }
88   -
89   - self.currentIndex = 0;
90   - [self.danmuView removeFromSuperview];
91   - self.danmuView = nil;
92   - self.danmuView = [[LVCDanmuView alloc] initWithFrame:_frame];
93   - [self.superView addSubview:self.danmuView];
94   -
95   - _danmuManagerState = DanmuManagerStateWait;
96   -}
97   -
98   -- (void)p_danmu:(NSTimeInterval)startTime {
99   - __weak typeof(self) weakSelf = self;
100   -
101   - __block NSMutableArray *danmuInfos = [NSMutableArray new];
102   - __block NSUInteger index = 0;
103   -
104   - for (int i = (int)self.currentIndex; i < self.infos.count; i++) {
105   - NSDictionary *obj = [self.infos objectAtIndex:i];
106   - CGFloat time = [[obj objectForKey:kDanmuTimeKey] floatValue];
107   - if (time >= startTime && time < startTime + weakSelf.durationTime) {
108   - [danmuInfos addObject:obj];
109   - }
110   - if (time >= startTime + weakSelf.durationTime) {
111   - index = i;
112   - break;
113   - }
114   - }
115   -
116   - if (danmuInfos.count > 0) {
117   - self.currentIndex = index;
118   -
119   - void(^func)(LVCDanmuLabel *danmuLabel, NSUInteger idx, CGFloat offsetXY) = ^(LVCDanmuLabel *danmuLabel, NSUInteger idx, CGFloat offsetXY){
120   - if (idx != NSNotFound) {
121   - [danmuLabel setDanmuChannel:idx offset:offsetXY];
122   - CGFloat time = [danmuLabel startTime];
123   - time = time - startTime;
124   - [danmuLabel animationDanmuItem:time];
125   - }
126   - };
127   -
128   - [danmuInfos enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) {
129   - __block LVCDanmuLabel *danmuLabel = [LVCDanmuLabel createWithInfo:obj inView:weakSelf.danmuView];
130   - [weakSelf p_getRollBestChannel:danmuLabel completion:^(NSUInteger idx, CGFloat offsetX) {
131   - func(danmuLabel, idx, offsetX);
132   - }];
133   - }];
134   - }
135   -}
136   -
137   -- (void)p_getRollBestChannel:(LVCDanmuLabel *)newDanmuL completion:(void(^)(NSUInteger idx, CGFloat offsetX))completion {
138   - DanmuPositionStruct danmuPosition;
139   - if (newDanmuL.isPositionMiddle) {
140   - danmuPosition = _middlePosition;
141   - }
142   - else if (newDanmuL.isPositionBottom) {
143   - danmuPosition = _downPosition;
144   - }
145   - else {
146   - danmuPosition = _upPosition;
147   - }
148   -
149   - NSUInteger index = danmuPosition.start;
150   - BOOL bFind = NO;
151   - for (int i = (int)danmuPosition.start; i < danmuPosition.start + danmuPosition.length; i++) {
152   - id obj = [self.arRollChannelInfo objectAtIndex:i];
153   - index = i;
154   - if ([obj isKindOfClass:[LVCDanmuLabel class]]) {
155   - bFind = [self p_last:obj new:newDanmuL];
156   - }else {
157   - bFind = YES;
158   - }
159   -
160   - if (bFind)
161   - break;
162   - }
163   -
164   - if (bFind) {
165   - id obj = [self.arRollChannelInfo objectAtIndex:index];
166   - [self.arRollChannelInfo replaceObjectAtIndex:index withObject:newDanmuL];
167   - if ([obj isKindOfClass:[LVCDanmuLabel class]]) {
168   - CGFloat x = ((LVCDanmuLabel *)obj).currentRightX;
169   - completion(index, x < 0 ? 0 : x);
170   - }else
171   - completion(index, 0);
172   - }else {
173   - if (index < danmuPosition.start + danmuPosition.length - 1) {
174   - index += 1;
175   - [self.arRollChannelInfo replaceObjectAtIndex:index withObject:newDanmuL];
176   - completion(index, 0);
177   - }
178   - else {
179   - NSUInteger index = NSNotFound;
180   - index = [self p_allChannelWithPosition:danmuPosition new:newDanmuL];
181   - if (index != NSNotFound) {
182   - LVCDanmuLabel *obj = [self.arRollChannelInfo objectAtIndex:index];
183   - [self.arRollChannelInfo replaceObjectAtIndex:index withObject:newDanmuL];
184   - CGFloat x = obj.currentRightX;
185   - completion(index, x < CHANNEL_SPACE ? CHANNEL_SPACE : x);
186   - }else
187   - completion(NSNotFound, 0);
188   - }
189   - }
190   -}
191   -
192   -//选择完全不会碰撞的航道
193   -- (BOOL)p_last:(LVCDanmuLabel *)lastDanmuL new:(LVCDanmuLabel *)newDanmuL {
194   - CGFloat durationTime = newDanmuL.startTime - lastDanmuL.startTime;
195   - if (durationTime > newDanmuL.animationDuartion) {
196   - return YES;
197   - }
198   - CGFloat timeS = lastDanmuL.frame.size.width/lastDanmuL.speed;
199   - if (timeS >= durationTime) {
200   - return NO;
201   - }
202   - CGFloat timeE = newDanmuL.currentRightX/newDanmuL.speed;
203   - if (timeE <= durationTime) {
204   - return NO;
205   - }
206   -
207   - return YES;
208   -}
209   -
210   -//选择在不超出缓冲区的且缓冲区最长的航道
211   -- (NSUInteger)p_allChannelWithPosition:(DanmuPositionStruct)danmuPosition new:(LVCDanmuLabel *)newDanmuL {
212   - CGFloat width = CHANNEL_WIDTH_MAX;
213   - NSUInteger index = NSNotFound;
214   - for (int i = (int)danmuPosition.start; i < danmuPosition.start + danmuPosition.length; i++) {id obj = [self.arRollChannelInfo objectAtIndex:i];
215   - if ([obj isKindOfClass:[LVCDanmuLabel class]]) {
216   - CGFloat rightX = ((LVCDanmuLabel *)obj).currentRightX;
217   - if (rightX <= CHANNEL_WIDTH_MAX) {
218   - CGFloat xx = rightX;
219   - if (xx < width) {
220   - width = xx;
221   - index = i;
222   - }
223   - }
224   - }
225   - }
226   -
227   - return index;
228   -}
229   -
230   -- (NSUInteger)p_arDanmuLabel:(NSMutableArray *)arDanmuLs position:(DanmuPositionStruct)danmuPosition new:(LVCDanmuLabel *)newDanmuL {
231   - BOOL bFind = NO;
232   - NSUInteger index = danmuPosition.start;
233   - for (int i = (int)danmuPosition.start; i < danmuPosition.start + danmuPosition.length; i++) {
234   - id obj = [arDanmuLs objectAtIndex:i];
235   - index = i;
236   - if ([obj isKindOfClass:[LVCDanmuLabel class]]) {
237   - LVCDanmuLabel *lastDanmuL = obj;
238   - CGFloat durationTime = newDanmuL.startTime - lastDanmuL.startTime;
239   - bFind = (durationTime > (newDanmuL.animationDuartion - 1));
240   - }else {
241   - bFind = YES;
242   - }
243   -
244   - if (bFind)
245   - break;
246   - }
247   - if (!bFind) {
248   - if (index < danmuPosition.start + danmuPosition.length - 1)
249   - index += 1;
250   - else
251   - index = NSNotFound;
252   - }
253   -
254   - return index;
255   -}
256   -
257   -#pragma mark - Action
258   -
259   -- (void)initStart {
260   - if (_danmuManagerState == DanmuManagerStateWait ||
261   - _danmuManagerState == DanmuManagerStateStop) {
262   - [self p_initData];
263   - }
264   -}
265   -
266   -- (void)rollDanmu:(NSTimeInterval)startTime {
267   - if (_danmuManagerState == DanmuManagerStateStop)
268   - return;
269   - if (_danmuManagerState != DanmuManagerStateAnimationing)
270   - _danmuManagerState = DanmuManagerStateAnimationing;
271   -
272   - if ((NSInteger)startTime % _durationTime == 0) {
273   - [self p_danmu:startTime];
274   - }
275   -}
276   -
277   -- (void)stop {
278   - _danmuManagerState = DanmuManagerStateStop;
279   - [self.arRollChannelInfo removeAllObjects];
280   - [self.danmuView.subviews makeObjectsPerformSelector:@selector(removeDanmu)];
281   - [self.danmuView removeFromSuperview];
282   -}
283   -
284   -- (void)pause {
285   - if (_danmuManagerState != DanmuManagerStateAnimationing)
286   - return;
287   - _danmuManagerState = DanmuManagerStatePause;
288   - [self.danmuView.subviews makeObjectsPerformSelector:@selector(pause)];
289   -}
290   -
291   -- (void)resume:(NSTimeInterval)nowTime {
292   - if (_danmuManagerState != DanmuManagerStatePause)
293   - return;
294   - _danmuManagerState = DanmuManagerStateAnimationing;
295   - for (id subview in self.danmuView.subviews) {
296   - if ([subview isKindOfClass:[LVCDanmuLabel class]]) {
297   - [(LVCDanmuLabel *)subview resume:nowTime];
298   - }
299   - }
300   -}
301   -
302   -- (void)restart {
303   - [self p_initData];
304   - _danmuManagerState = DanmuManagerStateAnimationing;
305   -}
306   -
307   -- (void)insertDanmu:(NSDictionary *)info {
308   - __block LVCDanmuLabel *danmuLabel = [LVCDanmuLabel createWithInfo:info inView:self.danmuView];
309   - [self p_getRollBestChannel:danmuLabel completion:^(NSUInteger idx, CGFloat offsetX) {
310   - if (idx != NSNotFound) {
311   - [danmuLabel setDanmuChannel:idx offset:offsetX];
312   - }
313   - }];
314   -}
315   -
316   -- (void)resetDanmuWithFrame:(CGRect)frame data:(NSArray *)infos inView:(UIView *)view durationTime:(NSUInteger)time {
317   - self.frame = frame;
318   - if (infos != nil)
319   - self.infos = infos;
320   - self.superView = view;
321   - self.durationTime = time;
322   -
323   - [self p_initInfo];
324   -}
325   -
326   -- (void)resetDanmuWithFrame:(CGRect)frame {
327   - self.frame = frame;
328   - [self p_initInfo];
329   -}
330   -
331   -
332   -@end
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Danmu/LVCDanmuUtil.h deleted 100644 → 0
1   -//
2   -// LVCDanmuUtil.h
3   -// LiveVideoCloud
4   -//
5   -// Created by iOS on 17/3/28.
6   -// Copyright © 2017年 cnlive. All rights reserved.
7   -//
8   -
9   -#import <Foundation/Foundation.h>
10   -#import <UIKit/UIKit.h>
11   -
12   -typedef NS_ENUM(NSUInteger, DanmuState) {
13   - DanmuStateStop = 1,
14   - DanmuStateAnimationing,
15   - DanmuStateFinish
16   -};
17   -
18   -#define CHANNEL_HEIGHT 25
19   -
20   -extern NSString * const kDanmuContentKey; //弹幕内容
21   -extern NSString * const kDanmuTimeKey; //视频时间
22   -extern NSString * const kDanmuOptionalKey; //弹幕样式
23   -
24   -@interface LVCDanmuUtil : NSObject
25   -
26   -+ (CGSize)getSizeWithString:(NSString *)str withFont:(UIFont *)font size:(CGSize)size;
27   -
28   -+ (UIColor *)colorFromARGB:(int)argb;
29   -
30   -+ (NSDictionary *)defaultOptions;
31   -
32   -+ (NSDictionary *)randomOptions;
33   -
34   -+ (BOOL)isOrientationLandscape;
35   -
36   -@end
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Danmu/LVCDanmuUtil.m deleted 100644 → 0
1   -//
2   -// LVCDanmuUtil.m
3   -// LiveVideoCloud
4   -//
5   -// Created by iOS on 17/3/28.
6   -// Copyright © 2017年 cnlive. All rights reserved.
7   -//
8   -
9   -#import "LVCDanmuUtil.h"
10   -
11   -NSString * const kDanmuContentKey = @"c";
12   -NSString * const kDanmuTimeKey = @"v";
13   -NSString * const kDanmuOptionalKey = @"t";
14   -
15   -@implementation LVCDanmuUtil
16   -
17   -+ (CGSize)getSizeWithString:(NSString *)str withFont:(UIFont *)font size:(CGSize)size {
18   - CGRect stringRect = [str boundingRectWithSize:size
19   - options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
20   - attributes:@{ NSFontAttributeName : font }
21   - context:nil];
22   -
23   - return stringRect.size;
24   -}
25   -
26   -+ (UIColor *)colorFromARGB:(int)argb {
27   - int blue = argb & 0xff;
28   - int green = argb >> 8 & 0xff;
29   - int red = argb >> 16 & 0xff;
30   - //int alpha = argb >> 24 & 0xff;
31   - //NSLog(@"%i, %i, %i", red, green, blue);
32   - return [UIColor colorWithRed:red/255.f green:green/255.f blue:blue/255.f alpha: 1];
33   -}
34   -
35   -+ (long)argbFromHex:(NSString *)hex
36   -{
37   - const char *cStr = [hex cStringUsingEncoding:NSASCIIStringEncoding];
38   - long x = strtol(cStr + 1, NULL, 16);
39   - return x;
40   - // return [self colorFromARGB: (int)x];
41   -}
42   -
43   -+ (NSDictionary *)defaultOptions {
44   - return @{@"c": [NSNumber numberWithLong:[LVCDanmuUtil argbFromHex: @"#ffffff"]],
45   - @"m": @"l",
46   - @"p": @"t",
47   - @"s": @"m",
48   - @"l": @"n"
49   - };
50   -}
51   -
52   -+ (NSDictionary *)randomOptions {
53   - NSUInteger c = arc4random_uniform(4);
54   - NSArray *arColor = @[@"#ffffff", @"#ff0000", @"#00ff00", @"#0000ff"];
55   - NSUInteger s = arc4random_uniform(3);
56   - NSArray *arFontSize = @[@"l", @"m", @"s"];
57   - NSUInteger m = arc4random_uniform(4);
58   - NSArray *arMode = @[@"l", @"f", @"l", @"l"];
59   - return @{@"c": [NSNumber numberWithLong:[LVCDanmuUtil argbFromHex:arColor[c]]],
60   - @"m": arMode[m],
61   - @"p": @"t",
62   - @"s": arFontSize[s],
63   - @"l": @"n"
64   - };
65   -}
66   -
67   -+ (BOOL)isOrientationLandscape {
68   - //if (UIDeviceOrientationIsLandscape([[UIDevice currentDevice] orientation])) {
69   - if (UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
70   - return YES;
71   - } else {
72   - return NO;
73   - }
74   -}
75   -
76   -@end
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Danmu/LVCDanmuView.h deleted 100644 → 0
1   -//
2   -// LVCDanmuView.h
3   -// LiveVideoCloud
4   -//
5   -// Created by iOS on 17/3/28.
6   -// Copyright © 2017年 cnlive. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -@interface LVCDanmuView : UIView
12   -
13   -@end
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Danmu/LVCDanmuView.m deleted 100644 → 0
1   -//
2   -// LVCDanmuView.m
3   -// LiveVideoCloud
4   -//
5   -// Created by iOS on 17/3/28.
6   -// Copyright © 2017年 cnlive. All rights reserved.
7   -//
8   -
9   -#import "LVCDanmuView.h"
10   -
11   -@implementation LVCDanmuView
12   -
13   -- (instancetype)initWithFrame:(CGRect)frame {
14   - self = [super initWithFrame:frame];
15   - if (self) {
16   - self.backgroundColor = [UIColor clearColor];
17   - self.clipsToBounds = YES;
18   - }
19   - return self;
20   -}
21   -
22   -/*
23   -// Only override drawRect: if you perform custom drawing.
24   -// An empty implementation adversely affects performance during animation.
25   -- (void)drawRect:(CGRect)rect {
26   - // Drawing code
27   -}
28   -*/
29   -
30   -@end
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/LVCPlayer.h
... ... @@ -7,6 +7,7 @@
7 7 //
8 8  
9 9 #import <UIKit/UIKit.h>
  10 +#import "LVCChannelDetailsModel.h"
10 11  
11 12 @class LVCPlayer;
12 13  
... ... @@ -14,9 +15,10 @@
14 15  
15 16 @optional
16 17  
17   -- (void)lvcPlayer:(LVCPlayer *)player clickedBackBtn:(UIButton *)backBtn; //返回
18   -- (void)lvcPlayer:(LVCPlayer *)player clickedFullScreenBtn:(UIButton *)fullScreenBtn; //全屏
19   -- (void)lvcPlayer:(LVCPlayer *)player clickedEditBtn:(UIButton *)editBtn; //全屏编辑按钮
  18 +- (void)lvcPlayer:(LVCPlayer *)player clickedBackBtn:(UIButton *)backBtn; //返回
  19 +- (void)lvcPlayer:(LVCPlayer *)player clickedFullScreenBtn:(UIButton *)fullScreenBtn; //全屏
  20 +- (void)lvcPlayer:(LVCPlayer *)player clickedEditBtn:(UIButton *)editBtn; //全屏编辑按钮
  21 +- (void)lvcPlayer:(LVCPlayer *)player barrageSwitch:(BOOL)on; //弹幕开关
20 22  
21 23 @end
22 24  
... ... @@ -26,11 +28,15 @@ typedef void(^HideInputViewBlock)(BOOL hide);
26 28  
27 29 @property (nonatomic, strong) UIImageView *topBgView; //顶部蒙版
28 30 @property (nonatomic, strong) UIImageView *bottomBgView; //底部蒙版
  31 +@property (nonatomic, strong) UIImageView *contentView; //所有空间统一管理在这个view中
  32 +@property (nonatomic, strong) LVCChannelDetailsModel *model; //所有空间统一管理在这个view中
29 33 @property (nonatomic, readwrite, assign) BOOL isFullScreen; //是否是全屏
30 34 @property (nonatomic, copy) HideInputViewBlock hideBlock; //全屏模式下是否隐藏输入框
31   -
  35 +@property (nonatomic, assign, readonly) BOOL displayBarrage; //是否显示弹幕
32 36 @property (nonatomic, assign) id<LVCPlayerDelegate> delegate;
33 37  
  38 +- (instancetype)initWithFrame:(CGRect)frame playerModel:(LVCChannelDetailsModel *)model;
  39 +
34 40 - (void)autoHideControlView; //自动隐藏上下功能条
35 41  
36 42 - (void)stopPlaying; //停止播放
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/LVCPlayer.m
... ... @@ -10,14 +10,9 @@
10 10 #import "LVCPlayerLoadingView.h"
11 11 #import "SevenSwitch.h"
12 12  
13   -#define kAppId @"60_irn9edco29"
14   -#define kAppKey @"69fe70bda67e059286ad509d9f5377f815955645b52f94"
15   -#define kbundleId @"com.cnlive.zhangxu.LiveVideoCloud"
16   -
17 13 @interface LVCPlayer ()<UIGestureRecognizerDelegate>
18 14  
19 15 @property (nonatomic, strong) UIButton *backBtn; //返回
20   -@property (nonatomic, strong) UIImageView *contentView; //所有空间统一管理在这个view中
21 16 @property (nonatomic, strong) UIButton *playOrPauseBtn; //播放/暂停
22 17 @property (nonatomic, strong) UILabel *titleLab; //标题
23 18 @property (nonatomic, strong) UIButton *fullScreenBtn; //控制全屏按钮
... ... @@ -32,12 +27,12 @@
32 27  
33 28 @implementation LVCPlayer
34 29  
35   -- (instancetype)initWithFrame:(CGRect)frame
  30 +- (instancetype)initWithFrame:(CGRect)frame playerModel:(LVCChannelDetailsModel *)model
36 31 {
37 32 self = [super initWithFrame:frame];
38 33 if (self) {
39 34  
40   - [self initPlayer];
  35 + [self initPlayerWithModel:model];
41 36  
42 37 [self addSubview:self.contentView];
43 38 [self.contentView addSubview:self.bottomBgView];
... ... @@ -58,27 +53,44 @@
58 53 }
59 54 #pragma mark -
60 55 #pragma mark - initPlayer
61   -- (void)initPlayer
62   -{
63   - [[CNLiveWebcastManager manager] initWithAppId:kAppId appKey:kAppKey];
64   - //点播播放
65   - _player = [[CNLiveMoviePlayerController alloc] initVodPlayWithVId:@"aaa123"
66   - authSuccess:^{
67   -
68   - [self addObservers];
69   - _player.videoDecoderMode = CNLiveMovieVideoDecoderMode_AUTO;
70   - _player.shouldAutoplay = YES;
71   - [_player prepareToPlay];
72   - [self.contentView addSubview:_player.view];
73   - [self.contentView sendSubviewToBack:_player.view];
74   -
75   - [self makePlayerConstraint];
76   -
77   -
78   - } authFailed:^(NSDictionary *errorInfo) {
79   - NSLog(@"初始化点播播放器失败%@", errorInfo);
  56 +- (void)initPlayerWithModel:(LVCChannelDetailsModel *)model
  57 +{
  58 + /*
  59 + */
  60 + _player = [[CNLiveMoviePlayerController alloc] initLivePlayWithChannelId:model.mediaId authSuccess:^{
  61 + [self addObservers];
  62 + _player.videoDecoderMode = CNLiveMovieVideoDecoderMode_AUTO;
  63 + _player.shouldAutoplay = YES;
  64 + [_player prepareToPlay];
  65 + [self.contentView addSubview:_player.view];
  66 + [self.contentView sendSubviewToBack:_player.view];
  67 +
  68 + [self makePlayerConstraint];
80 69  
81   - }];
  70 + } authFailed:^(NSDictionary *errorInfo) {
  71 + NSLog(@"初始化点播播放器失败%@", errorInfo);
  72 + } getAnchorStatusResult:NULL];
  73 +
  74 + /*
  75 + //点播播放
  76 + _player = [[CNLiveMoviePlayerController alloc] initVodPlayWithVId:@"aaa123"
  77 + authSuccess:^{
  78 +
  79 + [self addObservers];
  80 + _player.videoDecoderMode = CNLiveMovieVideoDecoderMode_AUTO;
  81 + _player.shouldAutoplay = YES;
  82 + [_player prepareToPlay];
  83 + [self.contentView addSubview:_player.view];
  84 + [self.contentView sendSubviewToBack:_player.view];
  85 +
  86 + [self makePlayerConstraint];
  87 +
  88 +
  89 + } authFailed:^(NSDictionary *errorInfo) {
  90 + NSLog(@"初始化点播播放器失败%@", errorInfo);
  91 +
  92 + }];
  93 + */
82 94 }
83 95  
84 96 #pragma mark -
... ... @@ -112,9 +124,12 @@
112 124  
113 125 - (void)barrageSwitchAction
114 126 {
115   - NSString *string = self.barrageSwitch.on ? @"已开启弹幕" : @"已关闭弹幕";
  127 + self.editBtn.hidden =! self.barrageSwitch.on;
  128 +
  129 + if (self.delegate && [self.delegate respondsToSelector:@selector(lvcPlayer:barrageSwitch:)]) {
  130 + [self.delegate lvcPlayer:self barrageSwitch:_barrageSwitch.on];
  131 + }
116 132  
117   - NSLog(@"%@",string);
118 133 }
119 134  
120 135 - (void)editBtnAction:(UIButton *)btn
... ... @@ -483,6 +498,11 @@
483 498 #pragma mark -
484 499 #pragma mark - getter
485 500  
  501 +- (BOOL)displayBarrage
  502 +{
  503 + return _barrageSwitch.on;
  504 +}
  505 +
486 506 - (UIImageView *)contentView
487 507 {
488 508 if (!_contentView) {
... ...
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/LVCTelevisionView.m
... ... @@ -13,6 +13,7 @@
13 13 #import "LVCChannelDetailsModel.h"
14 14 #import "LVCChannelsModel.h"
15 15 #import "LVCBannerModel.h"
  16 +#import "LVCLivePlayerController.h"
16 17  
17 18 static NSString *cellId = @"LVCLiveListCollectionViewCell";
18 19 static NSString *firstHeaderId = @"LVCFirstHeaderReusableView";
... ... @@ -186,8 +187,15 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;;
186 187 #pragma mark -
187 188 #pragma mark - UICollectionViewDelegate
188 189 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
189   - NSLog(@"跳转-----");
190 190  
  191 + LVCChannelsModel *model = _channelsModelArray[indexPath.section - 1];
  192 + LVCChannelDetailsModel *details = model.programs[indexPath.item];
  193 + self.viewController.hidesBottomBarWhenPushed = YES;
  194 +
  195 + LVCLivePlayerController *playVC = [[LVCLivePlayerController alloc] init];
  196 + playVC.model = details;
  197 + self.viewController.navigationController.navigationBar.hidden = YES;
  198 + [self.viewController.navigationController pushViewController:playVC animated:YES];
191 199 }
192 200  
193 201 #pragma mark -
... ... @@ -213,8 +221,7 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;;
213 221  
214 222 NSMutableArray *arrayM = [[NSMutableArray alloc]init];
215 223 for (NSDictionary *dict in responseObject[@"channels"]) {
216   - LVCChannelsModel *model = [LVCChannelsModel new];
217   - [model setValuesForKeysWithDictionary:dict];
  224 + LVCChannelsModel *model = [LVCChannelsModel mj_objectWithKeyValues:dict];
218 225 [arrayM addObject:model];
219 226 }
220 227 self.channelsModelArray = arrayM;
... ... @@ -223,8 +230,7 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;;
223 230  
224 231 NSMutableArray *arrayM = [NSMutableArray array];
225 232 for (NSDictionary *dict in responseObject[@"banner"]) {
226   - LVCBannerModel *rollModel = [LVCBannerModel new];
227   - [rollModel setValuesForKeysWithDictionary:dict];
  233 + LVCBannerModel *rollModel = [LVCBannerModel mj_objectWithKeyValues:dict];
228 234 [arrayM addObject:rollModel];
229 235 }
230 236 self.bannerModelArray = arrayM;
... ...
LiveVideoCloud/LiveVideoCloud/Info.plist
... ... @@ -2,19 +2,8 @@
2 2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 3 <plist version="1.0">
4 4 <dict>
5   - <key>UIViewControllerBasedStatusBarAppearance</key>
6   - <false/>
7 5 <key>CFBundleDevelopmentRegion</key>
8 6 <string>en</string>
9   - <key>NSAppTransportSecurity</key>
10   - <dict>
11   - <key>NSAllowsArbitraryLoads</key>
12   - <true/>
13   - </dict>
14   - <key>NSCameraUsageDescription</key>
15   - <string></string>
16   - <key>NSMicrophoneUsageDescription</key>
17   - <string></string>
18 7 <key>CFBundleExecutable</key>
19 8 <string>$(EXECUTABLE_NAME)</string>
20 9 <key>CFBundleIdentifier</key>
... ... @@ -59,5 +48,7 @@
59 48 <string>UIInterfaceOrientationLandscapeLeft</string>
60 49 <string>UIInterfaceOrientationLandscapeRight</string>
61 50 </array>
  51 + <key>UIViewControllerBasedStatusBarAppearance</key>
  52 + <false/>
62 53 </dict>
63 54 </plist>
... ...
LiveVideoCloud/LiveVideoCloud/UtilKits/Macro/Macros/AppMacro.h
... ... @@ -13,15 +13,8 @@
13 13 #ifndef AppMacro_h
14 14 #define AppMacro_h
15 15  
16   -#ifdef DEBUG
17   -#define AppId @"3_ix6yg1gl62"
18   -#define AppKey @"d8dd4312037a6aaff83dc4809c027fc9b06847a3f130e5"
19   -#define AppSceret @"78417aa2f74718de7958a0c9632f630904895029755b3e"
20   -#else
21   -#define AppId @"3_iw67pjcd56"
22   -#define AppKey @"0d88fbc8da13dfd434540a89da71cd96dd78d42d4d62c9"
23   -#define AppSceret @"c70a9bb56f2f654b60db64b2a5fa7e92ebd4954b237435"
24   -#endif
25   -
  16 +#define AppId @"60_j0uqrv0u11"
  17 +#define AppKey @"876c5efece0fc9c98c51ff2180ee1bcfa5c5b5af202c78"
  18 +#define AppSceret @"ee844ea67b6be7303b6f5d9365af10ac09933c0828aba7"
26 19  
27 20 #endif /* AppMacro_h */
... ...