Commit 45591957daf3701d38c3f935e54af931dea15bbc
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
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 = @"LVCOtherHeaderReusableView"; | @@ -186,8 +187,15 @@ static NSString *otherHeaderId = @"LVCOtherHeaderReusableView"; | ||
| 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 = @"LVCOtherHeaderReusableView"; | @@ -213,8 +221,7 @@ static NSString *otherHeaderId = @"LVCOtherHeaderReusableView"; | ||
| 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 = @"LVCOtherHeaderReusableView"; | @@ -223,8 +230,7 @@ static NSString *otherHeaderId = @"LVCOtherHeaderReusableView"; | ||
| 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 */ |