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,10 +26,8 @@
26 811BB6851E8106AF005C6291 /* CNLivePlayerSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 811BB6821E8106A2005C6291 /* CNLivePlayerSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 26 811BB6851E8106AF005C6291 /* CNLivePlayerSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 811BB6821E8106A2005C6291 /* CNLivePlayerSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
27 811BB6881E8107B4005C6291 /* LVCChatViewTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 811BB6871E8107B4005C6291 /* LVCChatViewTableViewCell.m */; }; 27 811BB6881E8107B4005C6291 /* LVCChatViewTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 811BB6871E8107B4005C6291 /* LVCChatViewTableViewCell.m */; };
28 811BB68E1E8116C8005C6291 /* NSString+StringSize.m in Sources */ = {isa = PBXBuildFile; fileRef = 811BB68D1E8116C8005C6291 /* NSString+StringSize.m */; }; 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 8130911E1E84C0F0005F0BFF /* LVCMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 8130911D1E84C0F0005F0BFF /* LVCMessage.m */; }; 31 8130911E1E84C0F0005F0BFF /* LVCMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 8130911D1E84C0F0005F0BFF /* LVCMessage.m */; };
34 81A1B9A91E8277410079FF5F /* LVCInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A1B9A81E8277410079FF5F /* LVCInputView.m */; }; 32 81A1B9A91E8277410079FF5F /* LVCInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A1B9A81E8277410079FF5F /* LVCInputView.m */; };
35 81A482F51E88ACC80097A80A /* LVCTelevisionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A482F41E88ACC80097A80A /* LVCTelevisionView.m */; }; 33 81A482F51E88ACC80097A80A /* LVCTelevisionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A482F41E88ACC80097A80A /* LVCTelevisionView.m */; };
@@ -282,14 +280,10 @@ @@ -282,14 +280,10 @@
282 811BB6871E8107B4005C6291 /* LVCChatViewTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCChatViewTableViewCell.m; sourceTree = "<group>"; }; 280 811BB6871E8107B4005C6291 /* LVCChatViewTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCChatViewTableViewCell.m; sourceTree = "<group>"; };
283 811BB68C1E8116C8005C6291 /* NSString+StringSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+StringSize.h"; sourceTree = "<group>"; }; 281 811BB68C1E8116C8005C6291 /* NSString+StringSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+StringSize.h"; sourceTree = "<group>"; };
284 811BB68D1E8116C8005C6291 /* NSString+StringSize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+StringSize.m"; sourceTree = "<group>"; }; 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 8130911C1E84C0F0005F0BFF /* LVCMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCMessage.h; sourceTree = "<group>"; }; 287 8130911C1E84C0F0005F0BFF /* LVCMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCMessage.h; sourceTree = "<group>"; };
294 8130911D1E84C0F0005F0BFF /* LVCMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCMessage.m; sourceTree = "<group>"; }; 288 8130911D1E84C0F0005F0BFF /* LVCMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCMessage.m; sourceTree = "<group>"; };
295 81A1B9A71E8277410079FF5F /* LVCInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCInputView.h; sourceTree = "<group>"; }; 289 81A1B9A71E8277410079FF5F /* LVCInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCInputView.h; sourceTree = "<group>"; };
@@ -725,19 +719,15 @@ @@ -725,19 +719,15 @@
725 path = ../ChatView; 719 path = ../ChatView;
726 sourceTree = "<group>"; 720 sourceTree = "<group>";
727 }; 721 };
728 - 8128E26B1E8A3AD400B40E75 /* Danmu */ = { 722 + 8128E2831E8A6A3600B40E75 /* Barrage */ = {
729 isa = PBXGroup; 723 isa = PBXGroup;
730 children = ( 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 sourceTree = "<group>"; 731 sourceTree = "<group>";
742 }; 732 };
743 812E504E1E7699B9004F5FCD /* CNLiveSDK */ = { 733 812E504E1E7699B9004F5FCD /* CNLiveSDK */ = {
@@ -1667,7 +1657,7 @@ @@ -1667,7 +1657,7 @@
1667 D2888DAA1E6EC014003A77C8 /* View */ = { 1657 D2888DAA1E6EC014003A77C8 /* View */ = {
1668 isa = PBXGroup; 1658 isa = PBXGroup;
1669 children = ( 1659 children = (
1670 - 8128E26B1E8A3AD400B40E75 /* Danmu */, 1660 + 8128E2831E8A6A3600B40E75 /* Barrage */,
1671 811BB67B1E80F858005C6291 /* ChatView */, 1661 811BB67B1E80F858005C6291 /* ChatView */,
1672 810B64DE1E779AE900133E15 /* LVCPlayer.h */, 1662 810B64DE1E779AE900133E15 /* LVCPlayer.h */,
1673 810B64DF1E779AE900133E15 /* LVCPlayer.m */, 1663 810B64DF1E779AE900133E15 /* LVCPlayer.m */,
@@ -1922,7 +1912,6 @@ @@ -1922,7 +1912,6 @@
1922 D2029D011E6EAE2E0027CD92 /* UIColor+HexString.m in Sources */, 1912 D2029D011E6EAE2E0027CD92 /* UIColor+HexString.m in Sources */,
1923 D2029CA41E6EADE10027CD92 /* MJRefreshComponent.m in Sources */, 1913 D2029CA41E6EADE10027CD92 /* MJRefreshComponent.m in Sources */,
1924 D2575C7A1E76A4F300E3A8FC /* NHCarViews.m in Sources */, 1914 D2575C7A1E76A4F300E3A8FC /* NHCarViews.m in Sources */,
1925 - 8128E26E1E8A3AFE00B40E75 /* LVCDanmuUtil.m in Sources */,  
1926 D2029CBC1E6EADE10027CD92 /* SDWebImageDownloaderOperation.m in Sources */, 1915 D2029CBC1E6EADE10027CD92 /* SDWebImageDownloaderOperation.m in Sources */,
1927 D2029CA51E6EADE10027CD92 /* MJRefreshFooter.m in Sources */, 1916 D2029CA51E6EADE10027CD92 /* MJRefreshFooter.m in Sources */,
1928 D22830FC1E77C2D900627701 /* BottomToolView.m in Sources */, 1917 D22830FC1E77C2D900627701 /* BottomToolView.m in Sources */,
@@ -1933,6 +1922,7 @@ @@ -1933,6 +1922,7 @@
1933 D2029CD01E6EADE10027CD92 /* SearchPresenter.m in Sources */, 1922 D2029CD01E6EADE10027CD92 /* SearchPresenter.m in Sources */,
1934 D2888DB71E6EC1B8003A77C8 /* LVCMyViewController.m in Sources */, 1923 D2888DB71E6EC1B8003A77C8 /* LVCMyViewController.m in Sources */,
1935 D2029CBE1E6EADE10027CD92 /* SDWebImagePrefetcher.m in Sources */, 1924 D2029CBE1E6EADE10027CD92 /* SDWebImagePrefetcher.m in Sources */,
  1925 + 8128E2891E8A6A3600B40E75 /* CNBarrageView.m in Sources */,
1936 D2A803081E80BD6F009D6F1C /* TopToolView.m in Sources */, 1926 D2A803081E80BD6F009D6F1C /* TopToolView.m in Sources */,
1937 D2B7B2571E8261EF00ED084E /* ChatBarrOperation.m in Sources */, 1927 D2B7B2571E8261EF00ED084E /* ChatBarrOperation.m in Sources */,
1938 810B65011E779B1F00133E15 /* MASLayoutConstraint.m in Sources */, 1928 810B65011E779B1F00133E15 /* MASLayoutConstraint.m in Sources */,
@@ -1970,6 +1960,7 @@ @@ -1970,6 +1960,7 @@
1970 D2029CB61E6EADE10027CD92 /* MKAnnotationView+WebCache.m in Sources */, 1960 D2029CB61E6EADE10027CD92 /* MKAnnotationView+WebCache.m in Sources */,
1971 D2B2ED801E88FC5200F7538A /* LVCUGCLiveEndView.m in Sources */, 1961 D2B2ED801E88FC5200F7538A /* LVCUGCLiveEndView.m in Sources */,
1972 810B64FE1E779B1F00133E15 /* MASCompositeConstraint.m in Sources */, 1962 810B64FE1E779B1F00133E15 /* MASCompositeConstraint.m in Sources */,
  1963 + 8128E2881E8A6A3600B40E75 /* CNBarrageManager.m in Sources */,
1973 D2029C981E6EADE10027CD92 /* MJExtensionConst.m in Sources */, 1964 D2029C981E6EADE10027CD92 /* MJExtensionConst.m in Sources */,
1974 D2575C671E76A25400E3A8FC /* LVCInteractionController.m in Sources */, 1965 D2575C671E76A25400E3A8FC /* LVCInteractionController.m in Sources */,
1975 D2029CAE1E6EADE10027CD92 /* MJRefreshNormalHeader.m in Sources */, 1966 D2029CAE1E6EADE10027CD92 /* MJRefreshNormalHeader.m in Sources */,
@@ -1978,7 +1969,6 @@ @@ -1978,7 +1969,6 @@
1978 D2029CC61E6EADE10027CD92 /* SSKeychain.m in Sources */, 1969 D2029CC61E6EADE10027CD92 /* SSKeychain.m in Sources */,
1979 811BB68E1E8116C8005C6291 /* NSString+StringSize.m in Sources */, 1970 811BB68E1E8116C8005C6291 /* NSString+StringSize.m in Sources */,
1980 D2029C8B1E6EADE10027CD92 /* AFURLResponseSerialization.m in Sources */, 1971 D2029C8B1E6EADE10027CD92 /* AFURLResponseSerialization.m in Sources */,
1981 - 8128E2711E8A3BF000B40E75 /* LVCDanmuView.m in Sources */,  
1982 D2029C921E6EADE10027CD92 /* UIImageView+AFNetworking.m in Sources */, 1972 D2029C921E6EADE10027CD92 /* UIImageView+AFNetworking.m in Sources */,
1983 D224B1971E826ED800CC61D0 /* ChatBarrageAnimAction.m in Sources */, 1973 D224B1971E826ED800CC61D0 /* ChatBarrageAnimAction.m in Sources */,
1984 D2029C9E1E6EADE10027CD92 /* NSObject+MJCoding.m in Sources */, 1974 D2029C9E1E6EADE10027CD92 /* NSObject+MJCoding.m in Sources */,
@@ -1997,7 +1987,6 @@ @@ -1997,7 +1987,6 @@
1997 D2888DB11E6EC05F003A77C8 /* TempViewController.m in Sources */, 1987 D2888DB11E6EC05F003A77C8 /* TempViewController.m in Sources */,
1998 81A483011E88B0130097A80A /* LVCBannerModel.m in Sources */, 1988 81A483011E88B0130097A80A /* LVCBannerModel.m in Sources */,
1999 810B65021E779B1F00133E15 /* MASViewAttribute.m in Sources */, 1989 810B65021E779B1F00133E15 /* MASViewAttribute.m in Sources */,
2000 - 8128E2771E8A3CD700B40E75 /* LVCDanmuManager.m in Sources */,  
2001 D2B7B2511E8247D400ED084E /* ChatBarrageManager.m in Sources */, 1990 D2B7B2511E8247D400ED084E /* ChatBarrageManager.m in Sources */,
2002 D2029CAC1E6EADE10027CD92 /* MJRefreshBackStateFooter.m in Sources */, 1991 D2029CAC1E6EADE10027CD92 /* MJRefreshBackStateFooter.m in Sources */,
2003 D2029CB11E6EADE10027CD92 /* MJRefreshConst.m in Sources */, 1992 D2029CB11E6EADE10027CD92 /* MJRefreshConst.m in Sources */,
@@ -2007,7 +1996,6 @@ @@ -2007,7 +1996,6 @@
2007 D2029D051E6EAE2E0027CD92 /* UILabel+labelFitSize.m in Sources */, 1996 D2029D051E6EAE2E0027CD92 /* UILabel+labelFitSize.m in Sources */,
2008 D2029CB21E6EADE10027CD92 /* UIScrollView+MJExtension.m in Sources */, 1997 D2029CB21E6EADE10027CD92 /* UIScrollView+MJExtension.m in Sources */,
2009 D29D88481E88C53300543A03 /* LVCUGCLivePrepareView.m in Sources */, 1998 D29D88481E88C53300543A03 /* LVCUGCLivePrepareView.m in Sources */,
2010 - 8128E2741E8A3C1900B40E75 /* LVCDanmuLabel.m in Sources */,  
2011 D2029D091E6EAE2E0027CD92 /* Foundation+Log.m in Sources */, 1999 D2029D091E6EAE2E0027CD92 /* Foundation+Log.m in Sources */,
2012 D2029C8E1E6EADE10027CD92 /* AFImageDownloader.m in Sources */, 2000 D2029C8E1E6EADE10027CD92 /* AFImageDownloader.m in Sources */,
2013 81A483201E88F4BF0097A80A /* LVCProgramModel.m in Sources */, 2001 81A483201E88F4BF0097A80A /* LVCProgramModel.m in Sources */,
@@ -2217,7 +2205,7 @@ @@ -2217,7 +2205,7 @@
2217 "$(inherited)", 2205 "$(inherited)",
2218 "$(PROJECT_DIR)/LiveVideoCloud/Classes/Sections/InteractionSections/Gift/GiftResource", 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 PRODUCT_NAME = "$(TARGET_NAME)"; 2209 PRODUCT_NAME = "$(TARGET_NAME)";
2222 }; 2210 };
2223 name = Debug; 2211 name = Debug;
@@ -2240,7 +2228,7 @@ @@ -2240,7 +2228,7 @@
2240 "$(inherited)", 2228 "$(inherited)",
2241 "$(PROJECT_DIR)/LiveVideoCloud/Classes/Sections/InteractionSections/Gift/GiftResource", 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 PRODUCT_NAME = "$(TARGET_NAME)"; 2232 PRODUCT_NAME = "$(TARGET_NAME)";
2245 }; 2233 };
2246 name = Release; 2234 name = Release;
LiveVideoCloud/LiveVideoCloud/AppDelegate/AppDelegate.m
@@ -23,23 +23,28 @@ @@ -23,23 +23,28 @@
23 self.window.rootViewController = [[ZXTabBarController alloc] init]; 23 self.window.rootViewController = [[ZXTabBarController alloc] init];
24 24
25 //初始化直播SDK 25 //初始化直播SDK
26 -// [[CNLiveWebcastManager manager] initWithAppId:AppId appKey:AppKey]; 26 + [[CNLiveWebcastManager manager] initWithAppId:AppId appKey:AppKey];
27 27
28 //初始化聊天SDK并连接服务器 28 //初始化聊天SDK并连接服务器
29 [[CNLiveChatManager sharedCNLiveChatManager] initWithAppKey:AppKey appId:AppId]; 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 } error:^(CNLiveChatConnectErrorCode errors) { 33 } error:^(CNLiveChatConnectErrorCode errors) {
41 NSLog(@"连接服务器失败-----%ld", errors); 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 [self.window makeKeyAndVisible]; 48 [self.window makeKeyAndVisible];
44 49
45 return YES; 50 return YES;
LiveVideoCloud/LiveVideoCloud/Classes/Sections/LiveSections/Controller/LVCLiveViewController.m
@@ -14,10 +14,6 @@ @@ -14,10 +14,6 @@
14 #import "LiveBaseView.h" 14 #import "LiveBaseView.h"
15 #import "LVCUGCLiveEndView.h" 15 #import "LVCUGCLiveEndView.h"
16 16
17 -  
18 -#define KAppId @"60_irn9edco29"  
19 -#define KAppKey @"69fe70bda67e059286ad509d9f5377f815955645b52f94"  
20 -  
21 @interface LVCLiveViewController ()<UIGestureRecognizerDelegate> { 17 @interface LVCLiveViewController ()<UIGestureRecognizerDelegate> {
22 18
23 BOOL _isStreaming; 19 BOOL _isStreaming;
@@ -61,8 +57,6 @@ @@ -61,8 +57,6 @@
61 [self.view addSubview:self.openFlashButton]; 57 [self.view addSubview:self.openFlashButton];
62 [self.view addSubview:self.filterView]; 58 [self.view addSubview:self.filterView];
63 59
64 - [[CNLiveWebcastManager manager] initWithAppId:KAppId appKey:KAppKey];  
65 -  
66 // 初始化推流 60 // 初始化推流
67 NSString *activityId = [NSString stringWithFormat:@"%d%d%d%d%d",arc4random()%9,arc4random()%9,arc4random()%9,arc4random()%9,arc4random()%9]; 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,9 +7,18 @@
7 // 7 //
8 8
9 #import <UIKit/UIKit.h> 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 @interface LVCChatView : UIView 19 @interface LVCChatView : UIView
12 @property (nonatomic, strong) UITableView *tableView; 20 @property (nonatomic, strong) UITableView *tableView;
  21 +@property (nonatomic, assign) id<LVCChatViewDelegate> delegate;
13 22
14 - (instancetype)initWithFrame:(CGRect)frame roomId:(NSString *)roomId; 23 - (instancetype)initWithFrame:(CGRect)frame roomId:(NSString *)roomId;
15 24
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/ChatView/LVCChatView.m
@@ -69,16 +69,23 @@ @@ -69,16 +69,23 @@
69 { 69 {
70 [[CNLiveChatManager sharedCNLiveChatManager] sendMessage:message type:CNLive_ConversationType_CHATROOM targetId:_roomId success:^(CNLiveChatMessage *message) { 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 dispatch_sync(dispatch_get_main_queue(), ^{ 77 dispatch_sync(dispatch_get_main_queue(), ^{
75 [self addData:msg]; 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 NSLog(@"电视台--发送消息---success-(%@)",msg.content); 84 NSLog(@"电视台--发送消息---success-(%@)",msg.content);
79 85
80 } error:^(CNLiveChatErrorCode errors, NSString *messageId, NSString *targetId) { 86 } error:^(CNLiveChatErrorCode errors, NSString *messageId, NSString *targetId) {
81 NSLog(@"电视台--发送消息---failed-(%ld)",(long)errors); 87 NSLog(@"电视台--发送消息---failed-(%ld)",(long)errors);
  88 +
82 }]; 89 }];
83 } 90 }
84 91
@@ -100,8 +107,16 @@ @@ -100,8 +107,16 @@
100 dispatch_queue_t globalQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 107 dispatch_queue_t globalQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
101 dispatch_async(globalQueue, ^{ 108 dispatch_async(globalQueue, ^{
102 LVCMessage *msg = [LVCMessage messageWihtContent:message isRight:NO]; 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 dispatch_sync(dispatch_get_main_queue(), ^{ 115 dispatch_sync(dispatch_get_main_queue(), ^{
104 [self addData:msg]; 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,7 +45,7 @@
45 [self.delegate lvcInputView:self sendMessage:_inputTextField.text]; 45 [self.delegate lvcInputView:self sendMessage:_inputTextField.text];
46 } 46 }
47 47
48 -// [self endEditing:YES]; 48 + [self endEditing:YES];
49 _inputTextField.text = @""; 49 _inputTextField.text = @"";
50 50
51 } 51 }
@@ -64,7 +64,7 @@ @@ -64,7 +64,7 @@
64 [self.delegate lvcInputView:self sendMessage:_inputTextField.text]; 64 [self.delegate lvcInputView:self sendMessage:_inputTextField.text];
65 } 65 }
66 66
67 -// [self endEditing:YES]; 67 + [self endEditing:YES];
68 textField.text = @""; 68 textField.text = @"";
69 return YES; 69 return YES;
70 } 70 }
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/ChatView/LVCMessage.m
@@ -39,7 +39,9 @@ @@ -39,7 +39,9 @@
39 msg.nikename = content.userInfo.name; 39 msg.nikename = content.userInfo.name;
40 msg.portraits = content.userInfo.portraitUri; 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 CGRect frameOfLabel = CGRectZero; 45 CGRect frameOfLabel = CGRectZero;
44 46
45 frameOfLabel.size = rect.size; 47 frameOfLabel.size = rect.size;
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/Controller/LVCLivePlayerController.h
@@ -7,7 +7,10 @@ @@ -7,7 +7,10 @@
7 // 7 //
8 8
9 #import "BaseViewController.h" 9 #import "BaseViewController.h"
  10 +#import "LVCChannelDetailsModel.h"
10 11
11 @interface LVCLivePlayerController : BaseViewController 12 @interface LVCLivePlayerController : BaseViewController
12 13
  14 +@property (nonatomic, strong) LVCChannelDetailsModel *model;
  15 +
13 @end 16 @end
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/Controller/LVCLivePlayerController.m
@@ -12,7 +12,11 @@ @@ -12,7 +12,11 @@
12 #import "LVCInputView.h" 12 #import "LVCInputView.h"
13 #import "LVCChatView.h" 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 BOOL isHiddenStatusBar; //记录状态的隐藏显示 21 BOOL isHiddenStatusBar; //记录状态的隐藏显示
18 CGRect playerFrame; //播放器原始位置 22 CGRect playerFrame; //播放器原始位置
@@ -29,6 +33,9 @@ @@ -29,6 +33,9 @@
29 @property (nonatomic, strong) NSTimer *timer; 33 @property (nonatomic, strong) NSTimer *timer;
30 @property (nonatomic, assign) NSTimeInterval countTime; 34 @property (nonatomic, assign) NSTimeInterval countTime;
31 35
  36 +@property (nonatomic, strong) CNBarrageManager *barrageManager; //弹幕管理者
  37 +@property (nonatomic ,strong) UIView *barrageBaseView; //弹幕总View
  38 +
32 @end 39 @end
33 40
34 @implementation LVCLivePlayerController 41 @implementation LVCLivePlayerController
@@ -73,14 +80,20 @@ @@ -73,14 +80,20 @@
73 }; 80 };
74 81
75 [self makeConstraints]; 82 [self makeConstraints];
76 -  
77 [_player autoHideControlView]; //自动隐藏工具条 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 - (void)addObservers 98 - (void)addObservers
86 { 99 {
@@ -148,11 +161,16 @@ @@ -148,11 +161,16 @@
148 //当键盘出现 161 //当键盘出现
149 - (void)keyboardWillShow:(NSNotification *)aNotification{ 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 - (void)keyboardWillHide:(NSNotification *)aNotification{ 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 #pragma mark - 176 #pragma mark -
@@ -177,6 +195,18 @@ @@ -177,6 +195,18 @@
177 [UIView animateWithDuration:0.3 animations:^{ 195 [UIView animateWithDuration:0.3 animations:^{
178 self.player.transform = CGAffineTransformMakeRotation(0); 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,9 +228,24 @@
198 [UIView animateWithDuration:0.3 animations:^{ 228 [UIView animateWithDuration:0.3 animations:^{
199 self.player.transform = CGAffineTransformMakeRotation(0); 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 #pragma mark - 249 #pragma mark -
205 #pragma mark - LVCPlayerDelegate 250 #pragma mark - LVCPlayerDelegate
206 - (void)lvcPlayer:(LVCPlayer *)player clickedBackBtn:(UIButton *)backBtn 251 - (void)lvcPlayer:(LVCPlayer *)player clickedBackBtn:(UIButton *)backBtn
@@ -220,7 +265,7 @@ @@ -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 if (_player.isFullScreen) {//全屏 270 if (_player.isFullScreen) {//全屏
226 [self toHalfScreenWithrotationAngle:M_PI_2]; 271 [self toHalfScreenWithrotationAngle:M_PI_2];
@@ -236,13 +281,28 @@ @@ -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 #pragma mark - 298 #pragma mark -
240 #pragma mark - LVCInputViewDelegate 299 #pragma mark - LVCInputViewDelegate
241 - (void)lvcInputView:(LVCInputView *)inputView sendMessage:(NSString *)message 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 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event 308 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
@@ -273,6 +333,7 @@ @@ -273,6 +333,7 @@
273 }]; 333 }];
274 _inputView.frame = CGRectMake(0, SCREEN_HEIGHT-50, SCREEN_WIDTH, 49); 334 _inputView.frame = CGRectMake(0, SCREEN_HEIGHT-50, SCREEN_WIDTH, 49);
275 335
  336 + _barrageBaseView.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
276 } else { //半屏 337 } else { //半屏
277 [self.player mas_remakeConstraints:^(MASConstraintMaker *make) { 338 [self.player mas_remakeConstraints:^(MASConstraintMaker *make) {
278 make.top.mas_equalTo(20); 339 make.top.mas_equalTo(20);
@@ -289,7 +350,7 @@ @@ -289,7 +350,7 @@
289 - (LVCPlayer *)player 350 - (LVCPlayer *)player
290 { 351 {
291 if (!_player) { 352 if (!_player) {
292 - _player = [[LVCPlayer alloc] init]; 353 + _player = [[LVCPlayer alloc] initWithFrame:CGRectZero playerModel:self.model];
293 _player.delegate = self; 354 _player.delegate = self;
294 } 355 }
295 return _player; 356 return _player;
@@ -316,10 +377,29 @@ @@ -316,10 +377,29 @@
316 { 377 {
317 if (!_chatView) { 378 if (!_chatView) {
318 _chatView = [[LVCChatView alloc] initWithFrame:CGRectMake(0, SCREEN_WIDTH*9/16+20, SCREEN_WIDTH, SCREEN_HEIGHT-SCREEN_WIDTH*9/16-20-49) roomId:_roomId]; 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 return _chatView; 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 - (void)didReceiveMemoryWarning { 404 - (void)didReceiveMemoryWarning {
325 [super didReceiveMemoryWarning]; 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,6 +7,7 @@
7 // 7 //
8 8
9 #import <UIKit/UIKit.h> 9 #import <UIKit/UIKit.h>
  10 +#import "LVCChannelDetailsModel.h"
10 11
11 @class LVCPlayer; 12 @class LVCPlayer;
12 13
@@ -14,9 +15,10 @@ @@ -14,9 +15,10 @@
14 15
15 @optional 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 @end 23 @end
22 24
@@ -26,11 +28,15 @@ typedef void(^HideInputViewBlock)(BOOL hide); @@ -26,11 +28,15 @@ typedef void(^HideInputViewBlock)(BOOL hide);
26 28
27 @property (nonatomic, strong) UIImageView *topBgView; //顶部蒙版 29 @property (nonatomic, strong) UIImageView *topBgView; //顶部蒙版
28 @property (nonatomic, strong) UIImageView *bottomBgView; //底部蒙版 30 @property (nonatomic, strong) UIImageView *bottomBgView; //底部蒙版
  31 +@property (nonatomic, strong) UIImageView *contentView; //所有空间统一管理在这个view中
  32 +@property (nonatomic, strong) LVCChannelDetailsModel *model; //所有空间统一管理在这个view中
29 @property (nonatomic, readwrite, assign) BOOL isFullScreen; //是否是全屏 33 @property (nonatomic, readwrite, assign) BOOL isFullScreen; //是否是全屏
30 @property (nonatomic, copy) HideInputViewBlock hideBlock; //全屏模式下是否隐藏输入框 34 @property (nonatomic, copy) HideInputViewBlock hideBlock; //全屏模式下是否隐藏输入框
31 - 35 +@property (nonatomic, assign, readonly) BOOL displayBarrage; //是否显示弹幕
32 @property (nonatomic, assign) id<LVCPlayerDelegate> delegate; 36 @property (nonatomic, assign) id<LVCPlayerDelegate> delegate;
33 37
  38 +- (instancetype)initWithFrame:(CGRect)frame playerModel:(LVCChannelDetailsModel *)model;
  39 +
34 - (void)autoHideControlView; //自动隐藏上下功能条 40 - (void)autoHideControlView; //自动隐藏上下功能条
35 41
36 - (void)stopPlaying; //停止播放 42 - (void)stopPlaying; //停止播放
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/LVCPlayer.m
@@ -10,14 +10,9 @@ @@ -10,14 +10,9 @@
10 #import "LVCPlayerLoadingView.h" 10 #import "LVCPlayerLoadingView.h"
11 #import "SevenSwitch.h" 11 #import "SevenSwitch.h"
12 12
13 -#define kAppId @"60_irn9edco29"  
14 -#define kAppKey @"69fe70bda67e059286ad509d9f5377f815955645b52f94"  
15 -#define kbundleId @"com.cnlive.zhangxu.LiveVideoCloud"  
16 -  
17 @interface LVCPlayer ()<UIGestureRecognizerDelegate> 13 @interface LVCPlayer ()<UIGestureRecognizerDelegate>
18 14
19 @property (nonatomic, strong) UIButton *backBtn; //返回 15 @property (nonatomic, strong) UIButton *backBtn; //返回
20 -@property (nonatomic, strong) UIImageView *contentView; //所有空间统一管理在这个view中  
21 @property (nonatomic, strong) UIButton *playOrPauseBtn; //播放/暂停 16 @property (nonatomic, strong) UIButton *playOrPauseBtn; //播放/暂停
22 @property (nonatomic, strong) UILabel *titleLab; //标题 17 @property (nonatomic, strong) UILabel *titleLab; //标题
23 @property (nonatomic, strong) UIButton *fullScreenBtn; //控制全屏按钮 18 @property (nonatomic, strong) UIButton *fullScreenBtn; //控制全屏按钮
@@ -32,12 +27,12 @@ @@ -32,12 +27,12 @@
32 27
33 @implementation LVCPlayer 28 @implementation LVCPlayer
34 29
35 -- (instancetype)initWithFrame:(CGRect)frame 30 +- (instancetype)initWithFrame:(CGRect)frame playerModel:(LVCChannelDetailsModel *)model
36 { 31 {
37 self = [super initWithFrame:frame]; 32 self = [super initWithFrame:frame];
38 if (self) { 33 if (self) {
39 34
40 - [self initPlayer]; 35 + [self initPlayerWithModel:model];
41 36
42 [self addSubview:self.contentView]; 37 [self addSubview:self.contentView];
43 [self.contentView addSubview:self.bottomBgView]; 38 [self.contentView addSubview:self.bottomBgView];
@@ -58,27 +53,44 @@ @@ -58,27 +53,44 @@
58 } 53 }
59 #pragma mark - 54 #pragma mark -
60 #pragma mark - initPlayer 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 #pragma mark - 96 #pragma mark -
@@ -112,9 +124,12 @@ @@ -112,9 +124,12 @@
112 124
113 - (void)barrageSwitchAction 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 - (void)editBtnAction:(UIButton *)btn 135 - (void)editBtnAction:(UIButton *)btn
@@ -483,6 +498,11 @@ @@ -483,6 +498,11 @@
483 #pragma mark - 498 #pragma mark -
484 #pragma mark - getter 499 #pragma mark - getter
485 500
  501 +- (BOOL)displayBarrage
  502 +{
  503 + return _barrageSwitch.on;
  504 +}
  505 +
486 - (UIImageView *)contentView 506 - (UIImageView *)contentView
487 { 507 {
488 if (!_contentView) { 508 if (!_contentView) {
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/LVCTelevisionView.m
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 #import "LVCChannelDetailsModel.h" 13 #import "LVCChannelDetailsModel.h"
14 #import "LVCChannelsModel.h" 14 #import "LVCChannelsModel.h"
15 #import "LVCBannerModel.h" 15 #import "LVCBannerModel.h"
  16 +#import "LVCLivePlayerController.h"
16 17
17 static NSString *cellId = @"LVCLiveListCollectionViewCell"; 18 static NSString *cellId = @"LVCLiveListCollectionViewCell";
18 static NSString *firstHeaderId = @"LVCFirstHeaderReusableView"; 19 static NSString *firstHeaderId = @"LVCFirstHeaderReusableView";
@@ -186,8 +187,15 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;; @@ -186,8 +187,15 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;;
186 #pragma mark - 187 #pragma mark -
187 #pragma mark - UICollectionViewDelegate 188 #pragma mark - UICollectionViewDelegate
188 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 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 #pragma mark - 201 #pragma mark -
@@ -213,8 +221,7 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;; @@ -213,8 +221,7 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;;
213 221
214 NSMutableArray *arrayM = [[NSMutableArray alloc]init]; 222 NSMutableArray *arrayM = [[NSMutableArray alloc]init];
215 for (NSDictionary *dict in responseObject[@"channels"]) { 223 for (NSDictionary *dict in responseObject[@"channels"]) {
216 - LVCChannelsModel *model = [LVCChannelsModel new];  
217 - [model setValuesForKeysWithDictionary:dict]; 224 + LVCChannelsModel *model = [LVCChannelsModel mj_objectWithKeyValues:dict];
218 [arrayM addObject:model]; 225 [arrayM addObject:model];
219 } 226 }
220 self.channelsModelArray = arrayM; 227 self.channelsModelArray = arrayM;
@@ -223,8 +230,7 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;; @@ -223,8 +230,7 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;;
223 230
224 NSMutableArray *arrayM = [NSMutableArray array]; 231 NSMutableArray *arrayM = [NSMutableArray array];
225 for (NSDictionary *dict in responseObject[@"banner"]) { 232 for (NSDictionary *dict in responseObject[@"banner"]) {
226 - LVCBannerModel *rollModel = [LVCBannerModel new];  
227 - [rollModel setValuesForKeysWithDictionary:dict]; 233 + LVCBannerModel *rollModel = [LVCBannerModel mj_objectWithKeyValues:dict];
228 [arrayM addObject:rollModel]; 234 [arrayM addObject:rollModel];
229 } 235 }
230 self.bannerModelArray = arrayM; 236 self.bannerModelArray = arrayM;
LiveVideoCloud/LiveVideoCloud/Info.plist
@@ -2,19 +2,8 @@ @@ -2,19 +2,8 @@
2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 <plist version="1.0"> 3 <plist version="1.0">
4 <dict> 4 <dict>
5 - <key>UIViewControllerBasedStatusBarAppearance</key>  
6 - <false/>  
7 <key>CFBundleDevelopmentRegion</key> 5 <key>CFBundleDevelopmentRegion</key>
8 <string>en</string> 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 <key>CFBundleExecutable</key> 7 <key>CFBundleExecutable</key>
19 <string>$(EXECUTABLE_NAME)</string> 8 <string>$(EXECUTABLE_NAME)</string>
20 <key>CFBundleIdentifier</key> 9 <key>CFBundleIdentifier</key>
@@ -59,5 +48,7 @@ @@ -59,5 +48,7 @@
59 <string>UIInterfaceOrientationLandscapeLeft</string> 48 <string>UIInterfaceOrientationLandscapeLeft</string>
60 <string>UIInterfaceOrientationLandscapeRight</string> 49 <string>UIInterfaceOrientationLandscapeRight</string>
61 </array> 50 </array>
  51 + <key>UIViewControllerBasedStatusBarAppearance</key>
  52 + <false/>
62 </dict> 53 </dict>
63 </plist> 54 </plist>
LiveVideoCloud/LiveVideoCloud/UtilKits/Macro/Macros/AppMacro.h
@@ -13,15 +13,8 @@ @@ -13,15 +13,8 @@
13 #ifndef AppMacro_h 13 #ifndef AppMacro_h
14 #define AppMacro_h 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 #endif /* AppMacro_h */ 20 #endif /* AppMacro_h */