Commit c5309b94e0aa48ffc809c7a5719be7677eb9744b

Authored by 朱林
1 parent efed3d62

no message

LiveVideoCloud/LiveVideoCloud.xcodeproj/project.pbxproj
@@ -26,6 +26,10 @@ @@ -26,6 +26,10 @@
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 8130911E1E84C0F0005F0BFF /* LVCMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 8130911D1E84C0F0005F0BFF /* LVCMessage.m */; }; 33 8130911E1E84C0F0005F0BFF /* LVCMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 8130911D1E84C0F0005F0BFF /* LVCMessage.m */; };
30 81A1B9A91E8277410079FF5F /* LVCInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A1B9A81E8277410079FF5F /* LVCInputView.m */; }; 34 81A1B9A91E8277410079FF5F /* LVCInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A1B9A81E8277410079FF5F /* LVCInputView.m */; };
31 81A482F51E88ACC80097A80A /* LVCTelevisionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A482F41E88ACC80097A80A /* LVCTelevisionView.m */; }; 35 81A482F51E88ACC80097A80A /* LVCTelevisionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A482F41E88ACC80097A80A /* LVCTelevisionView.m */; };
@@ -274,6 +278,14 @@ @@ -274,6 +278,14 @@
274 811BB6871E8107B4005C6291 /* LVCChatViewTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCChatViewTableViewCell.m; sourceTree = "<group>"; }; 278 811BB6871E8107B4005C6291 /* LVCChatViewTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCChatViewTableViewCell.m; sourceTree = "<group>"; };
275 811BB68C1E8116C8005C6291 /* NSString+StringSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+StringSize.h"; sourceTree = "<group>"; }; 279 811BB68C1E8116C8005C6291 /* NSString+StringSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+StringSize.h"; sourceTree = "<group>"; };
276 811BB68D1E8116C8005C6291 /* NSString+StringSize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+StringSize.m"; sourceTree = "<group>"; }; 280 811BB68D1E8116C8005C6291 /* NSString+StringSize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+StringSize.m"; sourceTree = "<group>"; };
  281 + 8128E26C1E8A3AFE00B40E75 /* LVCDanmuUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCDanmuUtil.h; sourceTree = "<group>"; };
  282 + 8128E26D1E8A3AFE00B40E75 /* LVCDanmuUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCDanmuUtil.m; sourceTree = "<group>"; };
  283 + 8128E26F1E8A3BF000B40E75 /* LVCDanmuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCDanmuView.h; sourceTree = "<group>"; };
  284 + 8128E2701E8A3BF000B40E75 /* LVCDanmuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCDanmuView.m; sourceTree = "<group>"; };
  285 + 8128E2721E8A3C1900B40E75 /* LVCDanmuLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCDanmuLabel.h; sourceTree = "<group>"; };
  286 + 8128E2731E8A3C1900B40E75 /* LVCDanmuLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCDanmuLabel.m; sourceTree = "<group>"; };
  287 + 8128E2751E8A3CD700B40E75 /* LVCDanmuManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCDanmuManager.h; sourceTree = "<group>"; };
  288 + 8128E2761E8A3CD700B40E75 /* LVCDanmuManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCDanmuManager.m; sourceTree = "<group>"; };
277 8130911C1E84C0F0005F0BFF /* LVCMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCMessage.h; sourceTree = "<group>"; }; 289 8130911C1E84C0F0005F0BFF /* LVCMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCMessage.h; sourceTree = "<group>"; };
278 8130911D1E84C0F0005F0BFF /* LVCMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCMessage.m; sourceTree = "<group>"; }; 290 8130911D1E84C0F0005F0BFF /* LVCMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCMessage.m; sourceTree = "<group>"; };
279 81A1B9A71E8277410079FF5F /* LVCInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCInputView.h; sourceTree = "<group>"; }; 291 81A1B9A71E8277410079FF5F /* LVCInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCInputView.h; sourceTree = "<group>"; };
@@ -701,6 +713,21 @@ @@ -701,6 +713,21 @@
701 path = ../ChatView; 713 path = ../ChatView;
702 sourceTree = "<group>"; 714 sourceTree = "<group>";
703 }; 715 };
  716 + 8128E26B1E8A3AD400B40E75 /* Danmu */ = {
  717 + isa = PBXGroup;
  718 + children = (
  719 + 8128E26C1E8A3AFE00B40E75 /* LVCDanmuUtil.h */,
  720 + 8128E26D1E8A3AFE00B40E75 /* LVCDanmuUtil.m */,
  721 + 8128E26F1E8A3BF000B40E75 /* LVCDanmuView.h */,
  722 + 8128E2701E8A3BF000B40E75 /* LVCDanmuView.m */,
  723 + 8128E2721E8A3C1900B40E75 /* LVCDanmuLabel.h */,
  724 + 8128E2731E8A3C1900B40E75 /* LVCDanmuLabel.m */,
  725 + 8128E2751E8A3CD700B40E75 /* LVCDanmuManager.h */,
  726 + 8128E2761E8A3CD700B40E75 /* LVCDanmuManager.m */,
  727 + );
  728 + path = Danmu;
  729 + sourceTree = "<group>";
  730 + };
704 812E504E1E7699B9004F5FCD /* CNLiveSDK */ = { 731 812E504E1E7699B9004F5FCD /* CNLiveSDK */ = {
705 isa = PBXGroup; 732 isa = PBXGroup;
706 children = ( 733 children = (
@@ -1630,6 +1657,7 @@ @@ -1630,6 +1657,7 @@
1630 D2888DAA1E6EC014003A77C8 /* View */ = { 1657 D2888DAA1E6EC014003A77C8 /* View */ = {
1631 isa = PBXGroup; 1658 isa = PBXGroup;
1632 children = ( 1659 children = (
  1660 + 8128E26B1E8A3AD400B40E75 /* Danmu */,
1633 811BB67B1E80F858005C6291 /* ChatView */, 1661 811BB67B1E80F858005C6291 /* ChatView */,
1634 810B64DE1E779AE900133E15 /* LVCPlayer.h */, 1662 810B64DE1E779AE900133E15 /* LVCPlayer.h */,
1635 810B64DF1E779AE900133E15 /* LVCPlayer.m */, 1663 810B64DF1E779AE900133E15 /* LVCPlayer.m */,
@@ -1881,6 +1909,7 @@ @@ -1881,6 +1909,7 @@
1881 D2029D011E6EAE2E0027CD92 /* UIColor+HexString.m in Sources */, 1909 D2029D011E6EAE2E0027CD92 /* UIColor+HexString.m in Sources */,
1882 D2029CA41E6EADE10027CD92 /* MJRefreshComponent.m in Sources */, 1910 D2029CA41E6EADE10027CD92 /* MJRefreshComponent.m in Sources */,
1883 D2575C7A1E76A4F300E3A8FC /* NHCarViews.m in Sources */, 1911 D2575C7A1E76A4F300E3A8FC /* NHCarViews.m in Sources */,
  1912 + 8128E26E1E8A3AFE00B40E75 /* LVCDanmuUtil.m in Sources */,
1884 D2029CBC1E6EADE10027CD92 /* SDWebImageDownloaderOperation.m in Sources */, 1913 D2029CBC1E6EADE10027CD92 /* SDWebImageDownloaderOperation.m in Sources */,
1885 D2029CA51E6EADE10027CD92 /* MJRefreshFooter.m in Sources */, 1914 D2029CA51E6EADE10027CD92 /* MJRefreshFooter.m in Sources */,
1886 D22830FC1E77C2D900627701 /* BottomToolView.m in Sources */, 1915 D22830FC1E77C2D900627701 /* BottomToolView.m in Sources */,
@@ -1933,6 +1962,7 @@ @@ -1933,6 +1962,7 @@
1933 D2029CC61E6EADE10027CD92 /* SSKeychain.m in Sources */, 1962 D2029CC61E6EADE10027CD92 /* SSKeychain.m in Sources */,
1934 811BB68E1E8116C8005C6291 /* NSString+StringSize.m in Sources */, 1963 811BB68E1E8116C8005C6291 /* NSString+StringSize.m in Sources */,
1935 D2029C8B1E6EADE10027CD92 /* AFURLResponseSerialization.m in Sources */, 1964 D2029C8B1E6EADE10027CD92 /* AFURLResponseSerialization.m in Sources */,
  1965 + 8128E2711E8A3BF000B40E75 /* LVCDanmuView.m in Sources */,
1936 D2029C921E6EADE10027CD92 /* UIImageView+AFNetworking.m in Sources */, 1966 D2029C921E6EADE10027CD92 /* UIImageView+AFNetworking.m in Sources */,
1937 D224B1971E826ED800CC61D0 /* ChatBarrageAnimAction.m in Sources */, 1967 D224B1971E826ED800CC61D0 /* ChatBarrageAnimAction.m in Sources */,
1938 D2029C9E1E6EADE10027CD92 /* NSObject+MJCoding.m in Sources */, 1968 D2029C9E1E6EADE10027CD92 /* NSObject+MJCoding.m in Sources */,
@@ -1943,7 +1973,6 @@ @@ -1943,7 +1973,6 @@
1943 D2029D041E6EAE2E0027CD92 /* UILabel+ContentSize.m in Sources */, 1973 D2029D041E6EAE2E0027CD92 /* UILabel+ContentSize.m in Sources */,
1944 D25530031E79115100DF38A5 /* AnimQueueManager.m in Sources */, 1974 D25530031E79115100DF38A5 /* AnimQueueManager.m in Sources */,
1945 D2029C871E6EADE10027CD92 /* AFHTTPSessionManager.m in Sources */, 1975 D2029C871E6EADE10027CD92 /* AFHTTPSessionManager.m in Sources */,
1946 - D236968D1E7FC7C200E4BF71 /* CNBarrageManager.m in Sources */,  
1947 81A482F81E88AFA20097A80A /* LVCFirstHeaderReusableView.m in Sources */, 1976 81A482F81E88AFA20097A80A /* LVCFirstHeaderReusableView.m in Sources */,
1948 D2029B861E6EAAA50027CD92 /* main.m in Sources */, 1977 D2029B861E6EAAA50027CD92 /* main.m in Sources */,
1949 D2029C8C1E6EADE10027CD92 /* AFURLSessionManager.m in Sources */, 1978 D2029C8C1E6EADE10027CD92 /* AFURLSessionManager.m in Sources */,
@@ -1952,6 +1981,7 @@ @@ -1952,6 +1981,7 @@
1952 D2888DB11E6EC05F003A77C8 /* TempViewController.m in Sources */, 1981 D2888DB11E6EC05F003A77C8 /* TempViewController.m in Sources */,
1953 81A483011E88B0130097A80A /* LVCBannerModel.m in Sources */, 1982 81A483011E88B0130097A80A /* LVCBannerModel.m in Sources */,
1954 810B65021E779B1F00133E15 /* MASViewAttribute.m in Sources */, 1983 810B65021E779B1F00133E15 /* MASViewAttribute.m in Sources */,
  1984 + 8128E2771E8A3CD700B40E75 /* LVCDanmuManager.m in Sources */,
1955 D2B7B2511E8247D400ED084E /* ChatBarrageManager.m in Sources */, 1985 D2B7B2511E8247D400ED084E /* ChatBarrageManager.m in Sources */,
1956 D2029CAC1E6EADE10027CD92 /* MJRefreshBackStateFooter.m in Sources */, 1986 D2029CAC1E6EADE10027CD92 /* MJRefreshBackStateFooter.m in Sources */,
1957 D2029CB11E6EADE10027CD92 /* MJRefreshConst.m in Sources */, 1987 D2029CB11E6EADE10027CD92 /* MJRefreshConst.m in Sources */,
@@ -1961,6 +1991,7 @@ @@ -1961,6 +1991,7 @@
1961 D2029D051E6EAE2E0027CD92 /* UILabel+labelFitSize.m in Sources */, 1991 D2029D051E6EAE2E0027CD92 /* UILabel+labelFitSize.m in Sources */,
1962 D2029CB21E6EADE10027CD92 /* UIScrollView+MJExtension.m in Sources */, 1992 D2029CB21E6EADE10027CD92 /* UIScrollView+MJExtension.m in Sources */,
1963 D29D88481E88C53300543A03 /* LVCUGCLivePrepareView.m in Sources */, 1993 D29D88481E88C53300543A03 /* LVCUGCLivePrepareView.m in Sources */,
  1994 + 8128E2741E8A3C1900B40E75 /* LVCDanmuLabel.m in Sources */,
1964 D2029D091E6EAE2E0027CD92 /* Foundation+Log.m in Sources */, 1995 D2029D091E6EAE2E0027CD92 /* Foundation+Log.m in Sources */,
1965 D2029C8E1E6EADE10027CD92 /* AFImageDownloader.m in Sources */, 1996 D2029C8E1E6EADE10027CD92 /* AFImageDownloader.m in Sources */,
1966 81A483201E88F4BF0097A80A /* LVCProgramModel.m in Sources */, 1997 81A483201E88F4BF0097A80A /* LVCProgramModel.m in Sources */,
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/Controller/HomeViewController.m
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 #import "LVCInteractionController.h" 11 #import "LVCInteractionController.h"
12 #import "LVCLivePlayerController.h" 12 #import "LVCLivePlayerController.h"
13 #import "LVCUGCLivePlayerController.h" 13 #import "LVCUGCLivePlayerController.h"
14 -#import "LVCTVLiveViewController.h" 14 +#import "LVCLivePlayerController.h"
15 15
16 @interface HomeViewController () 16 @interface HomeViewController ()
17 17
@@ -56,8 +56,8 @@ @@ -56,8 +56,8 @@
56 56
57 - (void)liveAction 57 - (void)liveAction
58 { 58 {
59 - LVCTVLiveViewController *liveVC = [[LVCTVLiveViewController alloc] init];  
60 -// self.navigationController.navigationBar.hidden = YES; 59 + LVCLivePlayerController *liveVC = [[LVCLivePlayerController alloc] init];
  60 + self.navigationController.navigationBar.hidden = YES;
61 [self.navigationController pushViewController:liveVC animated:YES]; 61 [self.navigationController pushViewController:liveVC animated:YES];
62 } 62 }
63 63
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/Controller/LVCLivePlayerController.m
@@ -26,6 +26,9 @@ @@ -26,6 +26,9 @@
26 @property (nonatomic, strong) LVCInputView *inputView; 26 @property (nonatomic, strong) LVCInputView *inputView;
27 @property (nonatomic, strong) LVCChatView *chatView; 27 @property (nonatomic, strong) LVCChatView *chatView;
28 28
  29 +@property (nonatomic, strong) NSTimer *timer;
  30 +@property (nonatomic, assign) NSTimeInterval countTime;
  31 +
29 @end 32 @end
30 33
31 @implementation LVCLivePlayerController 34 @implementation LVCLivePlayerController
@@ -72,8 +75,13 @@ @@ -72,8 +75,13 @@
72 [self makeConstraints]; 75 [self makeConstraints];
73 76
74 [_player autoHideControlView]; //自动隐藏工具条 77 [_player autoHideControlView]; //自动隐藏工具条
  78 +
  79 +
  80 +
  81 +
75 } 82 }
76 83
  84 +
77 - (void)addObservers 85 - (void)addObservers
78 { 86 {
79 [[NSNotificationCenter defaultCenter] addObserver:self 87 [[NSNotificationCenter defaultCenter] addObserver:self
@@ -140,9 +148,7 @@ @@ -140,9 +148,7 @@
140 //当键盘出现 148 //当键盘出现
141 - (void)keyboardWillShow:(NSNotification *)aNotification{ 149 - (void)keyboardWillShow:(NSNotification *)aNotification{
142 //获取键盘的高度 150 //获取键盘的高度
143 - NSDictionary* info = [aNotification userInfo];  
144 - CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;  
145 - _inputView.frame = CGRectMake(0, SCREEN_HEIGHT-kbSize.height-50, SCREEN_WIDTH, 50); 151 +
146 } 152 }
147 153
148 - (void)keyboardWillHide:(NSNotification *)aNotification{ 154 - (void)keyboardWillHide:(NSNotification *)aNotification{
@@ -214,7 +220,7 @@ @@ -214,7 +220,7 @@
214 } 220 }
215 } 221 }
216 222
217 -- (void)lvcPlayer:(LVCPlayer *)player clickedFullScreenBtn:(UIButton *)fullScreenBtn 223 +- (void)lvcPlayer:(LVCPlayer *)player clicketullScreenBtn:(UIButton *)fullScreenBtn
218 { 224 {
219 if (_player.isFullScreen) {//全屏 225 if (_player.isFullScreen) {//全屏
220 [self toHalfScreenWithrotationAngle:M_PI_2]; 226 [self toHalfScreenWithrotationAngle:M_PI_2];
@@ -236,8 +242,7 @@ @@ -236,8 +242,7 @@
236 { 242 {
237 NSLog(@"发送消息(%@)",message); 243 NSLog(@"发送消息(%@)",message);
238 244
239 - [_chatView sendMsgWithMessage:message];  
240 - 245 +// [_chatView sendMsgWithMessage:message];
241 } 246 }
242 247
243 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event 248 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
@@ -315,6 +320,7 @@ @@ -315,6 +320,7 @@
315 return _chatView; 320 return _chatView;
316 } 321 }
317 322
  323 +
318 - (void)didReceiveMemoryWarning { 324 - (void)didReceiveMemoryWarning {
319 [super didReceiveMemoryWarning]; 325 [super didReceiveMemoryWarning];
320 // Dispose of any resources that can be recreated. 326 // Dispose of any resources that can be recreated.
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/Controller/LVCMoreProgramViewController.m
@@ -73,7 +73,6 @@ @@ -73,7 +73,6 @@
73 }]; 73 }];
74 } 74 }
75 75
76 -  
77 - (void)refreshAction 76 - (void)refreshAction
78 { 77 {
79 [self request:1 refresh:YES]; 78 [self request:1 refresh:YES];
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/Danmu/LVCDanmuLabel.h 0 → 100644
  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 0 → 100644
  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 0 → 100644
  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 0 → 100644
  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 0 → 100644
  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 0 → 100644
  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 0 → 100644
  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 0 → 100644
  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/LVCTelevisionView.m
@@ -234,6 +234,8 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;; @@ -234,6 +234,8 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;;
234 234
235 } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 235 } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
236 236
  237 + [self.collectionView.header endRefreshing];
  238 +
237 NSLog(@"获取电视台数据失败"); 239 NSLog(@"获取电视台数据失败");
238 240
239 }]; 241 }];
@@ -274,8 +276,7 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;; @@ -274,8 +276,7 @@ static NSString *otherHeaderId = @&quot;LVCOtherHeaderReusableView&quot;;
274 _collectionView.dataSource = self; 276 _collectionView.dataSource = self;
275 _collectionView.delegate = self; 277 _collectionView.delegate = self;
276 278
277 -// MJRefreshGifHeader *header = [CNRefreshHeader headerWithRefreshingTarget:self refreshingAction:@selector(refresh)];  
278 -// _collectionView.header = header; 279 + _collectionView.header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(refresh)];
279 } 280 }
280 return _collectionView; 281 return _collectionView;
281 } 282 }