浏览代码

直播创建临时房间

Steven 3 年之前
父节点
当前提交
79d74997d5
共有 100 个文件被更改,包括 5584 次插入1210 次删除
  1. 208 6
      KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj
  2. 6 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/Contents.json
  3. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePreview_close.imageset/Contents.json
  4. 二进制
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePreview_close.imageset/livePreview_close@2x.png
  5. 二进制
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePreview_close.imageset/livePreview_close@3x.png
  6. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePrew_beauty.imageset/Contents.json
  7. 二进制
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePrew_beauty.imageset/livePrew_beauty@2x.png
  8. 二进制
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePrew_beauty.imageset/livePrew_beauty@3x.png
  9. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_share.imageset/Contents.json
  10. 二进制
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_share.imageset/live_share@2x.png
  11. 二进制
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_share.imageset/live_share@3x.png
  12. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_switch.imageset/Contents.json
  13. 二进制
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_switch.imageset/live_switch@2x.png
  14. 二进制
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_switch.imageset/live_switch@3x.png
  15. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/BaseViewController.h
  16. 28 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Custom/KSNormalAlertView.h
  17. 266 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Custom/KSNormalAlertView.m
  18. 47 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/CreateLiveViewController.m
  19. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LivePrepareViewController.h
  20. 137 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LivePrepareViewController.m
  21. 50 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LiveVideoRoomViewController.h
  22. 32 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LiveVideoRoomViewController.m
  23. 58 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSChatroomMessageCenter.h
  24. 73 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSChatroomMessageCenter.m
  25. 16 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomClose.h
  26. 31 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomClose.m
  27. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomDownSeat.h
  28. 50 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomDownSeat.m
  29. 26 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomEnter.h
  30. 48 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomEnter.m
  31. 36 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomKickOut.h
  32. 60 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomKickOut.m
  33. 25 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomLeave.h
  34. 12 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomLeave.m
  35. 19 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomLike.h
  36. 55 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomLike.m
  37. 37 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomSeatApply.h
  38. 65 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomSeatApply.m
  39. 39 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomSeatResponse.h
  40. 65 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomSeatResponse.m
  41. 27 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomUserQuit.h
  42. 49 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomUserQuit.m
  43. 24 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomWelcome.h
  44. 74 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomWelcome.m
  45. 20 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/KSEnterLiveroomManager.h
  46. 64 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/KSEnterLiveroomManager.m
  47. 38 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/KSLiveStreamVideo.h
  48. 36 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/KSLiveStreamVideo.m
  49. 3 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/CreateLiveBodyView.h
  50. 94 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/CreateLiveBodyView.m
  51. 140 3
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/CreateLiveBodyView.xib
  52. 136 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/Cell/BaseEmoji.plist
  53. 19 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/Cell/KSChatEmojiCollectionCell.h
  54. 50 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/Cell/KSChatEmojiCollectionCell.m
  55. 46 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatEmojiBoardView.h
  56. 236 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatEmojiBoardView.m
  57. 99 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatInputBarControl.h
  58. 206 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatInputBarControl.m
  59. 102 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatInputView.h
  60. 193 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatInputView.m
  61. 16 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/KSBeautySettingView.h
  62. 20 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/KSBeautySettingView.m
  63. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/KSBeautySettingView.xib
  64. 36 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/KSChatroomTextCell.h
  65. 302 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/KSChatroomTextCell.m
  66. 30 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LivePreviewBodyView.h
  67. 70 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LivePreviewBodyView.m
  68. 236 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LivePreviewBodyView.xib
  69. 16 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.h
  70. 20 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.m
  71. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.xib
  72. 16 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomHeadView.h
  73. 20 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomHeadView.m
  74. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomHeadView.xib
  75. 21 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomLikeLayer.h
  76. 69 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomLikeLayer.m
  77. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatContentView.h
  78. 147 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatContentView.m
  79. 10 8
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Controller/MineViewController.m
  80. 1 0
      KulexiuForTeacher/Podfile
  81. 4 1
      KulexiuForTeacher/Podfile.lock
  82. 4 1
      KulexiuForTeacher/Pods/Manifest.lock
  83. 1192 1190
      KulexiuForTeacher/Pods/Pods.xcodeproj/project.pbxproj
  84. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/2d_lut.png
  85. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/3d_lut.png
  86. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filterFile.zip
  87. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_chengshi.png
  88. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_chulian.png
  89. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_chuxin.png
  90. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_danse.png
  91. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_fanchase.png
  92. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_fennen.png
  93. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_huaijiu.png
  94. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_hupo.png
  95. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_landiao.png
  96. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_langman.png
  97. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_meiwei.png
  98. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_mitaofen.png
  99. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_naicha.png
  100. 二进制
      KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_pailide.png

+ 208 - 6
KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj

@@ -57,6 +57,34 @@
 		275B172B27EB269F0081FDEF /* ChatAddressHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 275B172A27EB269F0081FDEF /* ChatAddressHeaderView.xib */; };
 		275B172B27EB269F0081FDEF /* ChatAddressHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 275B172A27EB269F0081FDEF /* ChatAddressHeaderView.xib */; };
 		275B172F27EB27860081FDEF /* GroupCreateView.m in Sources */ = {isa = PBXBuildFile; fileRef = 275B172E27EB27860081FDEF /* GroupCreateView.m */; };
 		275B172F27EB27860081FDEF /* GroupCreateView.m in Sources */ = {isa = PBXBuildFile; fileRef = 275B172E27EB27860081FDEF /* GroupCreateView.m */; };
 		275B173127EB27960081FDEF /* GroupCreateView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 275B173027EB27960081FDEF /* GroupCreateView.xib */; };
 		275B173127EB27960081FDEF /* GroupCreateView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 275B173027EB27960081FDEF /* GroupCreateView.xib */; };
+		275E3DA327F441EC0010EC30 /* KSEnterLiveroomManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DA227F441EC0010EC30 /* KSEnterLiveroomManager.m */; };
+		275E3DA627F442B70010EC30 /* LiveVideoRoomViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DA527F442B70010EC30 /* LiveVideoRoomViewController.m */; };
+		275E3DA927F45A8A0010EC30 /* KSLiveStreamVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DA827F45A8A0010EC30 /* KSLiveStreamVideo.m */; };
+		275E3DAD27F45BE90010EC30 /* KSChatroomMessageCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DAC27F45BE90010EC30 /* KSChatroomMessageCenter.m */; };
+		275E3DB027F45CA60010EC30 /* KSLiveChatroomLike.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DAF27F45CA60010EC30 /* KSLiveChatroomLike.m */; };
+		275E3DB327F45D380010EC30 /* KSLiveChatroomDownSeat.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DB227F45D380010EC30 /* KSLiveChatroomDownSeat.m */; };
+		275E3DB627F45DA60010EC30 /* KSLiveChatroomEnter.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DB527F45DA60010EC30 /* KSLiveChatroomEnter.m */; };
+		275E3DBC27F45E750010EC30 /* KSLiveChatroomLeave.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DBB27F45E750010EC30 /* KSLiveChatroomLeave.m */; };
+		275E3DBF27F45EB90010EC30 /* KSLiveChatroomUserQuit.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DBE27F45EB90010EC30 /* KSLiveChatroomUserQuit.m */; };
+		275E3DC227F45F3F0010EC30 /* KSLiveChatroomWelcome.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DC127F45F3F0010EC30 /* KSLiveChatroomWelcome.m */; };
+		275E3DC527F460030010EC30 /* KSLiveChatroomClose.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DC427F460030010EC30 /* KSLiveChatroomClose.m */; };
+		275E3DC827F460720010EC30 /* KSLiveChatroomKickOut.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DC727F460720010EC30 /* KSLiveChatroomKickOut.m */; };
+		275E3DD127F463140010EC30 /* KSLiveChatroomSeatApply.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DD027F463140010EC30 /* KSLiveChatroomSeatApply.m */; };
+		275E3DD427F463580010EC30 /* KSLiveChatroomSeatResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DD327F463580010EC30 /* KSLiveChatroomSeatResponse.m */; };
+		275E3DE027F467410010EC30 /* KSChatEmojiBoardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DD627F467410010EC30 /* KSChatEmojiBoardView.m */; };
+		275E3DE127F467410010EC30 /* KSChatInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DD827F467410010EC30 /* KSChatInputView.m */; };
+		275E3DE227F467410010EC30 /* KSChatEmojiCollectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DDB27F467410010EC30 /* KSChatEmojiCollectionCell.m */; };
+		275E3DE327F467410010EC30 /* BaseEmoji.plist in Resources */ = {isa = PBXBuildFile; fileRef = 275E3DDC27F467410010EC30 /* BaseEmoji.plist */; };
+		275E3DE427F467410010EC30 /* KSChatInputBarControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DDE27F467410010EC30 /* KSChatInputBarControl.m */; };
+		275E3DE727F4677F0010EC30 /* LiveRoomHeadView.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DE627F4677F0010EC30 /* LiveRoomHeadView.m */; };
+		275E3DE927F4679E0010EC30 /* LiveRoomHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 275E3DE827F4679D0010EC30 /* LiveRoomHeadView.xib */; };
+		275E3DEC27F467B20010EC30 /* LiveRoomBottomView.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DEB27F467B20010EC30 /* LiveRoomBottomView.m */; };
+		275E3DEE27F467BF0010EC30 /* LiveRoomBottomView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 275E3DED27F467BF0010EC30 /* LiveRoomBottomView.xib */; };
+		275E3DF127F467D80010EC30 /* SeatContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DF027F467D70010EC30 /* SeatContentView.m */; };
+		275E3DF627F467ED0010EC30 /* KSChatroomTextCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DF427F467ED0010EC30 /* KSChatroomTextCell.m */; };
+		275E3DF727F467ED0010EC30 /* LiveRoomLikeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DF527F467ED0010EC30 /* LiveRoomLikeLayer.m */; };
+		275E3DFA27F46B340010EC30 /* KSBeautySettingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E3DF927F46B340010EC30 /* KSBeautySettingView.m */; };
+		275E3DFC27F46B440010EC30 /* KSBeautySettingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 275E3DFB27F46B440010EC30 /* KSBeautySettingView.xib */; };
 		275E8A6927E18F2300DD3F6E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E8A6827E18F2300DD3F6E /* AppDelegate.m */; };
 		275E8A6927E18F2300DD3F6E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E8A6827E18F2300DD3F6E /* AppDelegate.m */; };
 		275E8A6F27E18F2300DD3F6E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E8A6E27E18F2300DD3F6E /* ViewController.m */; };
 		275E8A6F27E18F2300DD3F6E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 275E8A6E27E18F2300DD3F6E /* ViewController.m */; };
 		275E8A7227E18F2300DD3F6E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 275E8A7027E18F2300DD3F6E /* Main.storyboard */; };
 		275E8A7227E18F2300DD3F6E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 275E8A7027E18F2300DD3F6E /* Main.storyboard */; };
@@ -294,7 +322,6 @@
 		2779334327E3147C0010E277 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2779334227E3147B0010E277 /* OpenGLES.framework */; };
 		2779334327E3147C0010E277 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2779334227E3147B0010E277 /* OpenGLES.framework */; };
 		2779334527E314870010E277 /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2779334427E314870010E277 /* VideoToolbox.framework */; };
 		2779334527E314870010E277 /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2779334427E314870010E277 /* VideoToolbox.framework */; };
 		2779334727E3148E0010E277 /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2779334627E3148E0010E277 /* GLKit.framework */; };
 		2779334727E3148E0010E277 /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2779334627E3148E0010E277 /* GLKit.framework */; };
-		2779334A27E314C60010E277 /* KSNormalAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2779334827E314C50010E277 /* KSNormalAlertView.m */; };
 		2779335527E316DD0010E277 /* WMPlayerModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2779334D27E316DD0010E277 /* WMPlayerModel.m */; };
 		2779335527E316DD0010E277 /* WMPlayerModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2779334D27E316DD0010E277 /* WMPlayerModel.m */; };
 		2779335627E316DD0010E277 /* WMPlayer.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2779334F27E316DD0010E277 /* WMPlayer.bundle */; };
 		2779335627E316DD0010E277 /* WMPlayer.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2779334F27E316DD0010E277 /* WMPlayer.bundle */; };
 		2779335727E316DD0010E277 /* WMLightView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2779335227E316DD0010E277 /* WMLightView.m */; };
 		2779335727E316DD0010E277 /* WMLightView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2779335227E316DD0010E277 /* WMLightView.m */; };
@@ -378,6 +405,10 @@
 		27D83F4927F3EBC400062476 /* CreateLiveViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D83F4827F3EBC400062476 /* CreateLiveViewController.m */; };
 		27D83F4927F3EBC400062476 /* CreateLiveViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D83F4827F3EBC400062476 /* CreateLiveViewController.m */; };
 		27D83F4C27F3EC1500062476 /* CreateLiveBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D83F4B27F3EC1500062476 /* CreateLiveBodyView.m */; };
 		27D83F4C27F3EC1500062476 /* CreateLiveBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D83F4B27F3EC1500062476 /* CreateLiveBodyView.m */; };
 		27D83F4E27F3EC2100062476 /* CreateLiveBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 27D83F4D27F3EC2100062476 /* CreateLiveBodyView.xib */; };
 		27D83F4E27F3EC2100062476 /* CreateLiveBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 27D83F4D27F3EC2100062476 /* CreateLiveBodyView.xib */; };
+		27D83F5127F4036E00062476 /* KSNormalAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D83F5027F4036E00062476 /* KSNormalAlertView.m */; };
+		27D83F5427F408E000062476 /* LivePrepareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D83F5327F408E000062476 /* LivePrepareViewController.m */; };
+		27D83F5727F4224F00062476 /* LivePreviewBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D83F5627F4224F00062476 /* LivePreviewBodyView.m */; };
+		27D83F5927F4225D00062476 /* LivePreviewBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 27D83F5827F4225D00062476 /* LivePreviewBodyView.xib */; };
 		27F902F127E8614D00C08A19 /* SettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27F902F027E8614D00C08A19 /* SettingViewController.m */; };
 		27F902F127E8614D00C08A19 /* SettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27F902F027E8614D00C08A19 /* SettingViewController.m */; };
 		27F902F427E863B600C08A19 /* NetworkingCheckController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27F902F327E863B600C08A19 /* NetworkingCheckController.m */; };
 		27F902F427E863B600C08A19 /* NetworkingCheckController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27F902F327E863B600C08A19 /* NetworkingCheckController.m */; };
 		27F902FF27E864AE00C08A19 /* KSNetworkAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = 27F902F927E864A300C08A19 /* KSNetworkAlert.xib */; };
 		27F902FF27E864AE00C08A19 /* KSNetworkAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = 27F902F927E864A300C08A19 /* KSNetworkAlert.xib */; };
@@ -506,6 +537,58 @@
 		275B172D27EB27860081FDEF /* GroupCreateView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GroupCreateView.h; sourceTree = "<group>"; };
 		275B172D27EB27860081FDEF /* GroupCreateView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GroupCreateView.h; sourceTree = "<group>"; };
 		275B172E27EB27860081FDEF /* GroupCreateView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GroupCreateView.m; sourceTree = "<group>"; };
 		275B172E27EB27860081FDEF /* GroupCreateView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GroupCreateView.m; sourceTree = "<group>"; };
 		275B173027EB27960081FDEF /* GroupCreateView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GroupCreateView.xib; sourceTree = "<group>"; };
 		275B173027EB27960081FDEF /* GroupCreateView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GroupCreateView.xib; sourceTree = "<group>"; };
+		275E3DA127F441EC0010EC30 /* KSEnterLiveroomManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSEnterLiveroomManager.h; sourceTree = "<group>"; };
+		275E3DA227F441EC0010EC30 /* KSEnterLiveroomManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSEnterLiveroomManager.m; sourceTree = "<group>"; };
+		275E3DA427F442B70010EC30 /* LiveVideoRoomViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveVideoRoomViewController.h; sourceTree = "<group>"; };
+		275E3DA527F442B70010EC30 /* LiveVideoRoomViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiveVideoRoomViewController.m; sourceTree = "<group>"; };
+		275E3DA727F45A8A0010EC30 /* KSLiveStreamVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSLiveStreamVideo.h; sourceTree = "<group>"; };
+		275E3DA827F45A8A0010EC30 /* KSLiveStreamVideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSLiveStreamVideo.m; sourceTree = "<group>"; };
+		275E3DAB27F45BE90010EC30 /* KSChatroomMessageCenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSChatroomMessageCenter.h; sourceTree = "<group>"; };
+		275E3DAC27F45BE90010EC30 /* KSChatroomMessageCenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSChatroomMessageCenter.m; sourceTree = "<group>"; };
+		275E3DAE27F45CA60010EC30 /* KSLiveChatroomLike.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomLike.h; sourceTree = "<group>"; };
+		275E3DAF27F45CA60010EC30 /* KSLiveChatroomLike.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomLike.m; sourceTree = "<group>"; };
+		275E3DB127F45D380010EC30 /* KSLiveChatroomDownSeat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomDownSeat.h; sourceTree = "<group>"; };
+		275E3DB227F45D380010EC30 /* KSLiveChatroomDownSeat.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomDownSeat.m; sourceTree = "<group>"; };
+		275E3DB427F45DA60010EC30 /* KSLiveChatroomEnter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomEnter.h; sourceTree = "<group>"; };
+		275E3DB527F45DA60010EC30 /* KSLiveChatroomEnter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomEnter.m; sourceTree = "<group>"; };
+		275E3DBA27F45E750010EC30 /* KSLiveChatroomLeave.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomLeave.h; sourceTree = "<group>"; };
+		275E3DBB27F45E750010EC30 /* KSLiveChatroomLeave.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomLeave.m; sourceTree = "<group>"; };
+		275E3DBD27F45EB90010EC30 /* KSLiveChatroomUserQuit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomUserQuit.h; sourceTree = "<group>"; };
+		275E3DBE27F45EB90010EC30 /* KSLiveChatroomUserQuit.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomUserQuit.m; sourceTree = "<group>"; };
+		275E3DC027F45F3F0010EC30 /* KSLiveChatroomWelcome.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomWelcome.h; sourceTree = "<group>"; };
+		275E3DC127F45F3F0010EC30 /* KSLiveChatroomWelcome.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomWelcome.m; sourceTree = "<group>"; };
+		275E3DC327F460030010EC30 /* KSLiveChatroomClose.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomClose.h; sourceTree = "<group>"; };
+		275E3DC427F460030010EC30 /* KSLiveChatroomClose.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomClose.m; sourceTree = "<group>"; };
+		275E3DC627F460720010EC30 /* KSLiveChatroomKickOut.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomKickOut.h; sourceTree = "<group>"; };
+		275E3DC727F460720010EC30 /* KSLiveChatroomKickOut.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomKickOut.m; sourceTree = "<group>"; };
+		275E3DCF27F463140010EC30 /* KSLiveChatroomSeatApply.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomSeatApply.h; sourceTree = "<group>"; };
+		275E3DD027F463140010EC30 /* KSLiveChatroomSeatApply.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomSeatApply.m; sourceTree = "<group>"; };
+		275E3DD227F463580010EC30 /* KSLiveChatroomSeatResponse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomSeatResponse.h; sourceTree = "<group>"; };
+		275E3DD327F463580010EC30 /* KSLiveChatroomSeatResponse.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomSeatResponse.m; sourceTree = "<group>"; };
+		275E3DD627F467410010EC30 /* KSChatEmojiBoardView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSChatEmojiBoardView.m; sourceTree = "<group>"; };
+		275E3DD727F467410010EC30 /* KSChatInputBarControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSChatInputBarControl.h; sourceTree = "<group>"; };
+		275E3DD827F467410010EC30 /* KSChatInputView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSChatInputView.m; sourceTree = "<group>"; };
+		275E3DDA27F467410010EC30 /* KSChatEmojiCollectionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSChatEmojiCollectionCell.h; sourceTree = "<group>"; };
+		275E3DDB27F467410010EC30 /* KSChatEmojiCollectionCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSChatEmojiCollectionCell.m; sourceTree = "<group>"; };
+		275E3DDC27F467410010EC30 /* BaseEmoji.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = BaseEmoji.plist; sourceTree = "<group>"; };
+		275E3DDD27F467410010EC30 /* KSChatEmojiBoardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSChatEmojiBoardView.h; sourceTree = "<group>"; };
+		275E3DDE27F467410010EC30 /* KSChatInputBarControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSChatInputBarControl.m; sourceTree = "<group>"; };
+		275E3DDF27F467410010EC30 /* KSChatInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSChatInputView.h; sourceTree = "<group>"; };
+		275E3DE527F4677F0010EC30 /* LiveRoomHeadView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveRoomHeadView.h; sourceTree = "<group>"; };
+		275E3DE627F4677F0010EC30 /* LiveRoomHeadView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiveRoomHeadView.m; sourceTree = "<group>"; };
+		275E3DE827F4679D0010EC30 /* LiveRoomHeadView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LiveRoomHeadView.xib; sourceTree = "<group>"; };
+		275E3DEA27F467B20010EC30 /* LiveRoomBottomView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveRoomBottomView.h; sourceTree = "<group>"; };
+		275E3DEB27F467B20010EC30 /* LiveRoomBottomView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiveRoomBottomView.m; sourceTree = "<group>"; };
+		275E3DED27F467BF0010EC30 /* LiveRoomBottomView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LiveRoomBottomView.xib; sourceTree = "<group>"; };
+		275E3DEF27F467D70010EC30 /* SeatContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SeatContentView.h; sourceTree = "<group>"; };
+		275E3DF027F467D70010EC30 /* SeatContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SeatContentView.m; sourceTree = "<group>"; };
+		275E3DF227F467EC0010EC30 /* KSChatroomTextCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSChatroomTextCell.h; sourceTree = "<group>"; };
+		275E3DF327F467EC0010EC30 /* LiveRoomLikeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveRoomLikeLayer.h; sourceTree = "<group>"; };
+		275E3DF427F467ED0010EC30 /* KSChatroomTextCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSChatroomTextCell.m; sourceTree = "<group>"; };
+		275E3DF527F467ED0010EC30 /* LiveRoomLikeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveRoomLikeLayer.m; sourceTree = "<group>"; };
+		275E3DF827F46B340010EC30 /* KSBeautySettingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSBeautySettingView.h; sourceTree = "<group>"; };
+		275E3DF927F46B340010EC30 /* KSBeautySettingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSBeautySettingView.m; sourceTree = "<group>"; };
+		275E3DFB27F46B440010EC30 /* KSBeautySettingView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KSBeautySettingView.xib; sourceTree = "<group>"; };
 		275E8A6427E18F2300DD3F6E /* KulexiuForTeacher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KulexiuForTeacher.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		275E8A6427E18F2300DD3F6E /* KulexiuForTeacher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KulexiuForTeacher.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		275E8A6727E18F2300DD3F6E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
 		275E8A6727E18F2300DD3F6E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
 		275E8A6827E18F2300DD3F6E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
 		275E8A6827E18F2300DD3F6E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@@ -957,8 +1040,6 @@
 		2779334227E3147B0010E277 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
 		2779334227E3147B0010E277 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
 		2779334427E314870010E277 /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; };
 		2779334427E314870010E277 /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; };
 		2779334627E3148E0010E277 /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
 		2779334627E3148E0010E277 /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
-		2779334827E314C50010E277 /* KSNormalAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KSNormalAlertView.m; path = ../../../../../../DAYA_WORK/teadaya_ios/TeacherDaya/TeacherDaya/UI/NewClassroom/View/NormalAlertView/KSNormalAlertView.m; sourceTree = "<group>"; };
-		2779334927E314C60010E277 /* KSNormalAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KSNormalAlertView.h; path = ../../../../../../DAYA_WORK/teadaya_ios/TeacherDaya/TeacherDaya/UI/NewClassroom/View/NormalAlertView/KSNormalAlertView.h; sourceTree = "<group>"; };
 		2779334C27E316DD0010E277 /* WMLightView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLightView.h; sourceTree = "<group>"; };
 		2779334C27E316DD0010E277 /* WMLightView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLightView.h; sourceTree = "<group>"; };
 		2779334D27E316DD0010E277 /* WMPlayerModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMPlayerModel.m; sourceTree = "<group>"; };
 		2779334D27E316DD0010E277 /* WMPlayerModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMPlayerModel.m; sourceTree = "<group>"; };
 		2779334E27E316DD0010E277 /* FastForwardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastForwardView.h; sourceTree = "<group>"; };
 		2779334E27E316DD0010E277 /* FastForwardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastForwardView.h; sourceTree = "<group>"; };
@@ -1106,6 +1187,13 @@
 		27D83F4A27F3EC1500062476 /* CreateLiveBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CreateLiveBodyView.h; sourceTree = "<group>"; };
 		27D83F4A27F3EC1500062476 /* CreateLiveBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CreateLiveBodyView.h; sourceTree = "<group>"; };
 		27D83F4B27F3EC1500062476 /* CreateLiveBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CreateLiveBodyView.m; sourceTree = "<group>"; };
 		27D83F4B27F3EC1500062476 /* CreateLiveBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CreateLiveBodyView.m; sourceTree = "<group>"; };
 		27D83F4D27F3EC2100062476 /* CreateLiveBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CreateLiveBodyView.xib; sourceTree = "<group>"; };
 		27D83F4D27F3EC2100062476 /* CreateLiveBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CreateLiveBodyView.xib; sourceTree = "<group>"; };
+		27D83F4F27F4036E00062476 /* KSNormalAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSNormalAlertView.h; sourceTree = "<group>"; };
+		27D83F5027F4036E00062476 /* KSNormalAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSNormalAlertView.m; sourceTree = "<group>"; };
+		27D83F5227F408E000062476 /* LivePrepareViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LivePrepareViewController.h; sourceTree = "<group>"; };
+		27D83F5327F408E000062476 /* LivePrepareViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LivePrepareViewController.m; sourceTree = "<group>"; };
+		27D83F5527F4224F00062476 /* LivePreviewBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LivePreviewBodyView.h; sourceTree = "<group>"; };
+		27D83F5627F4224F00062476 /* LivePreviewBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LivePreviewBodyView.m; sourceTree = "<group>"; };
+		27D83F5827F4225D00062476 /* LivePreviewBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LivePreviewBodyView.xib; sourceTree = "<group>"; };
 		27F902EF27E8614D00C08A19 /* SettingViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SettingViewController.h; sourceTree = "<group>"; };
 		27F902EF27E8614D00C08A19 /* SettingViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SettingViewController.h; sourceTree = "<group>"; };
 		27F902F027E8614D00C08A19 /* SettingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SettingViewController.m; sourceTree = "<group>"; };
 		27F902F027E8614D00C08A19 /* SettingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SettingViewController.m; sourceTree = "<group>"; };
 		27F902F227E863B600C08A19 /* NetworkingCheckController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NetworkingCheckController.h; sourceTree = "<group>"; };
 		27F902F227E863B600C08A19 /* NetworkingCheckController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NetworkingCheckController.h; sourceTree = "<group>"; };
@@ -1290,6 +1378,59 @@
 			path = View;
 			path = View;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		275E3DAA27F45BBB0010EC30 /* LiveRoomMessage */ = {
+			isa = PBXGroup;
+			children = (
+				275E3DAB27F45BE90010EC30 /* KSChatroomMessageCenter.h */,
+				275E3DAC27F45BE90010EC30 /* KSChatroomMessageCenter.m */,
+				275E3DAE27F45CA60010EC30 /* KSLiveChatroomLike.h */,
+				275E3DAF27F45CA60010EC30 /* KSLiveChatroomLike.m */,
+				275E3DB127F45D380010EC30 /* KSLiveChatroomDownSeat.h */,
+				275E3DB227F45D380010EC30 /* KSLiveChatroomDownSeat.m */,
+				275E3DB427F45DA60010EC30 /* KSLiveChatroomEnter.h */,
+				275E3DB527F45DA60010EC30 /* KSLiveChatroomEnter.m */,
+				275E3DBA27F45E750010EC30 /* KSLiveChatroomLeave.h */,
+				275E3DBB27F45E750010EC30 /* KSLiveChatroomLeave.m */,
+				275E3DBD27F45EB90010EC30 /* KSLiveChatroomUserQuit.h */,
+				275E3DBE27F45EB90010EC30 /* KSLiveChatroomUserQuit.m */,
+				275E3DC027F45F3F0010EC30 /* KSLiveChatroomWelcome.h */,
+				275E3DC127F45F3F0010EC30 /* KSLiveChatroomWelcome.m */,
+				275E3DC327F460030010EC30 /* KSLiveChatroomClose.h */,
+				275E3DC427F460030010EC30 /* KSLiveChatroomClose.m */,
+				275E3DC627F460720010EC30 /* KSLiveChatroomKickOut.h */,
+				275E3DC727F460720010EC30 /* KSLiveChatroomKickOut.m */,
+				275E3DCF27F463140010EC30 /* KSLiveChatroomSeatApply.h */,
+				275E3DD027F463140010EC30 /* KSLiveChatroomSeatApply.m */,
+				275E3DD227F463580010EC30 /* KSLiveChatroomSeatResponse.h */,
+				275E3DD327F463580010EC30 /* KSLiveChatroomSeatResponse.m */,
+			);
+			path = LiveRoomMessage;
+			sourceTree = "<group>";
+		};
+		275E3DD527F467410010EC30 /* InputBar */ = {
+			isa = PBXGroup;
+			children = (
+				275E3DD927F467410010EC30 /* Cell */,
+				275E3DDD27F467410010EC30 /* KSChatEmojiBoardView.h */,
+				275E3DD627F467410010EC30 /* KSChatEmojiBoardView.m */,
+				275E3DD727F467410010EC30 /* KSChatInputBarControl.h */,
+				275E3DDE27F467410010EC30 /* KSChatInputBarControl.m */,
+				275E3DDF27F467410010EC30 /* KSChatInputView.h */,
+				275E3DD827F467410010EC30 /* KSChatInputView.m */,
+			);
+			path = InputBar;
+			sourceTree = "<group>";
+		};
+		275E3DD927F467410010EC30 /* Cell */ = {
+			isa = PBXGroup;
+			children = (
+				275E3DDA27F467410010EC30 /* KSChatEmojiCollectionCell.h */,
+				275E3DDB27F467410010EC30 /* KSChatEmojiCollectionCell.m */,
+				275E3DDC27F467410010EC30 /* BaseEmoji.plist */,
+			);
+			path = Cell;
+			sourceTree = "<group>";
+		};
 		275E8A5B27E18F2300DD3F6E = {
 		275E8A5B27E18F2300DD3F6E = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -1724,8 +1865,8 @@
 		2779312227E30FC00010E277 /* Custom */ = {
 		2779312227E30FC00010E277 /* Custom */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
-				2779334927E314C60010E277 /* KSNormalAlertView.h */,
-				2779334827E314C50010E277 /* KSNormalAlertView.m */,
+				27D83F4F27F4036E00062476 /* KSNormalAlertView.h */,
+				27D83F5027F4036E00062476 /* KSNormalAlertView.m */,
 				2779316F27E30FC00010E277 /* GRCreateManager.h */,
 				2779316F27E30FC00010E277 /* GRCreateManager.h */,
 				2779312927E30FC00010E277 /* GRCreateManager.m */,
 				2779312927E30FC00010E277 /* GRCreateManager.m */,
 				2779312A27E30FC00010E277 /* GRScanManager.h */,
 				2779312A27E30FC00010E277 /* GRScanManager.h */,
@@ -2421,6 +2562,7 @@
 		27D83F4327F3EBAA00062476 /* Live */ = {
 		27D83F4327F3EBAA00062476 /* Live */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				275E3DAA27F45BBB0010EC30 /* LiveRoomMessage */,
 				27D83F4427F3EBAA00062476 /* Controller */,
 				27D83F4427F3EBAA00062476 /* Controller */,
 				27D83F4527F3EBAA00062476 /* Model */,
 				27D83F4527F3EBAA00062476 /* Model */,
 				27D83F4627F3EBAA00062476 /* View */,
 				27D83F4627F3EBAA00062476 /* View */,
@@ -2433,6 +2575,10 @@
 			children = (
 			children = (
 				27D83F4727F3EBC400062476 /* CreateLiveViewController.h */,
 				27D83F4727F3EBC400062476 /* CreateLiveViewController.h */,
 				27D83F4827F3EBC400062476 /* CreateLiveViewController.m */,
 				27D83F4827F3EBC400062476 /* CreateLiveViewController.m */,
+				27D83F5227F408E000062476 /* LivePrepareViewController.h */,
+				27D83F5327F408E000062476 /* LivePrepareViewController.m */,
+				275E3DA427F442B70010EC30 /* LiveVideoRoomViewController.h */,
+				275E3DA527F442B70010EC30 /* LiveVideoRoomViewController.m */,
 			);
 			);
 			path = Controller;
 			path = Controller;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -2440,6 +2586,10 @@
 		27D83F4527F3EBAA00062476 /* Model */ = {
 		27D83F4527F3EBAA00062476 /* Model */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				275E3DA127F441EC0010EC30 /* KSEnterLiveroomManager.h */,
+				275E3DA227F441EC0010EC30 /* KSEnterLiveroomManager.m */,
+				275E3DA727F45A8A0010EC30 /* KSLiveStreamVideo.h */,
+				275E3DA827F45A8A0010EC30 /* KSLiveStreamVideo.m */,
 			);
 			);
 			path = Model;
 			path = Model;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -2447,9 +2597,28 @@
 		27D83F4627F3EBAA00062476 /* View */ = {
 		27D83F4627F3EBAA00062476 /* View */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				275E3DD527F467410010EC30 /* InputBar */,
 				27D83F4A27F3EC1500062476 /* CreateLiveBodyView.h */,
 				27D83F4A27F3EC1500062476 /* CreateLiveBodyView.h */,
 				27D83F4B27F3EC1500062476 /* CreateLiveBodyView.m */,
 				27D83F4B27F3EC1500062476 /* CreateLiveBodyView.m */,
 				27D83F4D27F3EC2100062476 /* CreateLiveBodyView.xib */,
 				27D83F4D27F3EC2100062476 /* CreateLiveBodyView.xib */,
+				27D83F5527F4224F00062476 /* LivePreviewBodyView.h */,
+				27D83F5627F4224F00062476 /* LivePreviewBodyView.m */,
+				27D83F5827F4225D00062476 /* LivePreviewBodyView.xib */,
+				275E3DE527F4677F0010EC30 /* LiveRoomHeadView.h */,
+				275E3DE627F4677F0010EC30 /* LiveRoomHeadView.m */,
+				275E3DE827F4679D0010EC30 /* LiveRoomHeadView.xib */,
+				275E3DEA27F467B20010EC30 /* LiveRoomBottomView.h */,
+				275E3DEB27F467B20010EC30 /* LiveRoomBottomView.m */,
+				275E3DED27F467BF0010EC30 /* LiveRoomBottomView.xib */,
+				275E3DEF27F467D70010EC30 /* SeatContentView.h */,
+				275E3DF027F467D70010EC30 /* SeatContentView.m */,
+				275E3DF227F467EC0010EC30 /* KSChatroomTextCell.h */,
+				275E3DF427F467ED0010EC30 /* KSChatroomTextCell.m */,
+				275E3DF327F467EC0010EC30 /* LiveRoomLikeLayer.h */,
+				275E3DF527F467ED0010EC30 /* LiveRoomLikeLayer.m */,
+				275E3DF827F46B340010EC30 /* KSBeautySettingView.h */,
+				275E3DF927F46B340010EC30 /* KSBeautySettingView.m */,
+				275E3DFB27F46B440010EC30 /* KSBeautySettingView.xib */,
 			);
 			);
 			path = View;
 			path = View;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -2890,6 +3059,7 @@
 				275B173127EB27960081FDEF /* GroupCreateView.xib in Resources */,
 				275B173127EB27960081FDEF /* GroupCreateView.xib in Resources */,
 				2755C08E27ED5DB2007D9070 /* GroupApplyChooseCell.xib in Resources */,
 				2755C08E27ED5DB2007D9070 /* GroupApplyChooseCell.xib in Resources */,
 				277931CE27E30FC20010E277 /* KSPremissionAlert.xib in Resources */,
 				277931CE27E30FC20010E277 /* KSPremissionAlert.xib in Resources */,
+				275E3DFC27F46B440010EC30 /* KSBeautySettingView.xib in Resources */,
 				2779335627E316DD0010E277 /* WMPlayer.bundle in Resources */,
 				2779335627E316DD0010E277 /* WMPlayer.bundle in Resources */,
 				275E8A7427E18F2800DD3F6E /* Assets.xcassets in Resources */,
 				275E8A7427E18F2800DD3F6E /* Assets.xcassets in Resources */,
 				2755C06927EC71C8007D9070 /* GroupSettingBodyView.xib in Resources */,
 				2755C06927EC71C8007D9070 /* GroupSettingBodyView.xib in Resources */,
@@ -2903,8 +3073,10 @@
 				2780A06627E81E5E00447CFD /* MineNavView.xib in Resources */,
 				2780A06627E81E5E00447CFD /* MineNavView.xib in Resources */,
 				27A2F62A27E6C996009E2380 /* KSImageAlert.xib in Resources */,
 				27A2F62A27E6C996009E2380 /* KSImageAlert.xib in Resources */,
 				2708565327ED8B8C00EC8E72 /* GroupApplyChooseAllCell.xib in Resources */,
 				2708565327ED8B8C00EC8E72 /* GroupApplyChooseAllCell.xib in Resources */,
+				275E3DEE27F467BF0010EC30 /* LiveRoomBottomView.xib in Resources */,
 				27BC3B2B27F2DB9600D81E30 /* MusicUploadView.xib in Resources */,
 				27BC3B2B27F2DB9600D81E30 /* MusicUploadView.xib in Resources */,
 				2723B68E27F1686100E0B90B /* HomeNavView.xib in Resources */,
 				2723B68E27F1686100E0B90B /* HomeNavView.xib in Resources */,
+				275E3DE927F4679E0010EC30 /* LiveRoomHeadView.xib in Resources */,
 				27D83F4E27F3EC2100062476 /* CreateLiveBodyView.xib in Resources */,
 				27D83F4E27F3EC2100062476 /* CreateLiveBodyView.xib in Resources */,
 				27F9030827E86CCB00C08A19 /* DeviceCheckView.xib in Resources */,
 				27F9030827E86CCB00C08A19 /* DeviceCheckView.xib in Resources */,
 				2723B69327F1806500E0B90B /* HomeHeadView.xib in Resources */,
 				2723B69327F1806500E0B90B /* HomeHeadView.xib in Resources */,
@@ -2916,6 +3088,7 @@
 				277D433127E9A50800107DB7 /* PhoneCheckBodyView.xib in Resources */,
 				277D433127E9A50800107DB7 /* PhoneCheckBodyView.xib in Resources */,
 				2708565927ED961900EC8E72 /* ApplyBottomView.xib in Resources */,
 				2708565927ED961900EC8E72 /* ApplyBottomView.xib in Resources */,
 				275B170D27EB14AC0081FDEF /* KSChatListSearchView.xib in Resources */,
 				275B170D27EB14AC0081FDEF /* KSChatListSearchView.xib in Resources */,
+				27D83F5927F4225D00062476 /* LivePreviewBodyView.xib in Resources */,
 				2779362E27E33C360010E277 /* LoginBodyView.xib in Resources */,
 				2779362E27E33C360010E277 /* LoginBodyView.xib in Resources */,
 				2723B68927F1643B00E0B90B /* HomeBodyView.xib in Resources */,
 				2723B68927F1643B00E0B90B /* HomeBodyView.xib in Resources */,
 				27A54CF927E9BD8B007309A3 /* FeedbackBodyView.xib in Resources */,
 				27A54CF927E9BD8B007309A3 /* FeedbackBodyView.xib in Resources */,
@@ -2928,6 +3101,7 @@
 				27BC3B2627F2B76900D81E30 /* MusicMessageCell.xib in Resources */,
 				27BC3B2627F2B76900D81E30 /* MusicMessageCell.xib in Resources */,
 				27F9CB0127EC3D42003E0FE4 /* GroupListViewCell.xib in Resources */,
 				27F9CB0127EC3D42003E0FE4 /* GroupListViewCell.xib in Resources */,
 				27D5D5D227EDBA9400B4720C /* NoticeEditBodyView.xib in Resources */,
 				27D5D5D227EDBA9400B4720C /* NoticeEditBodyView.xib in Resources */,
+				275E3DE327F467410010EC30 /* BaseEmoji.plist in Resources */,
 				273C75A027E9681700F7C26F /* SettingBodyView.xib in Resources */,
 				273C75A027E9681700F7C26F /* SettingBodyView.xib in Resources */,
 				2779329A27E30FEB0010E277 /* mss_browseLoading@2x.png in Resources */,
 				2779329A27E30FEB0010E277 /* mss_browseLoading@2x.png in Resources */,
 				27F9CAFC27EC1AF3003E0FE4 /* ContractListCell.xib in Resources */,
 				27F9CAFC27EC1AF3003E0FE4 /* ContractListCell.xib in Resources */,
@@ -3016,6 +3190,7 @@
 			files = (
 			files = (
 				2779323227E30FC30010E277 /* ALCalendarManager.m in Sources */,
 				2779323227E30FC30010E277 /* ALCalendarManager.m in Sources */,
 				2779326F27E30FD80010E277 /* FSCalendarHeaderView.m in Sources */,
 				2779326F27E30FD80010E277 /* FSCalendarHeaderView.m in Sources */,
+				275E3DF727F467ED0010EC30 /* LiveRoomLikeLayer.m in Sources */,
 				277931E827E30FC20010E277 /* KSUtilities.m in Sources */,
 				277931E827E30FC20010E277 /* KSUtilities.m in Sources */,
 				2779326327E30FD80010E277 /* FSCalendarCollectionView.m in Sources */,
 				2779326327E30FD80010E277 /* FSCalendarCollectionView.m in Sources */,
 				2779324027E30FC30010E277 /* VoNetworking+RequestManager.m in Sources */,
 				2779324027E30FC30010E277 /* VoNetworking+RequestManager.m in Sources */,
@@ -3023,6 +3198,7 @@
 				27BC3B2927F2DB8600D81E30 /* MusicUploadView.m in Sources */,
 				27BC3B2927F2DB8600D81E30 /* MusicUploadView.m in Sources */,
 				277931F327E30FC20010E277 /* UIView+Hints.m in Sources */,
 				277931F327E30FC20010E277 /* UIView+Hints.m in Sources */,
 				2779321927E30FC30010E277 /* UITextView_Toolbar.m in Sources */,
 				2779321927E30FC30010E277 /* UITextView_Toolbar.m in Sources */,
+				275E3DBF27F45EB90010EC30 /* KSLiveChatroomUserQuit.m in Sources */,
 				27A54CE427E9B144007309A3 /* ModifyNameViewController.m in Sources */,
 				27A54CE427E9B144007309A3 /* ModifyNameViewController.m in Sources */,
 				2708565D27EDA83100EC8E72 /* GroupMemberListCell.m in Sources */,
 				2708565D27EDA83100EC8E72 /* GroupMemberListCell.m in Sources */,
 				277931BF27E30FC20010E277 /* CoinModel.m in Sources */,
 				277931BF27E30FC20010E277 /* CoinModel.m in Sources */,
@@ -3059,6 +3235,7 @@
 				275B170827EB13D50081FDEF /* KSChatConversationViewController.m in Sources */,
 				275B170827EB13D50081FDEF /* KSChatConversationViewController.m in Sources */,
 				2779320527E30FC30010E277 /* KSAudioRecordFileManager.m in Sources */,
 				2779320527E30FC30010E277 /* KSAudioRecordFileManager.m in Sources */,
 				277931C627E30FC20010E277 /* NSObject+KSImpChangeTool.m in Sources */,
 				277931C627E30FC20010E277 /* NSObject+KSImpChangeTool.m in Sources */,
+				275E3DAD27F45BE90010EC30 /* KSChatroomMessageCenter.m in Sources */,
 				2779322C27E30FC30010E277 /* ALCalendarHeader.m in Sources */,
 				2779322C27E30FC30010E277 /* ALCalendarHeader.m in Sources */,
 				2779360F27E32BF20010E277 /* HomeViewController.m in Sources */,
 				2779360F27E32BF20010E277 /* HomeViewController.m in Sources */,
 				27A2F62927E6C996009E2380 /* KSImageAlert.m in Sources */,
 				27A2F62927E6C996009E2380 /* KSImageAlert.m in Sources */,
@@ -3067,6 +3244,7 @@
 				2779335727E316DD0010E277 /* WMLightView.m in Sources */,
 				2779335727E316DD0010E277 /* WMLightView.m in Sources */,
 				277931DA27E30FC20010E277 /* UIImage+UIImageScale.m in Sources */,
 				277931DA27E30FC20010E277 /* UIImage+UIImageScale.m in Sources */,
 				277931DF27E30FC20010E277 /* UIControl+ButtonAction.m in Sources */,
 				277931DF27E30FC20010E277 /* UIControl+ButtonAction.m in Sources */,
+				275E3DB627F45DA60010EC30 /* KSLiveChatroomEnter.m in Sources */,
 				27BC3B2527F2B76900D81E30 /* MusicMessageCell.m in Sources */,
 				27BC3B2527F2B76900D81E30 /* MusicMessageCell.m in Sources */,
 				277931ED27E30FC20010E277 /* zhPopupController.m in Sources */,
 				277931ED27E30FC20010E277 /* zhPopupController.m in Sources */,
 				275FA19727E723D700CFEA2E /* KSLocalWebViewController.m in Sources */,
 				275FA19727E723D700CFEA2E /* KSLocalWebViewController.m in Sources */,
@@ -3082,6 +3260,7 @@
 				277931F027E30FC20010E277 /* UIView+AddConstraints.m in Sources */,
 				277931F027E30FC20010E277 /* UIView+AddConstraints.m in Sources */,
 				277D432527E9A46A00107DB7 /* ModifyPhoneCheckController.m in Sources */,
 				277D432527E9A46A00107DB7 /* ModifyPhoneCheckController.m in Sources */,
 				27F9CAF727EC1A16003E0FE4 /* UITableView+SCIndexView.m in Sources */,
 				27F9CAF727EC1A16003E0FE4 /* UITableView+SCIndexView.m in Sources */,
+				275E3DC827F460720010EC30 /* KSLiveChatroomKickOut.m in Sources */,
 				2779361B27E32C3A0010E277 /* MineViewController.m in Sources */,
 				2779361B27E32C3A0010E277 /* MineViewController.m in Sources */,
 				27A54D0127E9CD38007309A3 /* AddressViewController.m in Sources */,
 				27A54D0127E9CD38007309A3 /* AddressViewController.m in Sources */,
 				2779321B27E30FC30010E277 /* SearchView.m in Sources */,
 				2779321B27E30FC30010E277 /* SearchView.m in Sources */,
@@ -3089,6 +3268,8 @@
 				277932BC27E30FFE0010E277 /* TAAbstractDotView.m in Sources */,
 				277932BC27E30FFE0010E277 /* TAAbstractDotView.m in Sources */,
 				277931D927E30FC20010E277 /* NSObject+AutoProperty.m in Sources */,
 				277931D927E30FC20010E277 /* NSObject+AutoProperty.m in Sources */,
 				2779324127E30FC30010E277 /* VoNetWorking.m in Sources */,
 				2779324127E30FC30010E277 /* VoNetWorking.m in Sources */,
+				275E3DF127F467D80010EC30 /* SeatContentView.m in Sources */,
+				275E3DD127F463140010EC30 /* KSLiveChatroomSeatApply.m in Sources */,
 				2779322427E30FC30010E277 /* ShopButton.m in Sources */,
 				2779322427E30FC30010E277 /* ShopButton.m in Sources */,
 				277932EC27E310070010E277 /* TZImageManager.m in Sources */,
 				277932EC27E310070010E277 /* TZImageManager.m in Sources */,
 				2779323727E30FC30010E277 /* LLFileManager.m in Sources */,
 				2779323727E30FC30010E277 /* LLFileManager.m in Sources */,
@@ -3096,6 +3277,8 @@
 				277932F027E310070010E277 /* TZImagePickerController.m in Sources */,
 				277932F027E310070010E277 /* TZImagePickerController.m in Sources */,
 				275FA1A327E7311700CFEA2E /* KSRCIMDataSource.m in Sources */,
 				275FA1A327E7311700CFEA2E /* KSRCIMDataSource.m in Sources */,
 				275B171727EB1B930081FDEF /* KSSearchHistoryMessageController.m in Sources */,
 				275B171727EB1B930081FDEF /* KSSearchHistoryMessageController.m in Sources */,
+				275E3DE227F467410010EC30 /* KSChatEmojiCollectionCell.m in Sources */,
+				275E3DC227F45F3F0010EC30 /* KSLiveChatroomWelcome.m in Sources */,
 				27F9030E27E875DD00C08A19 /* AudioPlayManager.m in Sources */,
 				27F9030E27E875DD00C08A19 /* AudioPlayManager.m in Sources */,
 				277935E227E327F00010E277 /* KSTabBarViewController.m in Sources */,
 				277935E227E327F00010E277 /* KSTabBarViewController.m in Sources */,
 				2779322727E30FC30010E277 /* KSInputView.m in Sources */,
 				2779322727E30FC30010E277 /* KSInputView.m in Sources */,
@@ -3124,6 +3307,8 @@
 				277932B727E30FFE0010E277 /* SDQWMaskCustomModel.m in Sources */,
 				277932B727E30FFE0010E277 /* SDQWMaskCustomModel.m in Sources */,
 				277931FD27E30FC30010E277 /* AnimationContoller.m in Sources */,
 				277931FD27E30FC30010E277 /* AnimationContoller.m in Sources */,
 				277931FC27E30FC30010E277 /* KLTNavigationController.m in Sources */,
 				277931FC27E30FC30010E277 /* KLTNavigationController.m in Sources */,
+				275E3DBC27F45E750010EC30 /* KSLiveChatroomLeave.m in Sources */,
+				27D83F5127F4036E00062476 /* KSNormalAlertView.m in Sources */,
 				2779323F27E30FC30010E277 /* VoMemoryCache.m in Sources */,
 				2779323F27E30FC30010E277 /* VoMemoryCache.m in Sources */,
 				277931C027E30FC20010E277 /* ArchiveTools.m in Sources */,
 				277931C027E30FC20010E277 /* ArchiveTools.m in Sources */,
 				277931FA27E30FC20010E277 /* CALayer+Layout.m in Sources */,
 				277931FA27E30FC20010E277 /* CALayer+Layout.m in Sources */,
@@ -3136,6 +3321,7 @@
 				2779321627E30FC30010E277 /* StoreShopCaterview.m in Sources */,
 				2779321627E30FC30010E277 /* StoreShopCaterview.m in Sources */,
 				277931D127E30FC20010E277 /* UrlDecode.m in Sources */,
 				277931D127E30FC20010E277 /* UrlDecode.m in Sources */,
 				277931F227E30FC20010E277 /* NSDictionary+Extension.m in Sources */,
 				277931F227E30FC20010E277 /* NSDictionary+Extension.m in Sources */,
+				27D83F5727F4224F00062476 /* LivePreviewBodyView.m in Sources */,
 				277932B927E30FFE0010E277 /* TADotView.m in Sources */,
 				277932B927E30FFE0010E277 /* TADotView.m in Sources */,
 				2773204D27EDB72B008FAECA /* LFPopupMenu.m in Sources */,
 				2773204D27EDB72B008FAECA /* LFPopupMenu.m in Sources */,
 				2779320127E30FC30010E277 /* KSStatusView.m in Sources */,
 				2779320127E30FC30010E277 /* KSStatusView.m in Sources */,
@@ -3193,13 +3379,16 @@
 				2779323827E30FC30010E277 /* LLPhoto.m in Sources */,
 				2779323827E30FC30010E277 /* LLPhoto.m in Sources */,
 				2779331627E310AA0010E277 /* UIView+ShowProgress.m in Sources */,
 				2779331627E310AA0010E277 /* UIView+ShowProgress.m in Sources */,
 				277935E527E328C00010E277 /* CustomNavViewController.m in Sources */,
 				277935E527E328C00010E277 /* CustomNavViewController.m in Sources */,
+				275E3DE027F467410010EC30 /* KSChatEmojiBoardView.m in Sources */,
 				277931CC27E30FC20010E277 /* KSGifRefreshFooter.m in Sources */,
 				277931CC27E30FC20010E277 /* KSGifRefreshFooter.m in Sources */,
 				2779321127E30FC30010E277 /* YKMultiLevelTableView.m in Sources */,
 				2779321127E30FC30010E277 /* YKMultiLevelTableView.m in Sources */,
 				277931CB27E30FC20010E277 /* KSGifRefreshHeader.m in Sources */,
 				277931CB27E30FC20010E277 /* KSGifRefreshHeader.m in Sources */,
 				2755C07E27EC95CC007D9070 /* GroupNoticeViewController.m in Sources */,
 				2755C07E27EC95CC007D9070 /* GroupNoticeViewController.m in Sources */,
+				275E3DA627F442B70010EC30 /* LiveVideoRoomViewController.m in Sources */,
 				2779328F27E30FEB0010E277 /* MSSBrowseLocalViewController.m in Sources */,
 				2779328F27E30FEB0010E277 /* MSSBrowseLocalViewController.m in Sources */,
 				27A54CF127E9BD3B007309A3 /* FeedbackViewController.m in Sources */,
 				27A54CF127E9BD3B007309A3 /* FeedbackViewController.m in Sources */,
 				277932E527E310070010E277 /* TZVideoCropController.m in Sources */,
 				277932E527E310070010E277 /* TZVideoCropController.m in Sources */,
+				275E3DE127F467410010EC30 /* KSChatInputView.m in Sources */,
 				2779335527E316DD0010E277 /* WMPlayerModel.m in Sources */,
 				2779335527E316DD0010E277 /* WMPlayerModel.m in Sources */,
 				277931BE27E30FC20010E277 /* NSObject+Archiving.m in Sources */,
 				277931BE27E30FC20010E277 /* NSObject+Archiving.m in Sources */,
 				2728086727E6BD1F00DB71EA /* FirstSettingViewController.m in Sources */,
 				2728086727E6BD1F00DB71EA /* FirstSettingViewController.m in Sources */,
@@ -3217,6 +3406,7 @@
 				2779336027E31CB40010E277 /* UIView+KSExtension.m in Sources */,
 				2779336027E31CB40010E277 /* UIView+KSExtension.m in Sources */,
 				2779321C27E30FC30010E277 /* prodectButton.m in Sources */,
 				2779321C27E30FC30010E277 /* prodectButton.m in Sources */,
 				27F9CAEA27EC1780003E0FE4 /* KSJXBodyView.m in Sources */,
 				27F9CAEA27EC1780003E0FE4 /* KSJXBodyView.m in Sources */,
+				275E3DF627F467ED0010EC30 /* KSChatroomTextCell.m in Sources */,
 				2779323D27E30FC30010E277 /* VoDiskCache.m in Sources */,
 				2779323D27E30FC30010E277 /* VoDiskCache.m in Sources */,
 				277931D727E30FC20010E277 /* UIImage+ResizeImage.m in Sources */,
 				277931D727E30FC20010E277 /* UIImage+ResizeImage.m in Sources */,
 				2779329927E30FEB0010E277 /* MSSBrowseActionSheetCell.m in Sources */,
 				2779329927E30FEB0010E277 /* MSSBrowseActionSheetCell.m in Sources */,
@@ -3228,6 +3418,7 @@
 				277932E227E310070010E277 /* TZImageCropManager.m in Sources */,
 				277932E227E310070010E277 /* TZImageCropManager.m in Sources */,
 				277932B327E30FFE0010E277 /* QWdynamicModel.m in Sources */,
 				277932B327E30FFE0010E277 /* QWdynamicModel.m in Sources */,
 				2779329627E30FEB0010E277 /* MSSBrowseZoomScrollView.m in Sources */,
 				2779329627E30FEB0010E277 /* MSSBrowseZoomScrollView.m in Sources */,
+				275E3DE727F4677F0010EC30 /* LiveRoomHeadView.m in Sources */,
 				2779320427E30FC30010E277 /* KSHoldButton.m in Sources */,
 				2779320427E30FC30010E277 /* KSHoldButton.m in Sources */,
 				2779320627E30FC30010E277 /* UIView+ValueAdd.m in Sources */,
 				2779320627E30FC30010E277 /* UIView+ValueAdd.m in Sources */,
 				2779329B27E30FEB0010E277 /* UIView+MSSLayout.m in Sources */,
 				2779329B27E30FEB0010E277 /* UIView+MSSLayout.m in Sources */,
@@ -3236,6 +3427,8 @@
 				27A54CF427E9BD53007309A3 /* AboutUsViewController.m in Sources */,
 				27A54CF427E9BD53007309A3 /* AboutUsViewController.m in Sources */,
 				277931D827E30FC20010E277 /* UIButton+HasChooseImage.m in Sources */,
 				277931D827E30FC20010E277 /* UIButton+HasChooseImage.m in Sources */,
 				277931E627E30FC20010E277 /* UITextView+ZWLimitCounter.m in Sources */,
 				277931E627E30FC20010E277 /* UITextView+ZWLimitCounter.m in Sources */,
+				275E3DEC27F467B20010EC30 /* LiveRoomBottomView.m in Sources */,
+				27D83F5427F408E000062476 /* LivePrepareViewController.m in Sources */,
 				2780A06427E81E4900447CFD /* MineNavView.m in Sources */,
 				2780A06427E81E4900447CFD /* MineNavView.m in Sources */,
 				2779326E27E30FD80010E277 /* FSCalendarCalculator.m in Sources */,
 				2779326E27E30FD80010E277 /* FSCalendarCalculator.m in Sources */,
 				2779320027E30FC30010E277 /* QCCountdownButton.m in Sources */,
 				2779320027E30FC30010E277 /* QCCountdownButton.m in Sources */,
@@ -3282,6 +3475,7 @@
 				277931CF27E30FC20010E277 /* UIView+XIBView.m in Sources */,
 				277931CF27E30FC20010E277 /* UIView+XIBView.m in Sources */,
 				27F9CB0427EC5446003E0FE4 /* GroupSettingViewController.m in Sources */,
 				27F9CB0427EC5446003E0FE4 /* GroupSettingViewController.m in Sources */,
 				2779320F27E30FC30010E277 /* shopview.m in Sources */,
 				2779320F27E30FC30010E277 /* shopview.m in Sources */,
+				275E3DC527F460030010EC30 /* KSLiveChatroomClose.m in Sources */,
 				277932B527E30FFE0010E277 /* SDCycleScrollView.m in Sources */,
 				277932B527E30FFE0010E277 /* SDCycleScrollView.m in Sources */,
 				2779323627E30FC30010E277 /* LLImageCache.m in Sources */,
 				2779323627E30FC30010E277 /* LLImageCache.m in Sources */,
 				277931D527E30FC20010E277 /* UIView+KSLayer.m in Sources */,
 				277931D527E30FC20010E277 /* UIView+KSLayer.m in Sources */,
@@ -3295,14 +3489,17 @@
 				277932BA27E30FFE0010E277 /* TAPageControl.m in Sources */,
 				277932BA27E30FFE0010E277 /* TAPageControl.m in Sources */,
 				2779329127E30FEB0010E277 /* MSSBrowseModel.m in Sources */,
 				2779329127E30FEB0010E277 /* MSSBrowseModel.m in Sources */,
 				277931E227E30FC20010E277 /* UIViewController+zhStatusBarStyle.m in Sources */,
 				277931E227E30FC20010E277 /* UIViewController+zhStatusBarStyle.m in Sources */,
+				275E3DFA27F46B340010EC30 /* KSBeautySettingView.m in Sources */,
 				2779328E27E30FEB0010E277 /* MSSBrowseLoadingImageView.m in Sources */,
 				2779328E27E30FEB0010E277 /* MSSBrowseLoadingImageView.m in Sources */,
 				2779335827E316DD0010E277 /* FastForwardView.m in Sources */,
 				2779335827E316DD0010E277 /* FastForwardView.m in Sources */,
 				277935DC27E326650010E277 /* RecordCheckManager.m in Sources */,
 				277935DC27E326650010E277 /* RecordCheckManager.m in Sources */,
+				275E3DB327F45D380010EC30 /* KSLiveChatroomDownSeat.m in Sources */,
 				275B16FA27EB08230081FDEF /* CreateFansGroupViewController.m in Sources */,
 				275B16FA27EB08230081FDEF /* CreateFansGroupViewController.m in Sources */,
 				277931CA27E30FC20010E277 /* KSAudioSessionManager.m in Sources */,
 				277931CA27E30FC20010E277 /* KSAudioSessionManager.m in Sources */,
 				27F9030227E864AE00C08A19 /* KSNetworkAlert.m in Sources */,
 				27F9030227E864AE00C08A19 /* KSNetworkAlert.m in Sources */,
 				275B170B27EB14A00081FDEF /* KSChatListSearchView.m in Sources */,
 				275B170B27EB14A00081FDEF /* KSChatListSearchView.m in Sources */,
 				2779326D27E30FD80010E277 /* FSCalendarConstants.m in Sources */,
 				2779326D27E30FD80010E277 /* FSCalendarConstants.m in Sources */,
+				275E3DD427F463580010EC30 /* KSLiveChatroomSeatResponse.m in Sources */,
 				2779327027E30FD80010E277 /* FSCalendarTransitionCoordinator.m in Sources */,
 				2779327027E30FD80010E277 /* FSCalendarTransitionCoordinator.m in Sources */,
 				2779320727E30FC30010E277 /* KSRecordStatusView.m in Sources */,
 				2779320727E30FC30010E277 /* KSRecordStatusView.m in Sources */,
 				2779329527E30FEB0010E277 /* MSSBrowseBaseViewController.m in Sources */,
 				2779329527E30FEB0010E277 /* MSSBrowseBaseViewController.m in Sources */,
@@ -3322,9 +3519,11 @@
 				2779329427E30FEB0010E277 /* UIImage+MSSScale.m in Sources */,
 				2779329427E30FEB0010E277 /* UIImage+MSSScale.m in Sources */,
 				277931EF27E30FC20010E277 /* NSObject+Parse.m in Sources */,
 				277931EF27E30FC20010E277 /* NSObject+Parse.m in Sources */,
 				2779362927E33BE40010E277 /* WeakWebViewScriptMessageDelegate.m in Sources */,
 				2779362927E33BE40010E277 /* WeakWebViewScriptMessageDelegate.m in Sources */,
+				275E3DA927F45A8A0010EC30 /* KSLiveStreamVideo.m in Sources */,
 				277D431A27E9991200107DB7 /* ModifyViewController.m in Sources */,
 				277D431A27E9991200107DB7 /* ModifyViewController.m in Sources */,
 				277932EB27E310070010E277 /* TZProgressView.m in Sources */,
 				277932EB27E310070010E277 /* TZProgressView.m in Sources */,
 				27BC3B1B27F2B37500D81E30 /* MyMusicBodyView.m in Sources */,
 				27BC3B1B27F2B37500D81E30 /* MyMusicBodyView.m in Sources */,
+				275E3DB027F45CA60010EC30 /* KSLiveChatroomLike.m in Sources */,
 				2773204727EDB670008FAECA /* GroupNoticeEditController.m in Sources */,
 				2773204727EDB670008FAECA /* GroupNoticeEditController.m in Sources */,
 				277931C427E30FC20010E277 /* NSMutableArray+KSSafe.m in Sources */,
 				277931C427E30FC20010E277 /* NSMutableArray+KSSafe.m in Sources */,
 				275B172127EB1BE60081FDEF /* KSSearchResultViewCell.m in Sources */,
 				275B172127EB1BE60081FDEF /* KSSearchResultViewCell.m in Sources */,
@@ -3332,9 +3531,10 @@
 				27D83F3F27F3EA8A00062476 /* MinePageCourseView.m in Sources */,
 				27D83F3F27F3EA8A00062476 /* MinePageCourseView.m in Sources */,
 				2779331D27E311A10010E277 /* KSNetworkingManager.m in Sources */,
 				2779331D27E311A10010E277 /* KSNetworkingManager.m in Sources */,
 				2779362C27E33C2B0010E277 /* LoginBodyView.m in Sources */,
 				2779362C27E33C2B0010E277 /* LoginBodyView.m in Sources */,
-				2779334A27E314C60010E277 /* KSNormalAlertView.m in Sources */,
 				277931DD27E30FC20010E277 /* UIImage+Resize.m in Sources */,
 				277931DD27E30FC20010E277 /* UIImage+Resize.m in Sources */,
+				275E3DA327F441EC0010EC30 /* KSEnterLiveroomManager.m in Sources */,
 				2779323327E30FC30010E277 /* StateView.m in Sources */,
 				2779323327E30FC30010E277 /* StateView.m in Sources */,
+				275E3DE427F467410010EC30 /* KSChatInputBarControl.m in Sources */,
 				27D5D5D527EDBCB900B4720C /* GroupNoticeModel.m in Sources */,
 				27D5D5D527EDBCB900B4720C /* GroupNoticeModel.m in Sources */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -3513,6 +3713,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 1.0.0;
 				CURRENT_PROJECT_VERSION = 1.0.0;
 				DEVELOPMENT_TEAM = P664H7S5LL;
 				DEVELOPMENT_TEAM = P664H7S5LL;
+				ENABLE_BITCODE = NO;
 				GCC_PREFIX_HEADER = "$(SRCROOT)/KulexiuForTeacher/Common/Define/PrefixHeader.pch";
 				GCC_PREFIX_HEADER = "$(SRCROOT)/KulexiuForTeacher/Common/Define/PrefixHeader.pch";
 				GENERATE_INFOPLIST_FILE = YES;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = KulexiuForTeacher/Info.plist;
 				INFOPLIST_FILE = KulexiuForTeacher/Info.plist;
@@ -3547,6 +3748,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 1.0.0;
 				CURRENT_PROJECT_VERSION = 1.0.0;
 				DEVELOPMENT_TEAM = P664H7S5LL;
 				DEVELOPMENT_TEAM = P664H7S5LL;
+				ENABLE_BITCODE = NO;
 				GCC_PREFIX_HEADER = "$(SRCROOT)/KulexiuForTeacher/Common/Define/PrefixHeader.pch";
 				GCC_PREFIX_HEADER = "$(SRCROOT)/KulexiuForTeacher/Common/Define/PrefixHeader.pch";
 				GENERATE_INFOPLIST_FILE = YES;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = KulexiuForTeacher/Info.plist;
 				INFOPLIST_FILE = KulexiuForTeacher/Info.plist;

+ 6 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePreview_close.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "livePreview_close@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "livePreview_close@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

二进制
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePreview_close.imageset/livePreview_close@2x.png


二进制
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePreview_close.imageset/livePreview_close@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePrew_beauty.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "livePrew_beauty@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "livePrew_beauty@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

二进制
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePrew_beauty.imageset/livePrew_beauty@2x.png


二进制
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/livePrew_beauty.imageset/livePrew_beauty@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_share.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "live_share@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "live_share@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

二进制
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_share.imageset/live_share@2x.png


二进制
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_share.imageset/live_share@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_switch.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "live_switch@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "live_switch@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

二进制
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_switch.imageset/live_switch@2x.png


二进制
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Live/live_switch.imageset/live_switch@3x.png


+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Base/BaseViewController.h

@@ -6,6 +6,7 @@
 //
 //
 
 
 #import <UIKit/UIKit.h>
 #import <UIKit/UIKit.h>
+#import "UINavigationController+KSNavigationBar.h"
 
 
 NS_ASSUME_NONNULL_BEGIN
 NS_ASSUME_NONNULL_BEGIN
 
 

+ 28 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Custom/KSNormalAlertView.h

@@ -0,0 +1,28 @@
+//
+//  KSNormalAlertView.h
+//  StudentDaya
+//
+//  Created by Kyle on 2020/6/15.
+//  Copyright © 2020 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^ButtonCallback)(void);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSNormalAlertView : UIView
+
+@property (nonatomic, assign) BOOL isShow;
+
++ (KSNormalAlertView *)ks_showAlertWithTitle:(NSString *)title confirmTitle:(NSString *)confirmTitle  confirm:(ButtonCallback)confirm;
+
++ (KSNormalAlertView *)ks_showAlertWithTitle:(NSString *)title  leftTitle:(NSString *)leftTitle rightTitle:(NSString *)rightTitle  cancel:(ButtonCallback)cancel confirm:(ButtonCallback)confirm;
+
++ (KSNormalAlertView *)ks_showAlertWithTitle:(NSString *)title  leftTitle:(NSString *)leftTitle rightTitle:(NSString *)rightTitle inView:(UIView *)displayView cancel:(ButtonCallback)cancel confirm:(ButtonCallback)confirm;
+
+- (void)dismissAlertView;
+@end
+
+NS_ASSUME_NONNULL_END

+ 266 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Custom/KSNormalAlertView.m

@@ -0,0 +1,266 @@
+//
+//  KSNormalAlertView.m
+//  StudentDaya
+//
+//  Created by Kyle on 2020/6/15.
+//  Copyright © 2020 DayaMusic. All rights reserved.
+//
+
+#import "KSNormalAlertView.h"
+#import "UIView+Animation.h"
+
+typedef enum : NSUInteger {
+    ClassRoomAlertViewCancel,
+    ClassRoomAlertViewConfirm,
+} ClassRoomAlertViewActionTag;
+
+#define AWidth 320
+#define AHeight 180
+
+@interface KSNormalAlertView ()
+@property (nonatomic, strong) UILabel *tipsLabel;
+@property (nonatomic, strong) UILabel *titleLable;
+@property (nonatomic, strong) UIButton *cancelButton;
+@property (nonatomic, strong) UIButton *sureButton;
+@property (nonatomic, strong) NSString *title;
+@property (nonatomic, strong) NSString *leftTitle;
+@property (nonatomic, strong) NSString *rightTitle;
+@property (nonatomic, copy) ButtonCallback cancel;
+@property (nonatomic, copy) ButtonCallback confirm;
+@end
+
+@implementation KSNormalAlertView
+
++ (KSNormalAlertView *)ks_showAlertWithTitle:(NSString *)title confirmTitle:(NSString *)confirmTitle confirm:(ButtonCallback)confirm {
+    KSNormalAlertView * alertView = [[KSNormalAlertView alloc] initWithFrame:[UIScreen mainScreen].bounds];
+    alertView.backgroundColor = HexRGBAlpha(0x000000, 0.5f);
+    alertView.title = title;
+    alertView.rightTitle = confirmTitle;
+    alertView.confirm = confirm;
+    [alertView addCancelSubview];
+    [alertView showAlertView];
+    return alertView;
+}
+
++ (KSNormalAlertView *)ks_showAlertWithTitle:(NSString *)title leftTitle:(NSString *)leftTitle rightTitle:(NSString *)rightTitle cancel:(ButtonCallback)cancel confirm:(ButtonCallback)confirm {
+    KSNormalAlertView * alertView = [[KSNormalAlertView alloc] initWithFrame:[UIScreen mainScreen].bounds];
+    alertView.backgroundColor = HexRGBAlpha(0x000000, 0.5f);
+    alertView.title = title;
+    alertView.leftTitle = leftTitle;
+    alertView.rightTitle = rightTitle;
+    alertView.cancel = cancel;
+    alertView.confirm =confirm;
+    [alertView addSubviews];
+    [alertView showAlertView];
+    return alertView;
+}
+
++ (KSNormalAlertView *)ks_showAlertWithTitle:(NSString *)title  leftTitle:(NSString *)leftTitle rightTitle:(NSString *)rightTitle inView:(UIView *)displayView cancel:(ButtonCallback)cancel confirm:(ButtonCallback)confirm {
+    KSNormalAlertView * alertView = [[KSNormalAlertView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreen_Height)];
+    alertView.backgroundColor = HexRGBAlpha(0x000000, 0.5f);
+    alertView.title = title;
+    alertView.leftTitle = leftTitle;
+    alertView.rightTitle = rightTitle;
+    alertView.cancel = cancel;
+    alertView.confirm =confirm;
+    [alertView addSubviews];
+    [alertView showAlertInView:displayView];
+    return alertView;
+}
+
+- (void)showAlertInView:(UIView *)displayView {
+    _isShow = YES;
+    [displayView addSubview:self];
+    [displayView bringSubviewToFront:self];
+    [self setPopAnimation];
+}
+
+- (void)showAlertView {
+    _isShow = YES;
+    [[UIApplication sharedApplication].keyWindow addSubview:self];
+}
+
+- (void)dismissAlertView {
+    _isShow = NO;
+    [self removeFromSuperview];
+}
+
+
+- (void)addCancelSubview {
+    UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake((kScreenWidth - AWidth) / 2, (CGRectGetHeight(self.bounds) - AHeight) / 2, AWidth, AHeight)];
+    contentView.backgroundColor = HexRGB(0x35343e);
+    contentView.layer.cornerRadius = 10;
+    contentView.layer.masksToBounds = YES;
+    [self addSubview:contentView];
+    
+    UIView *topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, AWidth, 43)];
+    topView.backgroundColor = HexRGB(0x514f5f);
+    [contentView addSubview:topView];
+    
+    UIButton *cancleButton = [UIButton buttonWithType:UIButtonTypeCustom];
+    [cancleButton setImage:[UIImage imageNamed:@"cancle_white"] forState:UIControlStateNormal];
+    [topView addSubview:cancleButton];
+    [cancleButton mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.right.bottom.mas_equalTo(topView);
+        make.width.mas_equalTo(topView.mas_height);
+    }];
+    cancleButton.tag = ClassRoomAlertViewCancel;
+    [cancleButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
+    
+    [topView addSubview:self.tipsLabel];
+    [self.tipsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(topView.mas_left).offset(13);
+        make.top.bottom.mas_equalTo(topView);
+        make.right.mas_equalTo(cancleButton.mas_left);
+    }];
+    [contentView addSubview:self.titleLable];
+    [contentView addSubview:self.sureButton];
+    [self.titleLable mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(topView.mas_top).offset(20);
+        make.left.equalTo(contentView.mas_left).offset(13);
+        make.right.equalTo(contentView.mas_right).offset(-13);
+        make.bottom.equalTo(self.sureButton.mas_bottom).offset(-15);
+    }];
+    
+    [self.sureButton mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.bottom.mas_equalTo(contentView.mas_bottom).offset(-19);
+        make.height.mas_equalTo(34);
+        make.width.mas_equalTo(100);
+        make.centerX.mas_equalTo(contentView.mas_centerX);
+    }];
+    
+}
+
+- (void)addSubviews {
+    UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake((kScreenWidth - AWidth) / 2, (CGRectGetHeight(self.bounds) - AHeight) / 2, AWidth, AHeight)];
+    contentView.backgroundColor = HexRGB(0x35343e);
+    contentView.layer.cornerRadius = 10;
+    contentView.layer.masksToBounds = YES;
+    [self addSubview:contentView];
+    
+    
+    UIView *topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, AWidth, 43)];
+    topView.backgroundColor = HexRGB(0x514f5f);
+    [contentView addSubview:topView];
+    
+    UIButton *cancleButton = [UIButton buttonWithType:UIButtonTypeCustom];
+    [cancleButton setImage:[UIImage imageNamed:@"cancle_white"] forState:UIControlStateNormal];
+    [topView addSubview:cancleButton];
+    [cancleButton mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.right.bottom.mas_equalTo(topView);
+        make.width.mas_equalTo(topView.mas_height);
+    }];
+    cancleButton.tag = ClassRoomAlertViewCancel;
+    [cancleButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
+    
+    [topView addSubview:self.tipsLabel];
+    [self.tipsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(topView.mas_left).offset(13);
+        make.top.bottom.mas_equalTo(topView);
+        make.right.mas_equalTo(cancleButton.mas_left);
+    }];
+    [contentView addSubview:self.titleLable];
+    [contentView addSubview:self.cancelButton];
+    [contentView addSubview:self.sureButton];
+    [self.titleLable mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(topView.mas_top).offset(20);
+        make.left.equalTo(contentView.mas_left).offset(13);
+        make.right.equalTo(contentView.mas_right).offset(-13);
+        make.bottom.equalTo(self.sureButton.mas_bottom).offset(-15);
+    }];
+    CGFloat width = (AWidth - 17 * 2 - 13) / 2.0f;
+    [self.cancelButton mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(17);
+        make.bottom.equalTo(contentView.mas_bottom).offset(-19);
+        make.height.mas_equalTo(34);
+        make.width.mas_equalTo(width);
+    }];
+    
+    [self.sureButton mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(self.cancelButton.mas_right).offset(13);
+        make.bottom.mas_equalTo(contentView.mas_bottom).offset(-19);
+        make.height.mas_equalTo(34);
+        make.width.mas_equalTo(width);
+    }];
+}
+
+- (void)buttonAction:(UIButton *)button {
+    if (button.tag == ClassRoomAlertViewCancel) {
+        if (self.cancel) {
+            self.cancel();
+        }
+    }else {
+        if (self.confirm) {
+            self.confirm();
+        }
+    }
+    [self dismissAlertView];
+}
+
+- (UILabel *)tipsLabel {
+    if (!_tipsLabel) {
+        _tipsLabel = [[UILabel alloc] init];
+        _tipsLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
+        _tipsLabel.textAlignment = NSTextAlignmentLeft;
+        _tipsLabel.text = @"提示";
+        _tipsLabel.numberOfLines = 1;
+        _tipsLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
+        _tipsLabel.textColor = HexRGB(0xffffff);
+    }
+    return _tipsLabel;
+}
+
+- (UILabel *)titleLable {
+    if (!_titleLable) {
+        _titleLable = [[UILabel alloc] init];
+        _titleLable.font = [UIFont systemFontOfSize:16];
+        _titleLable.textAlignment = NSTextAlignmentLeft;
+        _titleLable.text = self.title;
+        _titleLable.numberOfLines = 0;
+        _titleLable.lineBreakMode = NSLineBreakByTruncatingMiddle;
+        _titleLable.textColor = HexRGB(0xffffff);
+    }
+    return _titleLable;
+}
+
+- (UIButton *)cancelButton {
+    if(!_cancelButton) {
+        _cancelButton = [[UIButton alloc] init];
+        _cancelButton.backgroundColor =  [UIColor clearColor];
+        [_cancelButton.titleLabel setFont:[UIFont systemFontOfSize:14]];
+        [_cancelButton setTitleColor:HexRGB(0xffffff) forState:UIControlStateNormal];
+        [_cancelButton setTitle:self.leftTitle forState:UIControlStateNormal];
+        _cancelButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
+        _cancelButton.tag = ClassRoomAlertViewCancel;
+        _cancelButton.layer.cornerRadius = 4.0f;
+        _cancelButton.layer.borderWidth = 1.0;
+        _cancelButton.layer.borderColor = HexRGB(0xffffff).CGColor;
+        [_cancelButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
+        
+    }
+    return _cancelButton;
+}
+
+- (UIButton *)sureButton {
+    if (!_sureButton) {
+        _sureButton = [[UIButton alloc] init];
+        _sureButton.backgroundColor =  HexRGB(0x656376);
+        [_sureButton.titleLabel setFont:[UIFont systemFontOfSize:14]];
+        [_sureButton setTitleColor:HexRGB(0xffffff) forState:UIControlStateNormal];
+        [_sureButton setTitle:self.rightTitle forState:UIControlStateNormal];
+        _sureButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
+        _sureButton.tag = ClassRoomAlertViewConfirm;
+        _sureButton.layer.cornerRadius = 4.0f;
+        [_sureButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
+    }
+    return _sureButton;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 47 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/CreateLiveViewController.m

@@ -7,9 +7,13 @@
 
 
 #import "CreateLiveViewController.h"
 #import "CreateLiveViewController.h"
 #import "CreateLiveBodyView.h"
 #import "CreateLiveBodyView.h"
+#import "LivePrepareViewController.h"
+#import "CustomNavViewController.h"
 
 
 @interface CreateLiveViewController ()
 @interface CreateLiveViewController ()
 
 
+@property (nonatomic, strong) CreateLiveBodyView *bodyView;
+
 @end
 @end
 
 
 @implementation CreateLiveViewController
 @implementation CreateLiveViewController
@@ -17,6 +21,49 @@
 - (void)viewDidLoad {
 - (void)viewDidLoad {
     [super viewDidLoad];
     [super viewDidLoad];
     // Do any additional setup after loading the view.
     // Do any additional setup after loading the view.
+    [self allocTitle:@"创建直播"];
+    [self configUI];
+}
+
+- (void)configUI {
+    self.bodyView = [CreateLiveBodyView shareInstance];
+    [self.scrollView addSubview:self.bodyView];
+    CGFloat height = kScreenHeight -kNaviBarHeight - iPhoneXSafeBottomMargin;
+    [self.bodyView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.mas_equalTo(self.scrollView.mas_top);
+        make.left.right.mas_equalTo(self.view);
+        make.height.mas_equalTo(height);
+    }];
+    [self.scrollView setContentSize:CGSizeMake(kScreenWidth, height)];
+    MJWeakSelf;
+    [self.bodyView createSureCallback:^(NSString *title, NSString *content) {
+        [weakSelf createLiveAction:title content:content];
+    }];
+}
+
+- (void)createLiveAction:(NSString *)title content:(NSString *)content {
+    NSString *imgUrl = nil;
+    [self showhud];
+    [KSNetworkingManager liveRoomCreateTempLiveRoom:KS_POST coverPic:imgUrl liveRemark:content roomTitle:title success:^(NSDictionary * _Nonnull dic) {
+        [self removehub];
+        if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
+            NSString *roomId = [dic stringValueForKey:@"data"];
+            [self previewViewWithRoomId:roomId];
+        }
+        else {
+            [self MBPShow:MESSAGEKEY];
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        [self removehub];
+    }];
+}
+
+- (void)previewViewWithRoomId:(NSString *)roomId {
+    LivePrepareViewController *ctrl = [[LivePrepareViewController alloc] init];
+    ctrl.roomId = roomId;
+    CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:ctrl];
+    navCtrl.modalPresentationStyle = UIModalPresentationFullScreen;
+    [self.navigationController presentViewController:navCtrl animated:YES completion:nil];
 }
 }
 
 
 /*
 /*

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LivePrepareViewController.h

@@ -0,0 +1,18 @@
+//
+//  LivePrepareViewController.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "BaseViewController.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LivePrepareViewController : BaseViewController
+
+@property (nonatomic, strong) NSString *roomId; // 房间号
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 137 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LivePrepareViewController.m

@@ -0,0 +1,137 @@
+//
+//  LivePrepareViewController.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "LivePrepareViewController.h"
+#import "LivePreviewBodyView.h"
+#import <RongRTCLib/RongRTCLib.h>
+#import "KSEnterLiveroomManager.h"
+#import <RongFaceBeautifier/RongFaceBeautifier.h>
+
+@interface LivePrepareViewController ()
+
+@property (nonatomic, strong) LivePreviewBodyView *bodyView;
+
+// 音频配置
+@property(strong, nonatomic) RCRTCEngine *engine;
+
+@end
+
+@implementation LivePrepareViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    self.ks_prefersNavigationBarHidden = YES;
+    [self configUI];
+    [self configEngine];
+}
+
+- (void)configUI {
+    self.bodyView = [LivePreviewBodyView shareInstance];
+    [self.view addSubview:self.bodyView];
+    [self.bodyView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.bottom.top.mas_equalTo(self.view);
+    }];
+    MJWeakSelf;
+    [self.bodyView previewOperationCallback:^(PREVIEWLIVEACTION action) {
+        [weakSelf previewOperationAction:action];
+    }];
+    
+}
+
+- (void)configEngine {
+    self.engine = [RCRTCEngine sharedInstance];
+    RCRTCVideoView *videoView = [[RCRTCVideoView alloc] init];
+    videoView.fillMode = RCRTCVideoFillModeAspectFill;
+    
+    videoView.frameAnimated = NO;
+    [self.bodyView.videoView addSubview:videoView];
+    [videoView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.top.bottom.right.mas_equalTo(self.bodyView.videoView);
+    }];
+    [self.engine.defaultVideoStream setVideoView:videoView];
+    [self.engine.defaultVideoStream startCapture];
+    
+}
+
+
+- (void)previewOperationAction:(PREVIEWLIVEACTION)action {
+    switch (action) {
+        case PREVIEWLIVEACTION_BACK: // 返回
+        {
+            [self.navigationController dismissViewControllerAnimated:YES completion:nil];
+        }
+            break;
+        case PREVIEWLIVEACTION_SWITCH: // 切换
+        {
+            [[RCRTCEngine sharedInstance].defaultVideoStream switchCamera];
+        }
+            break;
+        case PREVIEWLIVEACTION_BEAUTY: // 美颜
+        {
+            [self displayBeautyView];
+        }
+            break;
+        case PREVIEWLIVEACTION_SHARE: // 分享
+        {
+            
+        }
+            break;
+        case PREVIEWLIVEACTION_OPEN: // 进入直播间
+        {
+            [self joinLiveRoom];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)displayBeautyView {
+    [self configSettingBeauty:YES white:8 smoothLevel:5 ruddyLevel:8 brightLevel:7 filter:RCRTCBeautyFilterEsthetic filterLevel:80];
+}
+
+- (void)configSettingBeauty:(BOOL)isOn white:(NSInteger)whitenessLevel smoothLevel:(NSInteger)smoothLevel ruddyLevel:(NSInteger)ruddyLevel brightLevel:(NSInteger)brightLevel filter:(RCRTCBeautyFilter)filter filterLevel:(int)filterLevel {
+    if (isOn) {
+        // 获取当前美颜参数
+        RCRTCBeautyOption *option = [[RCRTCBeautyEngine sharedInstance] getCurrentBeautyOption];
+        // 修改参数
+        option.whitenessLevel = whitenessLevel;
+        option.smoothLevel = smoothLevel;
+        option.ruddyLevel = ruddyLevel;
+        option.brightLevel = brightLevel;
+        // 设置美颜
+        [[RCRTCBeautyEngine sharedInstance] setBeautyOption:YES option:option];
+        // 设置滤镜
+        [[RCRTCBeautyEngine sharedInstance] setBeautyFilter:filter];
+        // 设置滤镜强度
+        [[RCRTCBeautyEngine sharedInstance] setFilterIntensity:filterLevel];
+    }
+    else {
+        [[RCRTCBeautyEngine sharedInstance] reset];
+    }
+}
+
+- (void)joinLiveRoom {
+    [self showhud];
+    MJWeakSelf;
+    [KSEnterLiveroomManager joinLiveWithRoomId:self.roomId inController:(CustomNavViewController *)self.navigationController callback:^{
+        [weakSelf removehub];
+    }];
+}
+
+/*
+#pragma mark - Navigation
+
+// In a storyboard-based application, you will often want to do a little preparation before navigation
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
+    // Get the new view controller using [segue destinationViewController].
+    // Pass the selected object to the new view controller.
+}
+*/
+
+@end

+ 50 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LiveVideoRoomViewController.h

@@ -0,0 +1,50 @@
+//
+//  LiveVideoRoomViewController.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "BaseViewController.h"
+#import <RongRTCLib/RongRTCLib.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveVideoRoomViewController : BaseViewController
+
+/*!
+ 加入的房间 ID
+ */
+@property (nonatomic, strong) NSString *roomId;
+
+/*!
+ 身份状态 主讲人/观众
+ */
+@property (nonatomic, assign) RCRTCLiveRoleType liveRoleType;
+
+/// 主讲人id
+@property (nonatomic, strong) NSString *createrId;
+/// 主讲人名称
+@property (nonatomic, strong) NSString *createrName;
+/// 主讲人头像
+@property (nonatomic, strong) NSString *createrAvatal;
+
+@property (nonatomic, assign) NSInteger likeCount;
+
+/// 房间人数
+@property (nonatomic, assign) NSInteger totalCount;
+
+/// 是否临时房间
+@property (nonatomic, assign) BOOL isTempRoom;
+
+/// 直播课结束时间
+@property (nonatomic, strong) NSString *liveEndTime;
+
+/// 直播间自动关闭时间
+@property (nonatomic, assign) NSInteger expiredMinute;
+
+- (void)quitAction;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 32 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LiveVideoRoomViewController.m

@@ -0,0 +1,32 @@
+//
+//  LiveVideoRoomViewController.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "LiveVideoRoomViewController.h"
+#import "KSChatInputBarControl.h"
+
+@interface LiveVideoRoomViewController ()<RCRTCRoomEventDelegate,RCRTCStatusReportDelegate,UIGestureRecognizerDelegate,KSChatInputBarControlDelegate,UITableViewDataSource,UITableViewDelegate>
+
+@end
+
+@implementation LiveVideoRoomViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+}
+
+/*
+#pragma mark - Navigation
+
+// In a storyboard-based application, you will often want to do a little preparation before navigation
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
+    // Get the new view controller using [segue destinationViewController].
+    // Pass the selected object to the new view controller.
+}
+*/
+
+@end

+ 58 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSChatroomMessageCenter.h

@@ -0,0 +1,58 @@
+//
+//  KSChatroomMessageCenter.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <Foundation/Foundation.h>
+#import <RongIMLibCore/RongIMLibCore.h>
+#import "KSLiveChatroomLike.h"
+#import "KSLiveChatroomDownSeat.h"
+#import "KSLiveChatroomEnter.h"
+#import "KSLiveChatroomLeave.h"
+#import "KSLiveChatroomUserQuit.h"
+#import "KSLiveChatroomWelcome.h"
+#import "KSLiveChatroomSeatApply.h"
+#import "KSLiveChatroomSeatResponse.h"
+
+#import "KSLiveChatroomClose.h"
+#import "KSLiveChatroomKickOut.h"
+
+typedef void(^RCChatroomMessageSuccess)(long messageId);
+typedef void(^RCChatroomMessageError)(RCErrorCode errorCode, long messageId);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol RCChatroomLocalMessageDelegate <NSObject>
+
+- (void)didReceiveLocalChatroomMessage:(RCMessageContent *)content;
+
+@end
+
+@interface KSChatroomMessageCenter : NSObject
+
+///注册消息类
++ (void)registerMessageTypes;
+
+///发送消息
+///@param roomId 房间id
+///@param content 消息,对应自定义消息类型
++ (void)sendChatMessage:(NSString *)roomId
+                content:(RCMessageContent *)content
+                success:(RCChatroomMessageSuccess)success
+                  error:(RCChatroomMessageError)error;
+
+///发送消息
+///@param roomId 房间id
+///@param content 消息,对应自定义消息类型
+///@param queue 回调线程
++ (void)sendChatMessage:(NSString *)roomId
+                content:(RCMessageContent *)content
+                  queue:(dispatch_queue_t)queue
+                success:(RCChatroomMessageSuccess)success
+                  error:(RCChatroomMessageError)error;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 73 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSChatroomMessageCenter.m

@@ -0,0 +1,73 @@
+//
+//  KSChatroomMessageCenter.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSChatroomMessageCenter.h"
+
+#ifdef __has_include
+#if __has_include(<RongIMKit/RongIMKit.h>)
+#import <RongIMKit/RongIMKit.h>
+#define CMPTIMKit YES
+#endif
+#endif
+
+#ifdef CMPTIMKit
+#define RCIMReceiveMessageDelegate RCIMReceiveMessageDelegate
+#define RCClient [RCIM sharedRCIM]
+#else
+#define RCIMReceiveMessageDelegate RCIMClientReceiveMessageDelegate
+#define RCClient [RCCoreClient sharedCoreClient]
+#endif
+
+
+@implementation KSChatroomMessageCenter
+
++ (void)registerMessageTypes {
+    [[RCIM sharedRCIM] registerMessageType:[KSLiveChatroomLike class]];
+    [[RCIM sharedRCIM] registerMessageType:[KSLiveChatroomDownSeat class]];
+    [[RCIM sharedRCIM] registerMessageType:[KSLiveChatroomEnter class]];
+    [[RCIM sharedRCIM] registerMessageType:[KSLiveChatroomLeave class]];
+    [[RCIM sharedRCIM] registerMessageType:[KSLiveChatroomUserQuit class]];
+    [[RCIM sharedRCIM] registerMessageType:[KSLiveChatroomWelcome class]];
+    [[RCIM sharedRCIM] registerMessageType:[KSLiveChatroomSeatApply class]];
+    [[RCIM sharedRCIM] registerMessageType:[KSLiveChatroomSeatResponse class]];
+    [[RCIM sharedRCIM] registerMessageType:[KSLiveChatroomClose class]];
+    [[RCIM sharedRCIM] registerMessageType:[KSLiveChatroomKickOut class]];
+}
+
++ (void)sendChatMessage:(NSString *)roomId content:(RCMessageContent *)content
+                success:(RCChatroomMessageSuccess)success
+                  error:(RCChatroomMessageError)error {
+    [KSChatroomMessageCenter sendChatMessage:roomId
+                                     content:content
+                                       queue:dispatch_get_main_queue()
+                                     success:success
+                                       error:error];
+}
+
++ (void)sendChatMessage:(NSString *)roomId
+                content:(RCMessageContent *)content
+                  queue:(dispatch_queue_t)queue
+                success:(RCChatroomMessageSuccess)success
+                  error:(RCChatroomMessageError)error {
+    [[RCIM sharedRCIM] sendMessage:ConversationType_CHATROOM
+                 targetId:roomId
+                  content:content
+              pushContent:nil
+                 pushData:nil
+                  success:^(long messageId) {
+        dispatch_async(queue, ^{
+            success(messageId);
+        });
+    }
+                    error:^(RCErrorCode nErrorCode, long messageId) {
+        dispatch_async(queue, ^{
+            error(nErrorCode, messageId);
+        });
+    }];
+}
+
+@end

+ 16 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomClose.h

@@ -0,0 +1,16 @@
+//
+//  KSLiveChatroomClose.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSLiveChatroomClose : RCMessageContent
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 31 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomClose.m

@@ -0,0 +1,31 @@
+//
+//  KSLiveChatroomClose.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSLiveChatroomClose.h"
+
+@implementation KSLiveChatroomClose
+
+- (NSData *)encode {
+    return [NSJSONSerialization dataWithJSONObject:@{} options:kNilOptions error:nil];
+}
+
+- (void)decodeWithData:(NSData *)data {
+}
+
++ (NSString *)getObjectName {
+  return @"RC:ForcedOffline";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+  return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+  return MessagePersistent_NONE;
+}
+
+@end

+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomDownSeat.h

@@ -0,0 +1,22 @@
+//
+//  KSLiveChatroomDownSeat.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 观众下麦通知
+@interface KSLiveChatroomDownSeat : RCMessageContent
+
+// 观众名称
+@property (nonatomic, strong) NSString *audienceName;
+// 观众id
+@property (nonatomic, strong) NSString *audienceId;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 50 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomDownSeat.m

@@ -0,0 +1,50 @@
+//
+//  KSLiveChatroomDownSeat.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSLiveChatroomDownSeat.h"
+
+@implementation KSLiveChatroomDownSeat
+- (NSData *)encode {
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    
+    // 观众
+    if (self.audienceName) {
+        [mutableDict setObject:self.audienceName forKey:@"audienceName"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"audienceName"];
+    }
+    if (self.audienceId) {
+        [mutableDict setObject:self.audienceId forKey:@"audienceId"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"audienceId"];
+    }
+    
+    return [NSJSONSerialization dataWithJSONObject:mutableDict options:kNilOptions error:nil];
+}
+
+- (void)decodeWithData:(NSData *)data {
+    if (data == nil) return;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return;
+    
+    self.audienceName = [json stringValueForKey:@"audienceName"];
+    self.audienceId = [json stringValueForKey:@"audienceId"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:downSeat";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+  return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+  return MessagePersistent_NONE;
+}
+@end

+ 26 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomEnter.h

@@ -0,0 +1,26 @@
+//
+//  KSLiveChatroomEnter.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSLiveChatroomEnter : RCMessageContent
+
+/**
+ 用户 Id
+*/
+@property(nonatomic, copy, nonnull) NSString *userId;
+
+/**
+ 用户名称
+*/
+@property(nonatomic, copy, nonnull) NSString *userName;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 48 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomEnter.m

@@ -0,0 +1,48 @@
+//
+//  KSLiveChatroomEnter.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSLiveChatroomEnter.h"
+
+@implementation KSLiveChatroomEnter
+
+- (NSData *)encode {
+    NSMutableDictionary *multableDict = [NSMutableDictionary dictionary];
+    if (self.userId) {
+        [multableDict setObject:self.userId forKey:@"userId"];
+    } else {
+        [multableDict setObject:@"" forKey:@"userId"];
+    }
+    if (self.userName) {
+        [multableDict setObject:self.userName forKey:@"userName"];
+    } else {
+        [multableDict setObject:@"" forKey:@"userName"];
+    }
+    return [NSJSONSerialization dataWithJSONObject:multableDict options:kNilOptions error:nil];
+}
+
+- (void)decodeWithData:(NSData *)data {
+    if (data == nil) return;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return;
+    self.userId = [json stringValueForKey:@"userId"];
+    self.userName = [json stringValueForKey:@"userName"];
+}
+
++ (NSString *)getObjectName {
+  return @"RC:Chatroom:Enter";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+  return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+  return MessagePersistent_NONE;
+}
+
+@end

+ 36 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomKickOut.h

@@ -0,0 +1,36 @@
+//
+//  KSLiveChatroomKickOut.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSLiveChatroomKickOut : RCMessageContent
+
+/**
+ 操作用户 Id
+*/
+@property(nonatomic, copy) NSString *userId;
+
+/**
+ 操作用户 名称
+*/
+@property(nonatomic, copy) NSString *userName;
+
+/**
+ 被踢出用户 Id
+*/
+@property(nonatomic, copy) NSString *targetId;
+
+/**
+ 被踢出用户 名称
+*/
+@property(nonatomic, copy) NSString *targetName;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 60 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomKickOut.m

@@ -0,0 +1,60 @@
+//
+//  KSLiveChatroomKickOut.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSLiveChatroomKickOut.h"
+
+@implementation KSLiveChatroomKickOut
+
+- (NSData *)encode {
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    if (self.userId) {
+        [mutableDict setObject:self.userId forKey:@"userId"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"userId"];
+    }
+    if (self.userName) {
+        [mutableDict setObject:self.userName forKey:@"userName"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"userName"];
+    }
+    if (self.targetId) {
+        [mutableDict setObject:self.targetId forKey:@"targetId"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"targetId"];
+    }
+    if (self.targetName) {
+        [mutableDict setObject:self.targetName forKey:@"targetName"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"targetName"];
+    }
+    return [NSJSONSerialization dataWithJSONObject:mutableDict options:kNilOptions error:nil];
+}
+
+- (void)decodeWithData:(NSData *)data {
+    if (data == nil) return;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return;
+    self.userId = [json stringValueForKey:@"userId"];
+    self.userName = [json stringValueForKey:@"userName"];
+    self.targetId = [json stringValueForKey:@"targetId"];
+    self.targetName = [json stringValueForKey:@"targetName"];
+}
+
++ (NSString *)getObjectName {
+  return @"RC:Chatroom:KickOut";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+  return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+  return MessagePersistent_NONE;
+}
+
+@end

+ 25 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomLeave.h

@@ -0,0 +1,25 @@
+//
+//  KSLiveChatroomLeave.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 用户主动退出发送消息
+@interface KSLiveChatroomLeave : RCMessageContent
+/**
+ 用户 Id
+*/
+@property(nonatomic, copy, nonnull) NSString *userId;
+
+/**
+ 用户名称
+*/
+@property(nonatomic, copy, nonnull) NSString *userName;
+@end
+
+NS_ASSUME_NONNULL_END

+ 12 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomLeave.m

@@ -0,0 +1,12 @@
+//
+//  KSLiveChatroomLeave.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSLiveChatroomLeave.h"
+
+@implementation KSLiveChatroomLeave
+
+@end

+ 19 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomLike.h

@@ -0,0 +1,19 @@
+//
+//  KSLiveChatroomLike.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 点赞消息
+@interface KSLiveChatroomLike : RCMessageContent
+
+@property(nonatomic, assign) int counts;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 55 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomLike.m

@@ -0,0 +1,55 @@
+//
+//  KSLiveChatroomLike.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSLiveChatroomLike.h"
+
+@implementation KSLiveChatroomLike
+
+- (NSData *)encode {
+    NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
+    if (self.counts) {
+        [dataDict setObject:@(self.counts) forKey:@"counts"];
+    }
+    if (self.extra) {
+        [dataDict setObject:self.extra forKey:@"extra"];
+    } else {
+        [dataDict setObject:@"" forKey:@"extra"];
+    }
+    if (self.senderUserInfo) {
+        [dataDict setObject:[self encodeUserInfo:self.senderUserInfo] forKey:@"user"];
+    }
+    return [NSJSONSerialization dataWithJSONObject:dataDict options:kNilOptions error:nil];
+}
+
+- (void)decodeWithData:(NSData *)data {
+    if (data == nil) {
+        return;
+    }
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json) {
+        self.counts = [[json stringValueForKey:@"counts"] intValue];
+        self.extra = [json stringValueForKey:@"extra"];
+        
+        NSDictionary *userinfoDic = dictionary[@"user"];
+        [self decodeUserInfo:userinfoDic];
+    }
+}
+
++ (NSString *)getObjectName {
+  return @"RC:Chatroom:Like";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+  return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+  return MessagePersistent_NONE;
+}
+
+@end

+ 37 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomSeatApply.h

@@ -0,0 +1,37 @@
+//
+//  KSLiveChatroomSeatApply.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(NSInteger, SEATHANDLE) {
+    SEATHANDLE_INVITE = 1,     // 主讲人邀请连麦
+    SEATHANDLE_DISINVITE = 2,  // 主讲人取消邀请
+    SEATHANDLE_APPLY = 3,      // 观众申请连麦
+    SEATHANDLE_CANCELAPPLY = 4,// 观众取消申请
+    SEATHANDLE_KICKSEAT = 5,   // 主讲人将连麦人抱下麦
+};
+
+/// 连麦邀请或申请操作
+@interface KSLiveChatroomSeatApply : RCMessageContent
+/**
+ 操作类型 1 主讲人邀请 2 主讲人取消邀请 3 观众申请 4 观众取消申请
+ */
+@property (nonatomic, assign) SEATHANDLE type;
+// 主讲人名称
+@property (nonatomic, strong) NSString *teacherName;
+// 主讲人id
+@property (nonatomic, strong) NSString *teacherId;
+// 观众名称
+@property (nonatomic, strong) NSString *audienceName;
+// 观众id
+@property (nonatomic, strong) NSString *audienceId;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 65 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomSeatApply.m

@@ -0,0 +1,65 @@
+//
+//  KSLiveChatroomSeatApply.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSLiveChatroomSeatApply.h"
+
+@implementation KSLiveChatroomSeatApply
+
+- (NSData *)encode {
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    // 主讲人
+    if (self.teacherName) {
+        [mutableDict setObject:self.teacherName forKey:@"teacherName"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"teacherName"];
+    }
+    if (self.teacherId) {
+        [mutableDict setObject:self.teacherId forKey:@"teacherId"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"teacherId"];
+    }
+    // 观众
+    if (self.audienceName) {
+        [mutableDict setObject:self.audienceName forKey:@"audienceName"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"audienceName"];
+    }
+    if (self.audienceId) {
+        [mutableDict setObject:self.audienceId forKey:@"audienceId"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"audienceId"];
+    }
+    
+    [mutableDict setObject:@(self.type) forKey:@"type"];
+    return [NSJSONSerialization dataWithJSONObject:mutableDict options:kNilOptions error:nil];
+}
+
+- (void)decodeWithData:(NSData *)data {
+    if (data == nil) return;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return;
+    self.teacherName = [json stringValueForKey:@"teacherName"];
+    self.teacherId = [json stringValueForKey:@"teacherId"];
+    self.audienceName = [json stringValueForKey:@"audienceName"];
+    self.audienceId = [json stringValueForKey:@"audienceId"];
+    self.type = [json integerValueForKey:@"type"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:SeatApply";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+  return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+  return MessagePersistent_NONE;
+}
+
+@end

+ 39 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomSeatResponse.h

@@ -0,0 +1,39 @@
+//
+//  KSLiveChatroomSeatResponse.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(NSInteger, SEATRESPONSE) {
+    SEATRESPONSE_TEACHERAPPROVE = 1,       // 主讲人同意连麦
+    SEATRESPONSE_TEACHERREJECT = 2,        // 主讲人拒绝连麦
+    SEATRESPONSE_AUDIENCEAPPROVE = 3,      // 观众同意连麦
+    SEATRESPONSE_AUDIENCEREJECT = 4,       // 观众拒绝连麦
+};
+
+/// 连麦回复
+@interface KSLiveChatroomSeatResponse : RCMessageContent
+
+/**
+ 操作类型 1 主讲人同意 2 主讲人拒绝 3 观众同意 4 观众拒绝
+ */
+@property (nonatomic, assign) SEATRESPONSE type;
+// 主讲人名称
+@property (nonatomic, strong) NSString *teacherName;
+// 主讲人id
+@property (nonatomic, strong) NSString *teacherId;
+// 观众名称
+@property (nonatomic, strong) NSString *audienceName;
+// 观众id
+@property (nonatomic, strong) NSString *audienceId;
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 65 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomSeatResponse.m

@@ -0,0 +1,65 @@
+//
+//  KSLiveChatroomSeatResponse.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSLiveChatroomSeatResponse.h"
+
+@implementation KSLiveChatroomSeatResponse
+
+- (NSData *)encode {
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    // 主讲人
+    if (self.teacherName) {
+        [mutableDict setObject:self.teacherName forKey:@"teacherName"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"teacherName"];
+    }
+    if (self.teacherId) {
+        [mutableDict setObject:self.teacherId forKey:@"teacherId"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"teacherId"];
+    }
+    // 观众
+    if (self.audienceName) {
+        [mutableDict setObject:self.audienceName forKey:@"audienceName"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"audienceName"];
+    }
+    if (self.audienceId) {
+        [mutableDict setObject:self.audienceId forKey:@"audienceId"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"audienceId"];
+    }
+    
+    [mutableDict setObject:@(self.type) forKey:@"type"];
+    return [NSJSONSerialization dataWithJSONObject:mutableDict options:kNilOptions error:nil];
+}
+
+- (void)decodeWithData:(NSData *)data {
+    if (data == nil) return;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return;
+    self.teacherName = [json stringValueForKey:@"teacherName"];
+    self.teacherId = [json stringValueForKey:@"teacherId"];
+    self.audienceName = [json stringValueForKey:@"audienceName"];
+    self.audienceId = [json stringValueForKey:@"audienceId"];
+    self.type = [json integerValueForKey:@"type"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:SeatResponse";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+  return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+  return MessagePersistent_NONE;
+}
+
+@end

+ 27 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomUserQuit.h

@@ -0,0 +1,27 @@
+//
+//  KSLiveChatroomUserQuit.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 观众未调用leave退出房间
+@interface KSLiveChatroomUserQuit : RCMessageContent
+
+/**
+ 用户 Id
+*/
+@property(nonatomic, copy, nonnull) NSString *userId;
+
+/**
+ 用户名称
+*/
+@property(nonatomic, copy, nonnull) NSString *userName;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 49 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomUserQuit.m

@@ -0,0 +1,49 @@
+//
+//  KSLiveChatroomUserQuit.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSLiveChatroomUserQuit.h"
+
+@implementation KSLiveChatroomUserQuit
+
+- (NSData *)encode {
+    NSMutableDictionary *multableDict = [NSMutableDictionary dictionary];
+    if (self.userId) {
+        [multableDict setObject:self.userId forKey:@"userId"];
+    } else {
+        [multableDict setObject:@"" forKey:@"userId"];
+    }
+    if (self.userName) {
+        [multableDict setObject:self.userName forKey:@"userName"];
+    } else {
+        [multableDict setObject:@"" forKey:@"userName"];
+    }
+    return [NSJSONSerialization dataWithJSONObject:multableDict options:kNilOptions error:nil];
+}
+
+- (void)decodeWithData:(NSData *)data {
+    if (data == nil) return;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return;
+    self.userId = [json stringValueForKey:@"userId"];
+    self.userName = [json stringValueForKey:@"userName"];
+}
+
++ (NSString *)getObjectName {
+  return @"RC:LookerLoginOut";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+  return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+  return MessagePersistent_NONE;
+}
+
+
+@end

+ 24 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomWelcome.h

@@ -0,0 +1,24 @@
+//
+//  KSLiveChatroomWelcome.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSLiveChatroomWelcome : RCMessageContent
+
+@property(nonatomic, copy) NSString *msgId;
+
+@property(nonatomic, assign) int counts;
+
+@property(nonatomic, assign) int rank;
+
+@property(nonatomic, assign) int level;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 74 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSLiveChatroomWelcome.m

@@ -0,0 +1,74 @@
+//
+//  KSLiveChatroomWelcome.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSLiveChatroomWelcome.h"
+
+@implementation KSLiveChatroomWelcome
+
+- (NSData *)encode {
+    NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
+    if (self.msgId) {
+        [dataDict setObject:self.msgId forKey:@"msgId"];
+    } else {
+        [dataDict setObject:@"" forKey:@"msgId"];
+    }
+    if (self.counts) {
+        
+        [dataDict setObject:@(self.counts) forKey:@"counts"];
+    }
+    if (self.rank) {
+        [dataDict setObject:@(self.rank) forKey:@"rank"];
+    }
+    if (self.level) {
+        
+        [dataDict setObject:@(self.level) forKey:@"level"];
+    }
+    if (self.extra) {
+        [dataDict setObject:self.extra forKey:@"extra"];
+    } else {
+        [dataDict setObject:@"" forKey:@"extra"];
+    }
+    
+    
+    if (self.senderUserInfo) {
+        [dataDict setObject:[self encodeUserInfo:self.senderUserInfo] forKey:@"user"];
+    }
+    
+    NSData *data = [NSJSONSerialization dataWithJSONObject:dataDict options:kNilOptions error:nil];
+    return data;
+}
+
+- (void)decodeWithData:(NSData *)data {
+    if (data == nil) {
+        return;
+    }
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json) {
+        self.msgId = [json stringValueForKey:@"msgId"];
+        self.counts = [[json stringValueForKey:@"counts"] intValue];
+        self.rank = [[json stringValueForKey:@"rank"] intValue];
+        self.level = [[json stringValueForKey:@"level"] intValue];
+        
+        self.extra = [json stringValueForKey:@"extra"];
+        NSDictionary *userinfoDic = dictionary[@"user"];
+        [self decodeUserInfo:userinfoDic];
+    }
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:Welcome";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+    return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+    return MessagePersistent_NONE;
+}
+@end

+ 20 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/KSEnterLiveroomManager.h

@@ -0,0 +1,20 @@
+//
+//  KSEnterLiveroomManager.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <Foundation/Foundation.h>
+#import "CustomNavViewController.h"
+
+typedef void(^EnterCallback)(void);
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSEnterLiveroomManager : NSObject
+
++ (void)joinLiveWithRoomId:(NSString *)roomId inController:(CustomNavViewController *)navCtrl callback:(EnterCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 64 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/KSEnterLiveroomManager.m

@@ -0,0 +1,64 @@
+//
+//  KSEnterLiveroomManager.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSEnterLiveroomManager.h"
+#import "LiveVideoRoomViewController.h"
+
+@implementation KSEnterLiveroomManager
+
++ (void)joinLiveWithRoomId:(NSString *)roomId inController:(CustomNavViewController *)navCtrl callback:(EnterCallback)callback {
+    [KSNetworkingManager liveRoomJoinRoomRequest:KS_GET roomUid:roomId success:^(NSDictionary * _Nonnull dic) {
+        callback();
+        if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
+            [self joinRoomWithMessage:[dic dictionaryValueForKey:@"data"] controller:navCtrl];
+        }
+        else {
+            [self MBShowInWindow:MESSAGEKEY];
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        callback();
+    }];
+}
+
++ (void)joinRoomWithMessage:(NSDictionary *)source controller:(CustomNavViewController *)navCtrl {
+    LiveVideoRoomViewController *liveVC = [[LiveVideoRoomViewController alloc] init];
+    liveVC.roomId = [source stringValueForKey:@"roomUid"];
+    liveVC.liveRoleType = RCRTCLiveRoleTypeBroadcaster;
+    liveVC.createrId = [source stringValueForKey:@"speakerId"];
+    liveVC.createrName = [source stringValueForKey:@"speakerName"];
+    liveVC.createrAvatal = [source stringValueForKey:@"speakerPic"];
+    liveVC.likeCount = [source integerValueForKey:@"likeNum"]; // 点赞数
+    NSInteger lookCount = [source integerValueForKey:@"lookNum"] + 1;
+    liveVC.totalCount = lookCount; // 观看人数
+    
+    BOOL isTemp = [[source stringValueForKey:@"roomType"] isEqualToString:@"TEMP"];
+    liveVC.isTempRoom = isTemp;
+    if (isTemp == NO) {
+        liveVC.liveEndTime = [source stringValueForKey:@"liveEndTime"];
+        liveVC.expiredMinute = [source integerValueForKey:@"expiredMinute"];
+    }
+    CustomNavViewController *liveNav = [[CustomNavViewController alloc] initWithRootViewController:liveVC];
+    liveNav.modalPresentationStyle = UIModalPresentationFullScreen;
+    [navCtrl.visibleViewController presentViewController:liveNav animated:YES completion:nil];
+}
+
++ (void)MBShowInWindow:(NSString *)str {
+    [MBProgressHUD hideHUD];
+    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:[UIApplication sharedApplication].keyWindow animated:YES];
+    hud.removeFromSuperViewOnHide =YES;
+    hud.mode = MBProgressHUDModeText;
+    hud.label.text = str;
+    hud.label.numberOfLines = 0;
+    hud.minSize = CGSizeMake(132.f, 60.0f);
+    hud.label.textColor = [UIColor whiteColor];
+    hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
+    hud.bezelView.backgroundColor = [UIColor colorWithHexString:@"#000000" alpha:0.8];
+    double hiddenTime = str.length > 15 ? 3.0f : 1.5f;
+    [hud hideAnimated:YES afterDelay:hiddenTime];
+}
+
+@end

+ 38 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/KSLiveStreamVideo.h

@@ -0,0 +1,38 @@
+//
+//  KSLiveStreamVideo.h
+//  LiveStreamDemo
+//
+//  Created by Kyle on 2021/10/21.
+//
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#import <RongRTCLib/RongRTCLib.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSLiveStreamVideo : NSObject
+
+@property (nonatomic, strong) NSString *userId;
+
+@property(nonatomic, copy) NSString *streamId;
+
+/*!
+ 包含子类的 RCRTCLocalVideoView 和 RCRTCRemoteVideoView
+ */
+@property(nonatomic, strong) RCRTCVideoView *canvesView;
+
+/*!
+ RCRTCRemoteVideoView 初始化
+ @param streamId  音视频流 Id
+ */
+- (instancetype)initWithStreamId:(NSString *)streamId;
+
+/*!
+ 本地 RCRTCLocalVideoView 初始化
+ */
++ (instancetype)LocalStreamVideo;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 36 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/KSLiveStreamVideo.m

@@ -0,0 +1,36 @@
+//
+//  KSLiveStreamVideo.m
+//  LiveStreamDemo
+//
+//  Created by Kyle on 2021/10/21.
+//
+
+#import "KSLiveStreamVideo.h"
+static NSString *zero = @"0";
+
+@implementation KSLiveStreamVideo
+
+// 根据 streamId 创建并设置远端视频预览视图
+- (instancetype)initWithStreamId:(nonnull NSString *)stream {
+    if (self = [super init]) {
+        self.streamId = stream;
+        self.canvesView = [[RCRTCVideoView alloc] init];
+        self.canvesView.frameAnimated = NO;
+        self.canvesView.translatesAutoresizingMaskIntoConstraints = NO;
+        self.canvesView.fillMode = RCRTCVideoFillModeAspectFill;
+    }
+    return self;
+}
+
++ (instancetype)LocalStreamVideo {
+    KSLiveStreamVideo *localStreamVideo = [[KSLiveStreamVideo alloc] init];
+    // 初始化 这里的 streamId 推荐 0
+    localStreamVideo.streamId = zero;
+    localStreamVideo.canvesView = [[RCRTCVideoView alloc] init];
+    localStreamVideo.canvesView.frameAnimated = NO;
+    localStreamVideo.canvesView.translatesAutoresizingMaskIntoConstraints = NO;
+    localStreamVideo.canvesView.fillMode = RCRTCVideoFillModeAspectFill;
+    return localStreamVideo;
+}
+
+@end

+ 3 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/CreateLiveBodyView.h

@@ -7,7 +7,7 @@
 
 
 #import <UIKit/UIKit.h>
 #import <UIKit/UIKit.h>
 
 
-//typedef NS_ENUM(NSInteger, LIVECREATE_) <#name#>;
+typedef void(^CreateLiveCallback)(NSString * _Nonnull title,NSString *content);
 
 
 NS_ASSUME_NONNULL_BEGIN
 NS_ASSUME_NONNULL_BEGIN
 
 
@@ -15,6 +15,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 
 + (instancetype)shareInstance;
 + (instancetype)shareInstance;
 
 
+- (void)createSureCallback:(CreateLiveCallback)callback;
+
 @end
 @end
 
 
 NS_ASSUME_NONNULL_END
 NS_ASSUME_NONNULL_END

+ 94 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/CreateLiveBodyView.m

@@ -7,13 +7,107 @@
 
 
 #import "CreateLiveBodyView.h"
 #import "CreateLiveBodyView.h"
 
 
+@interface CreateLiveBodyView ()<UITextFieldDelegate,UITextViewDelegate>
+
+@property (weak, nonatomic) IBOutlet UITextField *titleField;
+
+@property (weak, nonatomic) IBOutlet UITextView *inputView;
+
+@property (weak, nonatomic) IBOutlet UILabel *tipsLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *countLabel;
+
+@property (nonatomic, copy) CreateLiveCallback callback;
+
+@end
+
 @implementation CreateLiveBodyView
 @implementation CreateLiveBodyView
 
 
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    self.titleField.delegate = self;
+    self.titleField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"请输入直播标题" attributes:@{NSForegroundColorAttributeName:HexRGB(0xc1c1c1)}];
+    self.inputView.delegate = self;
+}
+
 + (instancetype)shareInstance {
 + (instancetype)shareInstance {
     CreateLiveBodyView *view = [[[NSBundle mainBundle] loadNibNamed:@"CreateLiveBodyView" owner:nil options:nil] firstObject];
     CreateLiveBodyView *view = [[[NSBundle mainBundle] loadNibNamed:@"CreateLiveBodyView" owner:nil options:nil] firstObject];
     return view;
     return view;
 }
 }
 
 
+- (void)createSureCallback:(CreateLiveCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+
+- (IBAction)sureAction:(id)sender {
+    [self endEditing:YES];
+    if ([NSString isEmptyString:self.titleField.text]) {
+        [self MBPShow:@"请输入直播标题"];
+        return;
+    }
+    if ([NSString isEmptyString:self.inputView.text]) {
+        [self MBPShow:@"请输入直播内容"];
+        return;
+    }
+    if (self.callback) {
+        self.callback(self.titleField.text, self.inputView.text);
+    }
+}
+
+#pragma mark   ---- delegate
+
+- (void)textViewDidBeginEditing:(UITextView *)textView {
+    self.tipsLabel.hidden = YES;
+}
+- (void)textViewDidEndEditing:(UITextView *)textView {
+    if ([NSString isEmptyString:textView.text]) {
+        self.tipsLabel.hidden = NO;
+    }
+}
+
+- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
+    if ([text isEqualToString:@"\n"]) {
+        [self endEditing:YES];
+        return YES;
+    }
+    if ([text isEqualToString:@""]) {
+        return YES;
+    }
+    
+    // 长度判断
+    // 输入控制
+    NSString *newString = [textView.text stringByReplacingCharactersInRange:range withString:text];
+    if (newString.length > 200) {
+        return NO;
+    }
+    self.countLabel.text = [NSString stringWithFormat:@"%zd/200",newString.length];
+    
+    return YES;
+}
+
+
+- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
+    [self endEditing:YES];
+    return YES;
+}
+
+- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
+    [self endEditing:YES];
+}
+
+- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
+    if ([string isEqualToString:@"\n"]) {
+        [self endEditing:YES];
+        return YES;
+    }
+    if ([string isEqualToString:@""]) {
+        return YES;
+    }
+    return YES;
+}
 /*
 /*
 // Only override drawRect: if you perform custom drawing.
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 // An empty implementation adversely affects performance during animation.

+ 140 - 3
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/CreateLiveBodyView.xib

@@ -11,13 +11,150 @@
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
         <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="CreateLiveBodyView">
         <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="CreateLiveBodyView">
-            <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
+            <rect key="frame" x="0.0" y="0.0" width="414" height="642"/>
             <autoresizingMask key="autoresizingMask"/>
             <autoresizingMask key="autoresizingMask"/>
-            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IUC-2g-F8n">
+                    <rect key="frame" x="14" y="10" width="386" height="90"/>
+                    <subviews>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="*" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="l2j-s9-lvC">
+                            <rect key="frame" x="12" y="20" width="8" height="21"/>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
+                            <color key="textColor" red="1" green="0.30588235294117649" blue="0.098039215686274508" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="直播标题" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="A4e-tm-roy">
+                            <rect key="frame" x="20" y="20" width="70" height="21"/>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
+                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="请输入直播标题" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Zer-5J-UAf">
+                            <rect key="frame" x="12" y="46" width="362" height="30"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="30" id="mUd-Fw-YMu"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                            <textInputTraits key="textInputTraits"/>
+                        </textField>
+                    </subviews>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstAttribute="trailing" secondItem="Zer-5J-UAf" secondAttribute="trailing" constant="12" id="0Oh-5z-h7T"/>
+                        <constraint firstItem="l2j-s9-lvC" firstAttribute="leading" secondItem="IUC-2g-F8n" secondAttribute="leading" constant="12" id="BOJ-eO-mw1"/>
+                        <constraint firstAttribute="height" constant="90" id="Fpc-VG-t85"/>
+                        <constraint firstItem="A4e-tm-roy" firstAttribute="leading" secondItem="l2j-s9-lvC" secondAttribute="trailing" id="K1z-PI-rxs"/>
+                        <constraint firstItem="Zer-5J-UAf" firstAttribute="leading" secondItem="IUC-2g-F8n" secondAttribute="leading" constant="12" id="d7i-X6-VOw"/>
+                        <constraint firstItem="Zer-5J-UAf" firstAttribute="top" secondItem="l2j-s9-lvC" secondAttribute="bottom" constant="5" id="j6k-5Z-Hvt"/>
+                        <constraint firstItem="A4e-tm-roy" firstAttribute="centerY" secondItem="l2j-s9-lvC" secondAttribute="centerY" id="kEl-K0-6Td"/>
+                        <constraint firstItem="l2j-s9-lvC" firstAttribute="top" secondItem="IUC-2g-F8n" secondAttribute="top" constant="20" id="oPb-QA-9aG"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="10"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="AgR-dK-40h">
+                    <rect key="frame" x="14" y="112" width="386" height="210"/>
+                    <subviews>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="*" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="REu-cP-KFW">
+                            <rect key="frame" x="12" y="20" width="8" height="21"/>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
+                            <color key="textColor" red="1" green="0.30588235289999999" blue="0.098039215690000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="直播内容" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="R3Q-ty-XEs">
+                            <rect key="frame" x="20" y="20" width="70" height="21"/>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
+                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ez8-R7-sTU">
+                            <rect key="frame" x="12" y="53" width="362" height="137"/>
+                            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <color key="textColor" red="0.2666666667" green="0.2666666667" blue="0.2666666667" alpha="1" colorSpace="calibratedRGB"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                            <textInputTraits key="textInputTraits" autocapitalizationType="sentences" returnKeyType="done" enablesReturnKeyAutomatically="YES"/>
+                        </textView>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="请输入直播内容" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tnb-4n-z1s">
+                            <rect key="frame" x="12" y="62" width="114.5" height="20"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                            <color key="textColor" red="0.75686274509803919" green="0.75686274509803919" blue="0.75686274509803919" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0/200" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="K6I-S3-WCn">
+                            <rect key="frame" x="342" y="190" width="34" height="20"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="20" id="ajJ-B9-Cgj"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                            <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                    </subviews>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstAttribute="bottom" secondItem="ez8-R7-sTU" secondAttribute="bottom" constant="20" id="4ZO-J7-jFS"/>
+                        <constraint firstItem="ez8-R7-sTU" firstAttribute="top" secondItem="R3Q-ty-XEs" secondAttribute="bottom" constant="12" id="5ZN-9v-V8G"/>
+                        <constraint firstAttribute="bottom" secondItem="K6I-S3-WCn" secondAttribute="bottom" id="995-a4-PRl"/>
+                        <constraint firstAttribute="trailing" secondItem="K6I-S3-WCn" secondAttribute="trailing" constant="10" id="9Qc-mX-mBv"/>
+                        <constraint firstItem="tnb-4n-z1s" firstAttribute="leading" secondItem="AgR-dK-40h" secondAttribute="leading" constant="12" id="DVw-I6-R14"/>
+                        <constraint firstAttribute="trailing" secondItem="ez8-R7-sTU" secondAttribute="trailing" constant="12" id="F9X-Z3-UJU"/>
+                        <constraint firstItem="REu-cP-KFW" firstAttribute="leading" secondItem="AgR-dK-40h" secondAttribute="leading" constant="12" id="Guz-3G-MrC"/>
+                        <constraint firstItem="REu-cP-KFW" firstAttribute="top" secondItem="AgR-dK-40h" secondAttribute="top" constant="20" id="R00-CT-9IK"/>
+                        <constraint firstItem="tnb-4n-z1s" firstAttribute="top" secondItem="REu-cP-KFW" secondAttribute="bottom" constant="21" id="RsR-U6-Pel"/>
+                        <constraint firstAttribute="height" constant="210" id="XPt-iy-fEJ"/>
+                        <constraint firstItem="R3Q-ty-XEs" firstAttribute="centerY" secondItem="REu-cP-KFW" secondAttribute="centerY" id="pVY-BB-3wB"/>
+                        <constraint firstItem="R3Q-ty-XEs" firstAttribute="leading" secondItem="REu-cP-KFW" secondAttribute="trailing" id="tUw-eq-CSk"/>
+                        <constraint firstItem="ez8-R7-sTU" firstAttribute="leading" secondItem="AgR-dK-40h" secondAttribute="leading" constant="12" id="yal-dC-sF8"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="10"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NVl-Up-QMs">
+                    <rect key="frame" x="28" y="555" width="358" height="44"/>
+                    <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="44" id="HUl-sw-SN4"/>
+                    </constraints>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" title="确认"/>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="22"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                    <connections>
+                        <action selector="sureAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="Wco-AZ-BO6"/>
+                    </connections>
+                </button>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="NVl-Up-QMs" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="28" id="70y-ah-k3R"/>
+                <constraint firstAttribute="trailing" secondItem="NVl-Up-QMs" secondAttribute="trailing" constant="28" id="77x-p2-Jer"/>
+                <constraint firstItem="AgR-dK-40h" firstAttribute="trailing" secondItem="IUC-2g-F8n" secondAttribute="trailing" id="BsZ-RO-vmP"/>
+                <constraint firstAttribute="trailing" secondItem="IUC-2g-F8n" secondAttribute="trailing" constant="14" id="HHl-5j-HQK"/>
+                <constraint firstItem="IUC-2g-F8n" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="KzN-3e-sOc"/>
+                <constraint firstItem="IUC-2g-F8n" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="lnB-2q-sHz"/>
+                <constraint firstItem="AgR-dK-40h" firstAttribute="leading" secondItem="IUC-2g-F8n" secondAttribute="leading" id="oc2-Yu-gbH"/>
+                <constraint firstItem="AgR-dK-40h" firstAttribute="top" secondItem="IUC-2g-F8n" secondAttribute="bottom" constant="12" id="r6D-oe-Wh7"/>
+                <constraint firstAttribute="bottom" secondItem="NVl-Up-QMs" secondAttribute="bottom" constant="43" id="uVR-9h-5g8"/>
+            </constraints>
             <nil key="simulatedTopBarMetrics"/>
             <nil key="simulatedTopBarMetrics"/>
             <nil key="simulatedBottomBarMetrics"/>
             <nil key="simulatedBottomBarMetrics"/>
             <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
             <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <point key="canvasLocation" x="132" y="79"/>
+            <connections>
+                <outlet property="countLabel" destination="K6I-S3-WCn" id="KTW-ST-cYe"/>
+                <outlet property="inputView" destination="ez8-R7-sTU" id="KkF-CH-6Gx"/>
+                <outlet property="tipsLabel" destination="tnb-4n-z1s" id="hVS-S1-W0w"/>
+                <outlet property="titleField" destination="Zer-5J-UAf" id="9pj-Rs-O21"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="163.39285714285714"/>
         </view>
         </view>
     </objects>
     </objects>
     <resources>
     <resources>

+ 136 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/Cell/BaseEmoji.plist

@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+	<string>😃</string>
+	<string>😀</string>
+	<string>😊</string>
+	<string>☺️</string>
+	<string>😉</string>
+	<string>😍</string>
+	<string>😘</string>
+	<string>😚</string>
+	<string>😜</string>
+	<string>😝</string>
+	<string>😳</string>
+	<string>😁</string>
+	<string>😔</string>
+	<string>😌</string>
+	<string>😒</string>
+	<string>😟</string>
+	<string>😞</string>
+	<string>😣</string>
+	<string>😢</string>
+	<string>😂</string>
+	<string>😭</string>
+	<string>😪</string>
+	<string>😰</string>
+	<string>😅</string>
+	<string>😓</string>
+	<string>😫</string>
+	<string>😩</string>
+	<string>😨</string>
+	<string>😱</string>
+	<string>😡</string>
+	<string>😤</string>
+	<string>😖</string>
+	<string>😆</string>
+	<string>😋</string>
+	<string>😷</string>
+	<string>😎</string>
+	<string>😴</string>
+	<string>😲</string>
+	<string>😵</string>
+	<string>😈</string>
+	<string>👿</string>
+	<string>😯</string>
+	<string>😬</string>
+	<string>😕</string>
+	<string>😶</string>
+	<string>😇</string>
+	<string>😏</string>
+	<string>😑</string>
+	<string>🙈</string>
+	<string>🙉</string>
+	<string>🙊</string>
+	<string>👽</string>
+	<string>💩</string>
+	<string>❤️</string>
+	<string>💔</string>
+	<string>🔥</string>
+	<string>💢</string>
+	<string>💤</string>
+	<string>🚫</string>
+	<string>⭐</string>
+	<string>⚡</string>
+	<string>🌙</string>
+	<string>☀</string>
+	<string>⛅</string>
+	<string>☁</string>
+	<string>❄</string>
+	<string>☔</string>
+	<string>⛄</string>
+	<string>👍</string>
+	<string>👎</string>
+	<string>🤝</string>
+	<string>👌</string>
+	<string>👊</string>
+	<string>✊</string>
+	<string>✌</string>
+	<string>✋</string>
+	<string>🙏</string>
+	<string>☝</string>
+	<string>👏</string>
+	<string>💪</string>
+	<string>👪</string>
+	<string>👫</string>
+	<string>👼</string>
+	<string>🐴</string>
+	<string>🐶</string>
+	<string>🐷</string>
+	<string>👻</string>
+	<string>🌹</string>
+	<string>🌻</string>
+	<string>🌲</string>
+	<string>🎄</string>
+	<string>🎁</string>
+	<string>🎉</string>
+	<string>💰</string>
+	<string>🎂</string>
+	<string>🍖</string>
+	<string>🍚</string>
+	<string>🍦</string>
+	<string>🍫</string>
+	<string>🍉</string>
+	<string>🍷</string>
+	<string>🍻</string>
+	<string>☕</string>
+	<string>🏀</string>
+	<string>⚽</string>
+	<string>🏂</string>
+	<string>🎤</string>
+	<string>🎵</string>
+	<string>🎲</string>
+	<string>🀄</string>
+	<string>👑</string>
+	<string>💄</string>
+	<string>💋</string>
+	<string>💍</string>
+	<string>📚</string>
+	<string>🎓</string>
+	<string>✏</string>
+	<string>🏡</string>
+	<string>🚿</string>
+	<string>💡</string>
+	<string>📞</string>
+	<string>📢</string>
+	<string>🕖</string>
+	<string>⏰</string>
+	<string>⏳</string>
+	<string>💣</string>
+	<string>🔫</string>
+	<string>💊</string>
+	<string>🚀</string>
+	<string>🌏</string>
+</array>
+</plist>

+ 19 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/Cell/KSChatEmojiCollectionCell.h

@@ -0,0 +1,19 @@
+//
+//  KSChatEmojiCollectionCell.h
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/20.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSChatEmojiCollectionCell : UICollectionViewCell
+
+- (void)setData:(NSString *)emojiStr showDeleteImg:(BOOL)show;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 50 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/Cell/KSChatEmojiCollectionCell.m

@@ -0,0 +1,50 @@
+//
+//  KSChatEmojiCollectionCell.m
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/20.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "KSChatEmojiCollectionCell.h"
+@interface KSChatEmojiCollectionCell ()
+
+@property (nonatomic, strong) UILabel *emojiLabel;
+
+@property (nonatomic, strong) UIImageView *deleteImg;
+
+@end
+
+@implementation KSChatEmojiCollectionCell
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self) {
+        self.emojiLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 32, 32)];
+        [self.contentView addSubview:self.emojiLabel];
+        [self.emojiLabel setTextAlignment:NSTextAlignmentCenter];
+        [self.emojiLabel setFont:[UIFont systemFontOfSize:25]];
+        self.deleteImg = [[UIImageView alloc] initWithFrame:CGRectMake(6, 6, 20, 20)];
+        [self.deleteImg setImage:[UIImage imageNamed:@"deleteImg"]];
+        [self.deleteImg setUserInteractionEnabled:YES];
+        [self.contentView addSubview:self.deleteImg];
+    }
+    return self;
+}
+
+- (void)setData:(NSString *)emojiStr showDeleteImg:(BOOL)show {
+    if (!show) {
+        if (emojiStr == nil) {
+            [self.emojiLabel setText:@""];
+        } else {
+            [self.emojiLabel setText:emojiStr];
+        }
+        [self.deleteImg setHidden:YES];
+        [self.emojiLabel setHidden:NO];
+    } else {
+        [self.deleteImg setHidden:NO];
+        [self.emojiLabel setHidden:YES];
+    }
+}
+
+@end

+ 46 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatEmojiBoardView.h

@@ -0,0 +1,46 @@
+//
+//  KSChatEmojiBoardView.h
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/20.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class KSChatEmojiBoardView;
+
+/**
+ 表情输入的回调
+ */
+@protocol KSChatEmojiViewDelegate <NSObject>
+
+@optional
+
+/**
+ 点击表情的回调
+ 
+ @param emojiView 表情输入的View
+ @param string    点击的表情对应的字符串编码
+ */
+- (void)didTouchEmojiView:(KSChatEmojiBoardView *_Nonnull)emojiView touchedEmoji:(NSString *)string;
+
+/**
+ 点击发送按钮的回调
+
+ */
+- (void)didSendButtonEvent;
+
+@end
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSChatEmojiBoardView : UIView
+
+/*!
+ 表情输入的回调
+ */
+@property(nonatomic, weak) id<KSChatEmojiViewDelegate> delegate;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 236 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatEmojiBoardView.m

@@ -0,0 +1,236 @@
+//
+//  KSChatEmojiBoardView.m
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/20.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "KSChatEmojiBoardView.h"
+#import "KSChatEmojiCollectionCell.h"
+
+static NSString * const emojiCollectionViewCellIdentify = @"emojiCollectionViewCellIdentify";
+
+@interface KSChatEmojiBoardView ()<UIScrollViewDelegate, UICollectionViewDelegate, UICollectionViewDataSource>
+
+/**
+ 表情容器的View
+ */
+@property(nonatomic, strong) UICollectionView *emojiContentView;
+
+/**
+ emoji表情数组
+ */
+@property(nonatomic, strong) NSMutableArray *emojiArray;
+
+
+@property(nonatomic, strong) UIPageControl *pageControl;
+
+@property(nonatomic, strong) UIView *bottomContentView;
+
+@property(nonatomic, strong) UIButton *emojiBtn;
+
+@property(nonatomic, strong) UIButton *sendBtn;
+
+@property(nonatomic, assign) NSUInteger rows;
+
+@property(nonatomic, assign) NSUInteger columns;
+
+//表情页数
+@property(nonatomic, assign) NSUInteger pages;
+
+@end
+
+
+@implementation KSChatEmojiBoardView
+
+- (instancetype)init {
+    self = [super init];
+    if (self) {
+        NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
+        NSString *bundlePath = [resourcePath stringByAppendingPathComponent:@"BaseEmoji.plist"];
+        self.emojiArray = [[NSMutableArray alloc]initWithContentsOfFile:bundlePath];
+        self.rows = 3;
+        self.columns = 8;
+        self.pages = self.emojiArray.count/23 + ((self.emojiArray.count%23 == 0) ? 0 : 1);
+        for (int i = 1; i < self.pages; i++) {
+            [self.emojiArray insertObject:@"" atIndex:(i*24 - 1)];
+        }
+    }
+    return self;
+}
+
+- (void)setFrame:(CGRect)frame {
+    [super setFrame:frame];
+    [self initializedSubViews];
+}
+
+#pragma mark - UICollectionViewDelegate, UICollectionViewDataSource
+//  每页24个表情
+- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
+
+    return 24;
+}
+
+//  页数
+- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
+    return self.pages ? self.pages : (_emojiArray.count/23) + (_emojiArray.count%23 == 0 ? 0:1);
+}
+
+- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
+    KSChatEmojiCollectionCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:emojiCollectionViewCellIdentify forIndexPath:indexPath];
+    if (!cell) {
+        cell = [[KSChatEmojiCollectionCell alloc] init];
+    }
+    if (indexPath.row == 23) {
+        //  展示删除图案
+        [cell setData:nil showDeleteImg:YES];
+    } else {
+        //  横向排版
+        NSInteger row = indexPath.row % self.rows;
+        NSInteger col = floor(indexPath.row/self.rows);
+        //Calculate the new index in the `NSArray`
+        NSInteger newIndex = ((int)indexPath.section * self.rows * self.columns) + col + row * self.columns;
+        if (newIndex < _emojiArray.count) {
+            [cell setData:_emojiArray[newIndex] showDeleteImg:NO];
+        }
+        else {
+            [cell setData:nil showDeleteImg:NO];
+        }
+    }
+    return cell;
+}
+
+//  点击表情
+- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
+    
+    if ([self.delegate respondsToSelector:@selector(didTouchEmojiView:touchedEmoji:)]) {
+        
+        if (indexPath.row == 23) {
+            [self.delegate didTouchEmojiView:self touchedEmoji:nil];
+        } else {
+            NSInteger row = indexPath.row % self.rows;
+            NSInteger col = floor(indexPath.row/self.rows);
+            NSInteger newIndex = ((int)indexPath.section * self.rows * self.columns) + col + row * self.columns;
+            [self.delegate didTouchEmojiView:self touchedEmoji:_emojiArray[newIndex]];
+        }
+    }
+}
+- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
+    
+}
+
+//  停止滚动的时候
+- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
+    CGFloat contenOffset = scrollView.contentOffset.x;
+    int page = contenOffset/scrollView.frame.size.width + ((int)contenOffset %(int)scrollView.frame.size.width==0?0:1);
+    _pageControl.currentPage = page;
+}
+
+#pragma mark - action
+
+- (void)sendBtnClick:(UIButton *)sender {
+    if ([self.delegate respondsToSelector:@selector(didSendButtonEvent)]) {
+        [self.delegate didSendButtonEvent];
+    }
+}
+
+- (void)emojiBtnClick:(UIButton *)sender {
+    NSLog(@"点击了emoji表情选择按钮");
+}
+
+#pragma mark - UI
+- (void)initializedSubViews {
+    [self setBackgroundColor:[UIColor whiteColor]];
+    [self addSubview:self.emojiContentView];
+    [_emojiContentView setFrame:CGRectMake(0, 0, self.bounds.size.width, 170)];
+    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
+    layout.itemSize = CGSizeMake(32, 32);
+    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
+    //计算每个分区的左右边距
+    float distanceX = (self.bounds.size.width - 8*32)/9;
+    float distanceY = (170 - 3*32)/4;
+    //设置分区的内容偏移
+    layout.sectionInset = UIEdgeInsetsMake(distanceY, distanceX, distanceY, distanceX);
+    //设置行列间距
+    layout.minimumLineSpacing = distanceX;
+    layout.minimumInteritemSpacing = distanceY;
+
+    [_emojiContentView setCollectionViewLayout:layout animated:NO completion:nil];
+    
+    [self addSubview:self.pageControl];
+    [_pageControl setCurrentPageIndicatorTintColor:[UIColor blackColor]];
+    [_pageControl setPageIndicatorTintColor:[UIColor grayColor]];
+    [_pageControl setFrame:CGRectMake(0, 170, self.bounds.size.width, 10)];
+    [_pageControl setNumberOfPages:(self.pages ? self.pages : (_emojiArray.count/23) + (_emojiArray.count%23 == 0 ? 0:1))];
+     
+    [self addSubview:self.bottomContentView];
+    [_bottomContentView setFrame:CGRectMake(0, 180, self.bounds.size.width, 40)];
+    
+    [_bottomContentView addSubview:self.emojiBtn];
+    [_emojiBtn setFrame:CGRectMake(10, 0, 40, 40)];
+    
+    [_bottomContentView addSubview:self.sendBtn];
+    [_sendBtn setFrame:CGRectMake(self.bounds.size.width - 50, 0, 50, 40)];
+}
+
+- (UICollectionView *)emojiContentView {
+    if (!_emojiContentView) {
+        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
+        _emojiContentView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
+        [_emojiContentView setPagingEnabled:YES];
+        [_emojiContentView setShowsVerticalScrollIndicator:NO];
+        [_emojiContentView setShowsHorizontalScrollIndicator:NO];
+        [_emojiContentView setDelegate:self];
+        [_emojiContentView setDataSource:self];
+        [_emojiContentView registerClass:[KSChatEmojiCollectionCell class] forCellWithReuseIdentifier:emojiCollectionViewCellIdentify];
+        [_emojiContentView setBackgroundColor:[UIColor whiteColor]];
+    }
+    return _emojiContentView;
+}
+
+- (UIPageControl *)pageControl {
+    if (!_pageControl) {
+        _pageControl = [[UIPageControl alloc] init];
+    }
+    return  _pageControl;
+}
+- (UIView *)bottomContentView {
+    if (!_bottomContentView) {
+        _bottomContentView = [[UIView alloc] init];
+        [_bottomContentView setBackgroundColor:HexRGB(0xf5f5f5)];
+    }
+    return _bottomContentView;
+}
+
+- (UIButton *)emojiBtn {
+    if (!_emojiBtn) {
+        _emojiBtn = [[UIButton alloc] init];
+        [_emojiBtn addTarget:self
+                     action:@selector(emojiBtnClick:)
+           forControlEvents:UIControlEventTouchUpInside];
+        [_emojiBtn setTitle:@"😃" forState:UIControlStateNormal];
+    }
+    return _emojiBtn;
+}
+
+- (UIButton *)sendBtn {
+    if (!_sendBtn) {
+        _sendBtn = [[UIButton alloc] init];
+        [_sendBtn setTitleColor:HexRGB(0x444444) forState:UIControlStateNormal];
+        [_sendBtn addTarget:self
+                      action:@selector(sendBtnClick:)
+            forControlEvents:UIControlEventTouchUpInside];
+        [_sendBtn setTitle:@"发送" forState:UIControlStateNormal];
+    }
+    return _sendBtn;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 99 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatInputBarControl.h

@@ -0,0 +1,99 @@
+//
+//  KSChatInputBarControl.h
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/20.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#define HeighChatInputBar 48.0f
+
+/**
+ 输入工具栏的输入模式
+ */
+typedef NS_ENUM(NSInteger, KSBottomBarStatus) {
+    /**
+     初始状态
+     */
+    KSBottomBarStatusDefault = 0,
+    /**
+     文本输入状态
+     */
+    KSBottomBarStatusKeyboard,
+    /**
+     表情输入模式
+     */
+    KSBottomBarStatusEmoji
+};
+
+/**
+ 输入工具栏的点击监听器
+ */
+@protocol KSChatInputBarControlDelegate <NSObject>
+
+@optional
+#pragma mark - 输入框及外部区域事件
+
+/**
+ 输入工具栏尺寸(高度)发生变化的回调
+ 
+ @param frame 输入工具栏最终需要显示的Frame
+ */
+- (void)onInputBarControlContentSizeChanged:(CGRect)frame
+                      withAnimationDuration:(CGFloat)duration
+                          andAnimationCurve:(UIViewAnimationCurve)curve;
+/**
+ 输入框中内容发生变化的回调
+ 
+ @param inputTextView 文本输入框
+ @param range         当前操作的范围
+ @param text          插入的文本
+ */
+- (void)onInputTextView:(UITextView *_Nonnull)inputTextView
+shouldChangeTextInRange:(NSRange)range
+        replacementText:(NSString *_Nonnull)text;
+-(void)inputTextViewTextViewDidChange:(UITextView *_Nonnull)textView;;
+
+#pragma mark - 输入框事件
+
+/**
+ *  点击键盘回车或者emoji表情面板的发送按钮执行的方法
+ 
+ *  @param text      输入框的内容
+ */
+- (void)onTouchSendButton:(NSString *_Nonnull)text;
+
+@end
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSChatInputBarControl : UIView
+
+@property(nonatomic, weak) id<KSChatInputBarControlDelegate> delegate;
+
+
+- (void)layoutContainerView;
+/**
+ 设置输入工具栏状态
+
+ */
+-(void)setInputBarStatus:(KSBottomBarStatus)Status;
+
+/**
+ 重新调整页面布局时需要调用这个方法来设置输入框的frame
+ 
+ @param frame       显示的Frame
+ */
+-(void)changeInputBarFrame:(CGRect)frame;
+
+/**
+ 清除输入框内容
+ */
+-(void)clearInputView;
+
+- (id)initWithStatus:(KSBottomBarStatus)status;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 206 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatInputBarControl.m

@@ -0,0 +1,206 @@
+//
+//  KSChatInputBarControl.m
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/20.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "KSChatInputBarControl.h"
+#import "KSChatInputView.h"
+#import "KSChatEmojiBoardView.h"
+
+#define HeightEmojBoardView 220.0f
+
+@interface KSChatInputBarControl ()<KSChatInputViewDelegate, KSChatEmojiViewDelegate>
+
+/*!
+ 当前输入框状态
+ */
+@property(nonatomic) KSBottomBarStatus currentBottomBarStatus;
+
+/*!
+ 输入框
+ */
+@property(nonatomic, strong) KSChatInputView *inputBoxView;
+
+/*!
+ 表情View
+ */
+@property(nonatomic, strong) KSChatEmojiBoardView *emojiBoardView;
+
+@property(nonatomic, assign) CGRect originalFrame;
+
+@end
+
+@implementation KSChatInputBarControl
+
+//  初始化
+- (id)initWithStatus:(KSBottomBarStatus)status {
+    self = [super init];
+    if (self) {
+        [self setBackgroundColor:[UIColor clearColor]];
+        [self initializedSubViews];
+        [self registerNotification];
+        [self setCurrentBottomBarStatus:status];
+    }
+    return self;
+}
+
+- (void)setFrame:(CGRect)frame {
+    [super setFrame:frame];
+    if(CGRectEqualToRect(self.originalFrame, CGRectZero)){
+      self.originalFrame = frame;
+    }
+    [_inputBoxView setFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
+}
+
+-(void)setInputBarStatus:(KSBottomBarStatus)Status {
+    [self setCurrentBottomBarStatus:Status];
+    //  弹出键盘
+    if (Status == KSBottomBarStatusKeyboard) {
+        [_inputBoxView.emojiButton setSelected:NO];
+        [_inputBoxView.inputTextView becomeFirstResponder];
+    } else {
+        if (Status == KSBottomBarStatusEmoji) {
+            [_inputBoxView.emojiButton setSelected:YES];
+        } else {
+            [_inputBoxView.emojiButton setSelected:NO];
+        }
+        //  其他状态隐藏键盘
+        if (_inputBoxView.inputTextView.isFirstResponder) {
+            [_inputBoxView.inputTextView resignFirstResponder];
+        }
+    }
+    
+    if (Status != KSBottomBarStatusEmoji) {
+        //  非emoji状态设置输入框InputView为nil
+        [_inputBoxView.inputTextView setInputView:nil];
+    }
+}
+
+-(void)changeInputBarFrame:(CGRect)frame{
+    
+}
+
+#pragma mark - Notification action
+- (void) KeyboardWillShow:(NSNotification*)notification {
+    CGRect keyboardBounds = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
+    UIViewAnimationCurve curve = [[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
+    if ([self.delegate respondsToSelector:@selector(onInputBarControlContentSizeChanged:withAnimationDuration:andAnimationCurve:)]) {
+        [self.delegate onInputBarControlContentSizeChanged:keyboardBounds withAnimationDuration:0.1 andAnimationCurve:curve];
+    }
+}
+
+- (void)KeyboardWillHide:(NSNotification*)notification {
+    if ([self.delegate respondsToSelector:@selector(onInputBarControlContentSizeChanged:withAnimationDuration:andAnimationCurve:)]) {
+        //  目前只使用y值即可
+        CGRect frame ;
+        frame.origin.y = [[UIScreen mainScreen] bounds].size.height;
+        if (IS_iPhoneX) {
+            frame.origin.y -= 34;
+        }
+        [self.delegate onInputBarControlContentSizeChanged:frame withAnimationDuration:0.3 andAnimationCurve:0];
+    }
+}
+
+#pragma mark - RCCRInputViewDelegate
+//  点击表情按钮
+- (void)didTouchEmojiButton:(UIButton *)sender {
+    [_inputBoxView.inputTextView becomeFirstResponder];
+    if (!sender.selected) {
+        [_inputBoxView.inputTextView setInputView:nil];
+    } else {
+        [_inputBoxView.inputTextView setInputView:self.emojiBoardView];
+        if (!(_emojiBoardView.frame.size.width > 0)) {
+            [_emojiBoardView setFrame:CGRectMake(0, 0, self.bounds.size.width, IS_iPhoneX ? (HeightEmojBoardView + 34) : HeightEmojBoardView)];
+        }
+    }
+    [_inputBoxView.inputTextView reloadInputViews];
+}
+
+//  点击发送
+- (void)didTouchKeyboardReturnKey:(KSChatInputView *)inputControl text:(NSString *)text {
+    if([self.delegate respondsToSelector:@selector(onTouchSendButton:)]){
+        [self.delegate onTouchSendButton:text];
+    }
+}
+
+//  输入框内容变换
+- (void)inputTextView:(UITextView *)inputTextView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
+    if([self.delegate respondsToSelector:@selector(onInputTextView:shouldChangeTextInRange:replacementText:)]){
+        [self.delegate onInputTextView:inputTextView shouldChangeTextInRange:range replacementText:text];
+    }
+}
+-(void)inputTextViewTextViewDidChange:(UITextView *)textView{
+    if (self.delegate && [self.delegate respondsToSelector:@selector(inputTextViewTextViewDidChange:)]) {
+        [self.delegate inputTextViewTextViewDidChange:textView];
+    }
+}
+#pragma mark - RCCREmojiViewDelegate
+//  发送表情
+- (void)didSendButtonEvent {
+    NSString *sendText = self.inputBoxView.inputTextView.text;
+    
+    NSString *formatString = [sendText
+                               stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];    //去掉空格
+    if (0 == [formatString length]) {
+        return;
+    }
+    if([self.delegate respondsToSelector:@selector(onTouchSendButton:)]){
+        [self.delegate onTouchSendButton:sendText];
+    }
+}
+
+- (void)didTouchEmojiView:(KSChatEmojiBoardView *)emojiView touchedEmoji:(NSString *)string {
+//    NSString *replaceString = string;
+    if (string == nil) {
+        [self.inputBoxView.inputTextView deleteBackward];
+    } else {
+        [self.inputBoxView.inputTextView setText:[self.inputBoxView.inputTextView.text stringByAppendingString:string]];
+    }
+}
+
+#pragma mark - UI
+
+- (void)initializedSubViews {
+    [self addSubview:self.inputBoxView];
+}
+
+- (void)registerNotification {
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(KeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(KeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
+}
+
+- (KSChatInputView *)inputBoxView {
+    if (!_inputBoxView) {
+        _inputBoxView = [[KSChatInputView alloc] initWithStatus:KSBottomBarStatusDefault];
+        [_inputBoxView setDelegate:self];
+    }
+    return _inputBoxView;
+}
+
+//表情区域控件
+- (KSChatEmojiBoardView *)emojiBoardView {
+    if (!_emojiBoardView) {
+        _emojiBoardView = [[KSChatEmojiBoardView alloc] init];
+        _emojiBoardView.delegate = self;
+    }
+    return _emojiBoardView;
+}
+
+- (void)clearInputView {
+    dispatch_async(dispatch_get_main_queue(), ^{
+       [self.inputBoxView clearInputText];
+    });
+    
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 102 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatInputView.h

@@ -0,0 +1,102 @@
+//
+//  KSChatInputView.h
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/20.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "KSChatInputBarControl.h"
+
+#define HeighInputBar 50.0f
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ 输入工具栏的点击监听器
+ */
+@protocol KSChatInputViewDelegate;
+/**
+ 输入框
+ */
+@interface KSChatInputView : UIView
+
+/*!
+ 输入工具栏的点击回调监听
+ */
+@property(weak, nonatomic) id<KSChatInputViewDelegate> delegate;
+
+/*!
+ 容器View
+ */
+@property(strong, nonatomic) UIView *inputContainerView;
+
+/**
+ 文本输入框
+ */
+@property(strong, nonatomic) UITextView *inputTextView;
+
+/**
+ 表情的按钮
+ */
+@property(strong, nonatomic) UIButton *emojiButton;
+
+/**
+ 清空内容
+ */
+- (void)clearInputText;
+
+- (id)initWithStatus:(KSBottomBarStatus)status;
+
+@end
+
+/**
+ 输入框的点击监听器
+ */
+@protocol KSChatInputViewDelegate <NSObject>
+
+@optional
+
+/**
+ 键盘即将显示的回调
+ 
+ @param keyboardFrame 键盘最终需要显示的Frame
+ */
+- (void)keyboardWillShowWithFrame:(CGRect)keyboardFrame;
+
+/**
+ 键盘即将隐藏的回调
+ */
+- (void)keyboardWillHide;
+
+/**
+ 点击键盘Return按钮的回调
+ 
+ @param inputControl 当前输入工具栏
+ @param text         当前输入框中国的文本内容
+ */
+- (void)didTouchKeyboardReturnKey:(KSChatInputView *)inputControl text:(NSString *)text;
+
+/**
+ 点击表情按钮的回调
+ 
+ @param sender 表情按钮
+ */
+- (void)didTouchEmojiButton:(UIButton *)sender;
+
+
+/**
+ 输入框中内容发生变化的回调
+ 
+ @param inputTextView 文本输入框
+ @param range         当前操作的范围
+ @param text          插入的文本
+ */
+- (void)inputTextView:(UITextView *)inputTextView
+shouldChangeTextInRange:(NSRange)range
+      replacementText:(NSString *)text;
+- (void)inputTextViewTextViewDidChange:(UITextView *)textView;
+
+@end
+NS_ASSUME_NONNULL_END

+ 193 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/InputBar/KSChatInputView.m

@@ -0,0 +1,193 @@
+//
+//  KSChatInputView.m
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/20.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "KSChatInputView.h"
+
+@interface KSChatInputView () <UITextViewDelegate>
+
+@end
+
+@implementation KSChatInputView
+
+//  初始化
+- (id)initWithStatus:(KSBottomBarStatus)status {
+    self = [super init];
+    if (self) {
+        [self setBackgroundColor:[UIColor clearColor]];
+        [self initializedSubViews];
+        [self registerNotification];
+    }
+    return self;
+}
+
+- (void)setFrame:(CGRect)frame {
+    [super setFrame:frame];
+    [_inputContainerView setFrame:self.bounds];
+    [_inputTextView setFrame:CGRectMake(10, 7, self.bounds.size.width - 60, 36)];
+    [_emojiButton setFrame:CGRectMake(self.bounds.size.width - 40, 10, 30, 31)];
+}
+
+#pragma mark <UITextViewDelegate>
+-(void)textViewDidChange:(UITextView *)textView{
+    if (self.delegate && [self.delegate respondsToSelector:@selector(inputTextViewTextViewDidChange:)]) {
+        [self.delegate inputTextViewTextViewDidChange:textView];
+    }
+}
+- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
+    if ([self.delegate respondsToSelector:@selector(inputTextView:shouldChangeTextInRange:replacementText:)]) {
+        [self.delegate inputTextView:textView shouldChangeTextInRange:range replacementText:text];
+    }
+    if ([text isEqualToString:@"\n"]) {
+        if ([self.delegate respondsToSelector:@selector(didTouchKeyboardReturnKey:text:)]) {
+            NSString *_needToSendText = textView.text;
+            NSString *_formatString =
+            [_needToSendText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
+            if (0 == [_formatString length]) {
+                
+            } else {
+                //  发送点击事件
+                [self.delegate didTouchKeyboardReturnKey:self text:[_needToSendText copy]];
+            }
+        }
+        return NO;
+    }
+    return YES;
+}
+
+- (void)didTouchEmojiDown:(UIButton *)sender {
+    [_emojiButton setSelected:!sender.selected];
+    [self.delegate didTouchEmojiButton:sender];
+}
+
+- (void)inputBarDidReceiveKeyboardWillShowNotification:(NSNotification *)notification {
+    NSDictionary *userInfo = [notification userInfo];
+    CGRect keyboardBeginFrame = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
+    CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
+    
+    if (!CGRectEqualToRect(keyboardBeginFrame, keyboardEndFrame)) {
+        UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
+        NSInteger animationCurveOption = (animationCurve << 16);
+        
+        double animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
+        [UIView animateWithDuration:animationDuration
+                              delay:0.0
+                            options:animationCurveOption
+                         animations:^{
+                             if ([self.delegate respondsToSelector:@selector(keyboardWillShowWithFrame:)]) {
+                                 [self.delegate keyboardWillShowWithFrame:keyboardEndFrame];
+                             }
+                         }
+                         completion:^(BOOL finished) {
+                             
+                         }];
+    }
+}
+
+- (void)inputBarDidReceiveKeyboardWillHideNotification:(NSNotification *)notification {
+    NSDictionary *userInfo = [notification userInfo];
+    CGRect keyboardBeginFrame = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
+    CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
+    
+    if (!CGRectEqualToRect(keyboardBeginFrame, keyboardEndFrame)) {
+        UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
+        NSInteger animationCurveOption = (animationCurve << 16);
+        
+        double animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
+        [UIView animateWithDuration:animationDuration
+                              delay:0.0
+                            options:animationCurveOption
+                         animations:^{
+                             if (!CGRectEqualToRect(keyboardBeginFrame, keyboardEndFrame)) {
+                                 if ([self.delegate respondsToSelector:@selector(keyboardWillHide)]) {
+                                     [self.delegate keyboardWillHide];
+                                 }
+                             }
+                         }
+                         completion:^(BOOL finished) {
+                             
+                         }];
+    }
+}
+
+- (void)clearInputText {
+    dispatch_async(dispatch_get_main_queue(), ^{
+       [self.inputTextView setText:@""];
+    });
+    
+}
+
+- (void)initializedSubViews {
+    [self addSubview:self.inputContainerView];
+    [_inputContainerView addSubview:self.inputTextView];
+    [_inputContainerView addSubview:self.emojiButton];
+}
+
+- (void)registerNotification {
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(inputBarDidReceiveKeyboardWillShowNotification:)
+                                                 name:UIKeyboardWillShowNotification
+                                               object:nil];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(inputBarDidReceiveKeyboardWillHideNotification:)
+                                                 name:UIKeyboardWillHideNotification
+                                               object:nil];
+}
+
+#pragma mark - UI
+
+- (UIView *)inputContainerView {
+    if (!_inputContainerView) {
+        _inputContainerView = [[UIView alloc] init];
+        [_inputContainerView setBackgroundColor:[UIColor clearColor]];
+    }
+    return _inputContainerView;
+}
+
+- (UITextView *)inputTextView {
+    if (!_inputTextView) {
+        _inputTextView = [[UITextView alloc] init];
+        [_inputTextView setTextColor:[UIColor blackColor]];
+        [_inputTextView setFont:[UIFont systemFontOfSize:16]];
+        [_inputTextView setReturnKeyType:UIReturnKeySend];
+        [_inputTextView setBackgroundColor:[UIColor colorWithRed:248 / 255.f green:248 / 255.f blue:248 / 255.f alpha:1]];
+        [_inputTextView setEnablesReturnKeyAutomatically:YES];  //内容为空,返回按钮不可点击
+        [_inputTextView.layer setCornerRadius:4];
+        [_inputTextView.layer setMasksToBounds:YES];
+        [_inputTextView.layer setBorderWidth:0.3f];
+        [_inputTextView.layer setBorderColor:[UIColor grayColor].CGColor];
+        [_inputTextView.layoutManager setAllowsNonContiguousLayout:YES];    //默认从顶部开始显示
+        [_inputTextView setDelegate:self];
+//        [_inputTextView setAccessibilityLabel:@"chat_input_textView"];
+    }
+    return _inputTextView;
+}
+
+- (UIButton *)emojiButton {
+    if (!_emojiButton) {
+        _emojiButton = [[UIButton alloc] init];
+        [_emojiButton setImage:[UIImage imageNamed:@"emoji"] forState:UIControlStateNormal];
+        [_emojiButton setImage:[UIImage imageNamed:@"keyboard"] forState:UIControlStateSelected];
+        [_emojiButton setExclusiveTouch:YES];
+        [_emojiButton addTarget:self action:@selector(didTouchEmojiDown:) forControlEvents:UIControlEventTouchUpInside];
+    }
+    return _emojiButton;
+}
+
+- (void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 16 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/KSBeautySettingView.h

@@ -0,0 +1,16 @@
+//
+//  KSBeautySettingView.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSBeautySettingView : UIView
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 20 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/KSBeautySettingView.m

@@ -0,0 +1,20 @@
+//
+//  KSBeautySettingView.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSBeautySettingView.h"
+
+@implementation KSBeautySettingView
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/KSBeautySettingView.xib

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB">
+            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+            <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
+        </view>
+    </objects>
+</document>

+ 36 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/KSChatroomTextCell.h

@@ -0,0 +1,36 @@
+//
+//  KSChatroomTextCell.h
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/23.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "KSRCMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSChatroomTextCell : UITableViewCell
+
+/**
+ 消息Cell的数据模型
+ */
+@property(strong, nonatomic) KSRCMessageModel *model;
+
+/*!
+ 显示消息内容的Label
+ */
+@property (nonatomic, strong) UILabel *contentLabel;
+
+@property (nonatomic, strong) UIView *containerView;
+
+/**
+ 设置当前消息Cell的数据模型
+ 
+ @param model 消息Cell的数据模型
+ */
+- (void)setDataModel:(KSRCMessageModel *)model createrId:(NSString *)createrId;
+@end
+
+NS_ASSUME_NONNULL_END

+ 302 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/KSChatroomTextCell.m

@@ -0,0 +1,302 @@
+//
+//  KSChatroomTextCell.m
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/23.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "KSChatroomTextCell.h"
+#import <RongIMLib/RongIMLib.h>
+#import "RCChatroomMessageCenter.h"
+
+@interface KSChatroomTextCell ()
+
+@property (nonatomic, strong) CAShapeLayer *bubbleLayer;
+
+@property (nonatomic, strong) NSString *creatorId;
+
+@end
+
+@implementation KSChatroomTextCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    
+}
+
+- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
+    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
+    if (self) {
+        self.selectionStyle = UITableViewCellSelectionStyleNone;
+        self.backgroundColor = [UIColor clearColor];
+        self.contentView.backgroundColor = [UIColor clearColor];
+        [self initializedSubViews];
+    }
+    return self;
+}
+
+- (void)initializedSubViews {
+    [self.contentView addSubview:self.containerView];
+    [self.containerView.layer addSublayer:self.bubbleLayer];
+    [self.containerView addSubview:self.contentLabel];
+    [self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(self.contentView.mas_left).offset(8);
+        make.right.lessThanOrEqualTo(self.contentView.mas_right).offset(-8);
+        make.top.mas_equalTo(self.contentView.mas_top).offset(3);
+        make.bottom.mas_equalTo(self.contentView.mas_bottom).offset(-3);
+    }];
+    
+    [self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(self.containerView.mas_left).offset(8);
+        make.right.mas_equalTo(self.containerView.mas_right).offset(-8);
+        make.top.mas_equalTo(self.containerView.mas_top).offset(5);
+        make.bottom.mas_equalTo(self.containerView.mas_bottom).offset(-5);
+    }];
+}
+
+- (void)setDataModel:(KSRCMessageModel *)model createrId:(NSString *)createrId {
+    self.model = model;
+    self.creatorId = createrId;
+    [self updateUI:model];
+}
+
+- (void)updateUI:(KSRCMessageModel *)model {
+    BOOL isCreator = NO;
+    NSString *creatorImg = @"chatroom_speaker";
+    NSString *headString = @"";
+    if ([model.senderUserId isEqualToString:self.creatorId]) {
+        isCreator = YES;
+        headString = @" ";
+    }
+    
+    if ([model.content isMemberOfClass:[RCChatroomWelcome class]]) {
+        RCUserInfo *userInfo = model.userInfo;
+        NSString *userName = [userInfo.name stringByAppendingString:@""];
+        NSString *localizedMessage = @"进入直播间";
+        NSString *str =[NSString stringWithFormat:@"%@%@%@",headString,userName,localizedMessage];
+        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0x00d6c9)) range:[str rangeOfString:userName]];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0xffffff)) range:[str rangeOfString:localizedMessage]];
+        if (isCreator) {
+            [self addAttachmentImg:attributedString imgName:creatorImg];
+        }
+        [self.contentLabel setAttributedText:attributedString.copy];
+        return;
+    }
+    else if ([model.content isMemberOfClass:[RCChatroomSeatsControl class]]) { // 连麦控制消息
+        RCChatroomSeatsControl *seatControlMessage = (RCChatroomSeatsControl *)model.content;
+        NSString *userName = [seatControlMessage.userName stringByAppendingString:@""];
+        
+        NSString *localizedMessage = seatControlMessage.seatBan ? @"关闭连麦" : @"开启连麦";
+        NSString *str =[NSString stringWithFormat:@"%@%@%@",headString,userName,localizedMessage];
+        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0x00d6c9)) range:[str rangeOfString:userName]];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0xffffff)) range:[str rangeOfString:localizedMessage]];
+        if (isCreator) {
+            [self addAttachmentImg:attributedString imgName:creatorImg];
+        }
+        [self.contentLabel setAttributedText:attributedString.copy];
+    }
+    else if ([model.content isMemberOfClass:[RCChatroomChatBan class]]) { // 禁言消息
+        RCChatroomChatBan *chatBanMsg = (RCChatroomChatBan *)model.content;
+        NSString *userName = [chatBanMsg.userName stringByAppendingString:@""];
+        
+        NSString *localizedMessage = chatBanMsg.chatBan ? @"关闭聊天" : @"开启聊天";
+        NSString *str =[NSString stringWithFormat:@"%@%@%@",headString,userName,localizedMessage];
+        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0x00d6c9)) range:[str rangeOfString:userName]];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0xffffff)) range:[str rangeOfString:localizedMessage]];
+        if (isCreator) {
+            [self addAttachmentImg:attributedString imgName:creatorImg];
+        }
+        [self.contentLabel setAttributedText:attributedString.copy];
+    }
+    else if ([model.content isMemberOfClass:[RCChatroomSeatApply class]]) {
+        RCChatroomSeatApply *seatApply = (RCChatroomSeatApply *)model.content;
+        NSString *userName = @"";
+        NSString *localizedMessage = @"";
+        if (seatApply.type == SEATHANDLE_INVITE) {
+            userName = seatApply.teacherName;
+            localizedMessage = @"发起了连麦邀请";
+        }
+        else if (seatApply.type == SEATHANDLE_DISINVITE) {
+            userName = seatApply.teacherName;
+            localizedMessage = @"取消了连麦邀请";
+        }
+        else if (seatApply.type == SEATHANDLE_KICKSEAT) {
+            userName = seatApply.teacherName;
+            localizedMessage = @"将你报下麦";
+        }
+        else if (seatApply.type == SEATHANDLE_APPLY) {
+            userName = seatApply.audienceName;
+            localizedMessage = @"发起了连麦申请";
+        }
+        else if (seatApply.type == SEATHANDLE_CANCELAPPLY) {
+            userName = seatApply.audienceName;
+            localizedMessage = @"取消了连麦申请";
+        }
+        
+        NSString *str =[NSString stringWithFormat:@"%@%@%@",headString,userName,localizedMessage];
+        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0x00d6c9)) range:[str rangeOfString:userName]];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0xffffff)) range:[str rangeOfString:localizedMessage]];
+        if (isCreator) {
+            [self addAttachmentImg:attributedString imgName:creatorImg];
+        }
+        [self.contentLabel setAttributedText:attributedString.copy];
+    }
+    else if ([model.content isMemberOfClass:[RCChatroomSeatResponse class]]) {
+        RCChatroomSeatResponse *seatResponse = (RCChatroomSeatResponse *)model.content;
+        NSString *userName = @"";
+        NSString *localizedMessage = @"";
+        if (seatResponse.type == SEATRESPONSE_TEACHERAPPROVE) {
+            userName = seatResponse.teacherName;
+            localizedMessage = @"同意了连麦申请";
+        }
+        else if (seatResponse.type == SEATRESPONSE_TEACHERREJECT) {
+            userName = seatResponse.teacherName;
+            localizedMessage = @"拒绝了连麦申请";
+        }
+        else if (seatResponse.type == SEATRESPONSE_AUDIENCEAPPROVE) {
+            userName = seatResponse.audienceName;
+            localizedMessage = @"同意了连麦邀请";
+        }
+        else if (seatResponse.type == SEATRESPONSE_AUDIENCEREJECT) {
+            userName = seatResponse.audienceName;
+            localizedMessage = @"拒绝了连麦邀请";
+        }
+        NSString *str =[NSString stringWithFormat:@"%@%@%@",headString,userName,localizedMessage];
+        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0x00d6c9)) range:[str rangeOfString:userName]];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0xffffff)) range:[str rangeOfString:localizedMessage]];
+        if (isCreator) {
+            [self addAttachmentImg:attributedString imgName:creatorImg];
+        }
+        [self.contentLabel setAttributedText:attributedString.copy];
+    }
+    
+    else if ([model.content isMemberOfClass:[RCChatroomFollow class]]) {
+        RCUserInfo *userInfo = model.userInfo;
+        NSString *userName = [userInfo.name stringByAppendingString:@":"];
+        NSString *localizedMessage = @"关注了主讲人";
+        NSString *str =[NSString stringWithFormat:@"%@%@",userName,localizedMessage];
+        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0x00d6c9)) range:[str rangeOfString:userName]];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0xffffff)) range:[str rangeOfString:localizedMessage]];
+        [self.contentLabel setAttributedText:attributedString.copy];
+        return;
+    }
+    else if ([model.content isMemberOfClass:[RCChatroomLike class]]) {
+        RCChatroomLike *likeMessage = (RCChatroomLike *)model.content;
+        RCUserInfo *userInfo = model.userInfo;
+        NSString *userName = [userInfo.name stringByAppendingString:@""];
+        NSString *localizedMessage = [NSString stringWithFormat:@"给主讲人点了%d个赞",likeMessage.counts];
+        NSString *str =[NSString stringWithFormat:@"%@%@",userName,localizedMessage];
+        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
+        
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0x00d6c9)) range:[str rangeOfString:userName]];
+        [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0xffffff)) range:[str rangeOfString:localizedMessage]];
+        [self.contentLabel setAttributedText:attributedString.copy];
+        return;
+    }
+    else if ([model.content isMemberOfClass:[RCTextMessage class]]) {
+        
+        RCTextMessage *textMessage = (RCTextMessage *)self.model.content;
+        if ([textMessage.extra isEqualToString:@"statement"]) {
+            NSString *str = textMessage.content;
+            NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
+            [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0x00d6c9)) range:NSMakeRange(0, str.length)];
+            [self.contentLabel setAttributedText:attributedString.copy];
+        }
+        else if (self.model.senderUserId) {
+            NSString *localizedMessage = textMessage.content;
+            RCUserInfo *userInfo = model.userInfo;
+            NSString *userName = [userInfo.name stringByAppendingString:@":"];
+            NSString *str =[NSString stringWithFormat:@"%@%@%@",headString,userName,localizedMessage];
+            NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
+            [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0x00d6c9)) range:[str rangeOfString:userName]];
+            [attributedString addAttribute:NSForegroundColorAttributeName value:(HexRGB(0xffffff)) range:[str rangeOfString:localizedMessage]];
+            if (isCreator) {
+                [self addAttachmentImg:attributedString imgName:creatorImg];
+            }
+            [self.contentLabel setAttributedText:attributedString.copy];
+            
+        }
+    }
+    else {
+        NSLog(@"----");
+    }
+}
+
+- (void)addAttachmentImg:(NSMutableAttributedString *)attrStr imgName:(NSString *)imgName {
+    NSTextAttachment *typeAttachment = [[NSTextAttachment alloc] init];
+    typeAttachment.bounds = CGRectMake(0, -3, 38, 15);
+    typeAttachment.image = [UIImage imageNamed:imgName];
+    NSAttributedString *typeAttr = [NSAttributedString attributedStringWithAttachment:typeAttachment];
+    [attrStr insertAttributedString:typeAttr atIndex:0];
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    dispatch_async(dispatch_get_main_queue(), ^{
+        [self updateLayer:self.bubbleLayer withFrame:self.containerView.bounds corner:10.0f];
+    });
+}
+
+- (void)updateLayer:(CAShapeLayer *)layer withFrame:(CGRect)frame corner:(CGFloat)corner {
+    layer.frame = frame;
+    UIBezierPath *cornerPath = [UIBezierPath bezierPathWithRoundedRect:layer.bounds cornerRadius:corner];
+    layer.path = cornerPath.CGPath;
+}
+
+- (UIView *)containerView {
+    if (_containerView == nil) {
+        _containerView = [[UIView alloc] init];
+        _containerView.backgroundColor = [UIColor clearColor];
+    }
+    return _containerView;
+}
+
+- (CAShapeLayer *)bubbleLayer {
+    if (_bubbleLayer == nil) {
+        _bubbleLayer = [CAShapeLayer layer];
+        _bubbleLayer.fillColor = HexRGBAlpha(0x000000, 0.32).CGColor;
+    }
+    return _bubbleLayer;
+}
+
+- (UILabel *)contentLabel {
+    if (!_contentLabel) {
+        _contentLabel = [[UILabel alloc] init];
+        [_contentLabel setTextAlignment: NSTextAlignmentLeft];
+        _contentLabel.font = [UIFont systemFontOfSize:13.0f weight:UIFontWeightMedium];
+        [_contentLabel setTintColor:[UIColor whiteColor]];
+        [_contentLabel setNumberOfLines:0];
+    }
+    return _contentLabel;
+}
+
+
+- (NSString *)timeWithTimeInterval:(long)timeInterval {
+    // 格式化时间
+    NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
+    formatter.timeZone = [NSTimeZone timeZoneWithName:@"shanghai"];
+    [formatter setDateStyle:NSDateFormatterMediumStyle];
+    [formatter setTimeStyle:NSDateFormatterShortStyle];
+    [formatter setDateFormat:@"yyyy年MM月dd日 HH:mm"];
+    
+    // 毫秒值转化为秒
+    NSDate* date = [NSDate dateWithTimeIntervalSince1970:timeInterval/ 1000.0];
+    NSString* dateString = [formatter stringFromDate:date];
+    return dateString;
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end

+ 30 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LivePreviewBodyView.h

@@ -0,0 +1,30 @@
+//
+//  LivePreviewBodyView.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <UIKit/UIKit.h>
+typedef NS_ENUM(NSInteger, PREVIEWLIVEACTION) {
+    PREVIEWLIVEACTION_BACK, // 返回
+    PREVIEWLIVEACTION_SWITCH, // 翻转
+    PREVIEWLIVEACTION_BEAUTY, // 美颜
+    PREVIEWLIVEACTION_SHARE,  // 分享
+    PREVIEWLIVEACTION_OPEN,   // 开播
+};
+typedef void(^PreviewCallback)(PREVIEWLIVEACTION action);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LivePreviewBodyView : UIView
+
+@property (weak, nonatomic) IBOutlet UIView *videoView;
+
++ (instancetype)shareInstance;
+
+- (void)previewOperationCallback:(PreviewCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 70 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LivePreviewBodyView.m

@@ -0,0 +1,70 @@
+//
+//  LivePreviewBodyView.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "LivePreviewBodyView.h"
+
+@interface LivePreviewBodyView ()
+
+@property (nonatomic, copy) PreviewCallback callback;
+
+@end
+
+
+@implementation LivePreviewBodyView
+
++ (instancetype)shareInstance {
+    LivePreviewBodyView *view = [[[NSBundle mainBundle] loadNibNamed:@"LivePreviewBodyView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)previewOperationCallback:(PreviewCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)backAction:(id)sender {
+    if (self.callback) {
+        self.callback(PREVIEWLIVEACTION_BACK);
+    }
+}
+
+- (IBAction)switchAction:(id)sender {
+    if (self.callback) {
+        self.callback(PREVIEWLIVEACTION_SWITCH);
+    }
+}
+
+- (IBAction)beautyAction:(id)sender {
+    if (self.callback) {
+        self.callback(PREVIEWLIVEACTION_BEAUTY);
+    }
+}
+
+
+- (IBAction)shareAction:(id)sender {
+    if (self.callback) {
+        self.callback(PREVIEWLIVEACTION_SHARE);
+    }
+}
+
+
+- (IBAction)openLive:(id)sender {
+    if (self.callback) {
+        self.callback(PREVIEWLIVEACTION_OPEN);
+    }
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 236 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LivePreviewBodyView.xib

@@ -0,0 +1,236 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="LivePreviewBodyView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="917"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kfm-aC-UJ6">
+                    <rect key="frame" x="0.0" y="0.0" width="414" height="917"/>
+                    <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                </view>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="livePreview_close" translatesAutoresizingMaskIntoConstraints="NO" id="YaR-eI-9ID">
+                    <rect key="frame" x="19" y="65" width="18" height="18"/>
+                </imageView>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XeW-qC-lAf">
+                    <rect key="frame" x="81.5" y="608.5" width="251" height="76"/>
+                    <subviews>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="utK-Cw-EDV">
+                            <rect key="frame" x="0.0" y="0.0" width="83.5" height="76"/>
+                            <subviews>
+                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="live_switch" translatesAutoresizingMaskIntoConstraints="NO" id="lKf-On-Nhz">
+                                    <rect key="frame" x="24.5" y="10" width="35" height="35"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="35" id="ilG-Eb-HZf"/>
+                                        <constraint firstAttribute="height" constant="35" id="rjF-Db-eZM"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="翻转" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6dP-na-Q0G">
+                                    <rect key="frame" x="30.5" y="48" width="23" height="16"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="16" id="mrk-u6-hK9"/>
+                                    </constraints>
+                                    <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Q0-gr-Dbs">
+                                    <rect key="frame" x="0.0" y="0.0" width="83.5" height="76"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="switchAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="luH-9V-uMZ"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstItem="lKf-On-Nhz" firstAttribute="top" secondItem="utK-Cw-EDV" secondAttribute="top" constant="10" id="9Ds-fi-7dW"/>
+                                <constraint firstItem="lKf-On-Nhz" firstAttribute="centerX" secondItem="utK-Cw-EDV" secondAttribute="centerX" id="Nxm-Wq-RpT"/>
+                                <constraint firstItem="3Q0-gr-Dbs" firstAttribute="leading" secondItem="utK-Cw-EDV" secondAttribute="leading" id="RIN-zF-dsr"/>
+                                <constraint firstItem="3Q0-gr-Dbs" firstAttribute="top" secondItem="utK-Cw-EDV" secondAttribute="top" id="TfT-0N-rft"/>
+                                <constraint firstItem="6dP-na-Q0G" firstAttribute="centerX" secondItem="lKf-On-Nhz" secondAttribute="centerX" id="b1i-4O-14L"/>
+                                <constraint firstAttribute="bottom" secondItem="3Q0-gr-Dbs" secondAttribute="bottom" id="cmV-D3-Eae"/>
+                                <constraint firstItem="6dP-na-Q0G" firstAttribute="top" secondItem="lKf-On-Nhz" secondAttribute="bottom" constant="3" id="cn2-l4-FMs"/>
+                                <constraint firstAttribute="trailing" secondItem="3Q0-gr-Dbs" secondAttribute="trailing" id="vOd-6V-d8M"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vhH-ad-pgs">
+                            <rect key="frame" x="83.5" y="0.0" width="84" height="76"/>
+                            <subviews>
+                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="livePrew_beauty" translatesAutoresizingMaskIntoConstraints="NO" id="4dd-Kh-Kmk">
+                                    <rect key="frame" x="24.5" y="10" width="35" height="35"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="35" id="Khe-GL-mWs"/>
+                                        <constraint firstAttribute="height" constant="35" id="qhs-hu-n1W"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="美颜" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="j4U-EV-Gh0">
+                                    <rect key="frame" x="30.5" y="48" width="23" height="16"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="16" id="bTP-CQ-5pM"/>
+                                    </constraints>
+                                    <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TJq-DR-AeU">
+                                    <rect key="frame" x="0.0" y="0.0" width="84" height="76"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="beautyAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="Hlz-7Z-w4w"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstItem="4dd-Kh-Kmk" firstAttribute="top" secondItem="vhH-ad-pgs" secondAttribute="top" constant="10" id="443-BX-uep"/>
+                                <constraint firstItem="4dd-Kh-Kmk" firstAttribute="centerX" secondItem="vhH-ad-pgs" secondAttribute="centerX" id="IEg-Yo-jVy"/>
+                                <constraint firstAttribute="bottom" secondItem="TJq-DR-AeU" secondAttribute="bottom" id="Jfb-mv-imx"/>
+                                <constraint firstItem="j4U-EV-Gh0" firstAttribute="centerX" secondItem="4dd-Kh-Kmk" secondAttribute="centerX" id="Twf-JO-ynW"/>
+                                <constraint firstItem="j4U-EV-Gh0" firstAttribute="top" secondItem="4dd-Kh-Kmk" secondAttribute="bottom" constant="3" id="VPq-i3-dPS"/>
+                                <constraint firstAttribute="trailing" secondItem="TJq-DR-AeU" secondAttribute="trailing" id="WbV-II-nTh"/>
+                                <constraint firstItem="TJq-DR-AeU" firstAttribute="top" secondItem="vhH-ad-pgs" secondAttribute="top" id="dsb-mk-oTi"/>
+                                <constraint firstItem="TJq-DR-AeU" firstAttribute="leading" secondItem="vhH-ad-pgs" secondAttribute="leading" id="fNS-Pp-8Lu"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jAT-dj-aq8">
+                            <rect key="frame" x="167.5" y="0.0" width="83.5" height="76"/>
+                            <subviews>
+                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="live_share" translatesAutoresizingMaskIntoConstraints="NO" id="nc9-4x-kHq">
+                                    <rect key="frame" x="24" y="10" width="35" height="35"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="35" id="8nt-P7-avU"/>
+                                        <constraint firstAttribute="width" constant="35" id="uSC-nv-5GY"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="分享" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Bpv-QR-PtI">
+                                    <rect key="frame" x="30" y="48" width="23" height="16"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="16" id="grB-Ze-frq"/>
+                                    </constraints>
+                                    <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cjc-mH-jHh">
+                                    <rect key="frame" x="0.0" y="0.0" width="83.5" height="76"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="shareAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="SF3-Tf-k7q"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstItem="cjc-mH-jHh" firstAttribute="top" secondItem="jAT-dj-aq8" secondAttribute="top" id="EMK-G4-h14"/>
+                                <constraint firstAttribute="trailing" secondItem="cjc-mH-jHh" secondAttribute="trailing" id="IoO-ZQ-KwS"/>
+                                <constraint firstItem="cjc-mH-jHh" firstAttribute="leading" secondItem="jAT-dj-aq8" secondAttribute="leading" id="Tfa-3f-GPw"/>
+                                <constraint firstItem="Bpv-QR-PtI" firstAttribute="top" secondItem="nc9-4x-kHq" secondAttribute="bottom" constant="3" id="ZAF-dn-94b"/>
+                                <constraint firstItem="nc9-4x-kHq" firstAttribute="top" secondItem="jAT-dj-aq8" secondAttribute="top" constant="10" id="lrL-5L-xOv"/>
+                                <constraint firstAttribute="bottom" secondItem="cjc-mH-jHh" secondAttribute="bottom" id="qFE-d2-s45"/>
+                                <constraint firstItem="nc9-4x-kHq" firstAttribute="centerX" secondItem="jAT-dj-aq8" secondAttribute="centerX" id="xJp-7k-uXH"/>
+                                <constraint firstItem="Bpv-QR-PtI" firstAttribute="centerX" secondItem="nc9-4x-kHq" secondAttribute="centerX" id="y4D-wj-3Kx"/>
+                            </constraints>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="0.25" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstItem="jAT-dj-aq8" firstAttribute="width" secondItem="utK-Cw-EDV" secondAttribute="width" id="0aS-HW-sVk"/>
+                        <constraint firstAttribute="bottom" secondItem="vhH-ad-pgs" secondAttribute="bottom" id="5VH-L7-Ddf"/>
+                        <constraint firstItem="vhH-ad-pgs" firstAttribute="leading" secondItem="utK-Cw-EDV" secondAttribute="trailing" id="LAZ-t9-jV1"/>
+                        <constraint firstItem="vhH-ad-pgs" firstAttribute="width" secondItem="utK-Cw-EDV" secondAttribute="width" id="UZ5-vx-Rdn"/>
+                        <constraint firstAttribute="width" constant="251" id="Ubg-yr-iPK"/>
+                        <constraint firstItem="jAT-dj-aq8" firstAttribute="top" secondItem="XeW-qC-lAf" secondAttribute="top" id="gsa-Ij-iNg"/>
+                        <constraint firstItem="vhH-ad-pgs" firstAttribute="top" secondItem="XeW-qC-lAf" secondAttribute="top" id="izP-7H-KLr"/>
+                        <constraint firstAttribute="bottom" secondItem="utK-Cw-EDV" secondAttribute="bottom" id="j2i-p7-8nf"/>
+                        <constraint firstItem="utK-Cw-EDV" firstAttribute="leading" secondItem="XeW-qC-lAf" secondAttribute="leading" id="kbp-n5-G0A"/>
+                        <constraint firstItem="jAT-dj-aq8" firstAttribute="leading" secondItem="vhH-ad-pgs" secondAttribute="trailing" id="l4J-RU-UfG"/>
+                        <constraint firstAttribute="trailing" secondItem="jAT-dj-aq8" secondAttribute="trailing" id="p6Y-cm-oFt"/>
+                        <constraint firstItem="utK-Cw-EDV" firstAttribute="top" secondItem="XeW-qC-lAf" secondAttribute="top" id="rTd-JI-zwO"/>
+                        <constraint firstAttribute="height" constant="76" id="sty-yK-rcr"/>
+                        <constraint firstAttribute="bottom" secondItem="jAT-dj-aq8" secondAttribute="bottom" id="wlL-vf-TFQ"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="16"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5iE-d1-dDu">
+                    <rect key="frame" x="76" y="732.5" width="262" height="48"/>
+                    <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="48" id="YZo-l7-ee9"/>
+                    </constraints>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" title="开启视频直播"/>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="24"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                    <connections>
+                        <action selector="openLive:" destination="iN0-l3-epB" eventType="touchUpInside" id="X3p-5d-krv"/>
+                    </connections>
+                </button>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="关闭" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mK5-gh-2k9">
+                    <rect key="frame" x="42" y="65.5" width="29" height="17"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WPP-dz-byk">
+                    <rect key="frame" x="19" y="52" width="52" height="44"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="44" id="6h9-nI-aHz"/>
+                    </constraints>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <connections>
+                        <action selector="backAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="xuA-4R-7D6"/>
+                    </connections>
+                </button>
+            </subviews>
+            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+            <constraints>
+                <constraint firstItem="5iE-d1-dDu" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="76" id="0BM-aX-teB"/>
+                <constraint firstItem="mK5-gh-2k9" firstAttribute="leading" secondItem="YaR-eI-9ID" secondAttribute="trailing" constant="5" id="0Qn-9N-cX7"/>
+                <constraint firstItem="5iE-d1-dDu" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="6hT-QH-nMS"/>
+                <constraint firstAttribute="bottom" secondItem="kfm-aC-UJ6" secondAttribute="bottom" id="7Nj-1P-3Db"/>
+                <constraint firstItem="XeW-qC-lAf" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="centerY" constant="150" id="8KA-3y-6hP"/>
+                <constraint firstAttribute="trailing" secondItem="5iE-d1-dDu" secondAttribute="trailing" constant="76" id="9It-qv-zSA"/>
+                <constraint firstItem="XeW-qC-lAf" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="CNw-tL-PrC"/>
+                <constraint firstAttribute="trailing" secondItem="kfm-aC-UJ6" secondAttribute="trailing" id="CwN-02-0IV"/>
+                <constraint firstItem="YaR-eI-9ID" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="65" id="EKk-aC-GLF"/>
+                <constraint firstItem="mK5-gh-2k9" firstAttribute="centerY" secondItem="WPP-dz-byk" secondAttribute="centerY" id="Lr2-fW-E1n"/>
+                <constraint firstItem="YaR-eI-9ID" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="19" id="U45-pT-bqn"/>
+                <constraint firstItem="mK5-gh-2k9" firstAttribute="trailing" secondItem="WPP-dz-byk" secondAttribute="trailing" id="VZS-rD-hex"/>
+                <constraint firstItem="kfm-aC-UJ6" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="YIO-zg-fbO"/>
+                <constraint firstItem="mK5-gh-2k9" firstAttribute="centerY" secondItem="YaR-eI-9ID" secondAttribute="centerY" id="gzj-Jq-Pkw"/>
+                <constraint firstItem="5iE-d1-dDu" firstAttribute="top" secondItem="XeW-qC-lAf" secondAttribute="bottom" constant="48" id="iUr-iC-CiR"/>
+                <constraint firstItem="kfm-aC-UJ6" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="n4X-0E-r5B"/>
+                <constraint firstItem="YaR-eI-9ID" firstAttribute="leading" secondItem="WPP-dz-byk" secondAttribute="leading" id="wfl-r8-cKI"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="videoView" destination="kfm-aC-UJ6" id="git-Rx-Zzs"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="56.584821428571423"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="livePreview_close" width="18" height="18"/>
+        <image name="livePrew_beauty" width="35" height="35"/>
+        <image name="live_share" width="35" height="35"/>
+        <image name="live_switch" width="35" height="35"/>
+    </resources>
+</document>

+ 16 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.h

@@ -0,0 +1,16 @@
+//
+//  LiveRoomBottomView.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveRoomBottomView : UIView
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 20 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.m

@@ -0,0 +1,20 @@
+//
+//  LiveRoomBottomView.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "LiveRoomBottomView.h"
+
+@implementation LiveRoomBottomView
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.xib

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="93"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="131.8840579710145" y="-10.379464285714285"/>
+        </view>
+    </objects>
+</document>

+ 16 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomHeadView.h

@@ -0,0 +1,16 @@
+//
+//  LiveRoomHeadView.h
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveRoomHeadView : UIView
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 20 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomHeadView.m

@@ -0,0 +1,20 @@
+//
+//  LiveRoomHeadView.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "LiveRoomHeadView.h"
+
+@implementation LiveRoomHeadView
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomHeadView.xib

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB">
+            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+            <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
+        </view>
+    </objects>
+</document>

+ 21 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomLikeLayer.h

@@ -0,0 +1,21 @@
+//
+//  LiveRoomLikeLayer.h
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/24.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <QuartzCore/QuartzCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveRoomLikeLayer : CALayer
+
+- (instancetype)initWithName:(NSString *)name;
+
+- (void)startAnimation;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 69 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomLikeLayer.m

@@ -0,0 +1,69 @@
+//
+//  LiveRoomLikeLayer.m
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/24.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "LiveRoomLikeLayer.h"
+
+@interface LiveRoomLikeLayer ()<CAAnimationDelegate>
+
+
+@end
+
+@implementation LiveRoomLikeLayer
+
+
+- (instancetype)initWithName:(NSString *)name {
+    self = [super init];
+    if (self) {
+        [self setIcon];
+    }
+    return self;
+}
+
+- (void)setIcon {
+    NSString *imgName = [NSString stringWithFormat:@"like_gift_%d",arc4random() % 8 +1];
+    UIImage *likeImage = [UIImage imageNamed:imgName];
+    if (likeImage) {
+        self.contents = (__bridge id _Nullable)(likeImage.CGImage);
+    }
+}
+- (void)startAnimation {
+    [self addAnimation:[self likeAnimation] forKey:@"likeAnimation"];
+}
+
+- (CAAnimation *)likeAnimation {
+    
+    CABasicAnimation *postionAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
+    CGFloat dx = (arc4random() % 17);
+    CGFloat dy = (arc4random() % 41);
+    postionAnimation.fromValue = [NSValue valueWithCGPoint:self.position];
+    postionAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(self.position.x + dx - 8, self.position.y + dy - 320)];
+    
+    CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
+    opacityAnimation.fromValue = @(1);
+    opacityAnimation.toValue = @(0);
+    
+    
+    CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
+    groupAnimation.animations = @[postionAnimation,opacityAnimation];
+    groupAnimation.duration = 2.0f;
+    groupAnimation.fillMode = kCAFillModeForwards;
+    groupAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
+    groupAnimation.delegate = self;
+    groupAnimation.removedOnCompletion = NO;
+    return groupAnimation;
+}
+
+
+#pragma mark ----- CAAnimationDelegate
+- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
+    [self removeAllAnimations];
+    [self removeFromSuperlayer];
+}
+
+
+@end

+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatContentView.h

@@ -0,0 +1,22 @@
+//
+//  SeatContentView.h
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/21.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 连麦的UI
+@interface SeatContentView : UIView
+
+@property (nonatomic, strong) NSMutableArray *seatMemberArray;
+
+- (void)refreshSeatUI;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 147 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatContentView.m

@@ -0,0 +1,147 @@
+//
+//  SeatContentView.m
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/21.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "SeatContentView.h"
+#import <RongIMKit/RongIMKit.h>
+
+@interface SeatMemberView : UIView
+
+@property (nonatomic, strong) NSString *userId;
+
+@property (nonatomic, strong) NSString *userName;
+
+@property (nonatomic, strong) UILabel *nameLabel;
+
+- (instancetype)initViewWithFrame:(CGRect)frame useId:(NSString *)userId;
+
+@end
+
+@implementation SeatMemberView
+
+- (instancetype)initViewWithFrame:(CGRect)frame useId:(NSString *)userId {
+    self = [super initWithFrame:frame];
+    if (self) {
+        self.userId = userId;
+        [self setupUI];
+    }
+    return self;
+}
+
+- (void)setupUI {
+    self.backgroundColor = [UIColor clearColor];
+    
+    if ([self.userId isEqualToString:UserDefault(UIDKey)]) { // 自己
+        UIImageView *bgImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"seat_mine"]];
+        [self addSubview:bgImage];
+        [bgImage mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.centerX.mas_equalTo(self.mas_centerX);
+            make.top.mas_equalTo(self.mas_top);
+            make.width.height.mas_equalTo(54);
+        }];
+        UIView *bgView = [[UIView alloc] initWithFrame:CGRectZero];
+        bgView.layer.cornerRadius = 7.0f;
+        bgView.backgroundColor = HexRGB(0xf37f17);
+        [self addSubview:bgView];
+        
+        [bgView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.centerX.mas_equalTo(self.mas_centerX);
+            make.left.mas_greaterThanOrEqualTo(self.mas_left).offset(5);
+            make.height.mas_equalTo(15);
+            make.top.mas_equalTo(bgImage.mas_bottom).offset(-2);
+        }];
+        
+        [bgView addSubview:self.nameLabel];
+        [self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.centerX.mas_equalTo(bgView.mas_centerX);
+            make.centerY.mas_equalTo(bgView.mas_centerY);
+            make.left.mas_equalTo(bgView.mas_left).offset(6);
+            make.right.mas_equalTo(bgView.mas_right).offset(-6);
+        }];
+        
+        
+        self.nameLabel.font = [UIFont systemFontOfSize:9.0f weight:UIFontWeightMedium];
+        self.nameLabel.text = [NSString returnNoNullStringWithString:[RCIMClient sharedRCIMClient].currentUserInfo.name];
+        
+    }
+    else { // 其他人
+        UIImageView *bgImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"seat_other"]];
+        [self addSubview:bgImage];
+        [bgImage mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.centerX.mas_equalTo(self.mas_centerX);
+            make.top.mas_equalTo(self.mas_top).offset(4);
+            make.width.height.mas_equalTo(46);
+        }];
+        
+        [self addSubview:self.nameLabel];
+        [self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self);
+            make.top.mas_equalTo(bgImage.mas_bottom).offset(2);
+            make.height.mas_equalTo(13);
+        }];
+        [self queryUserInfoWithUserId:self.userId];
+    }
+}
+
+- (UILabel *)nameLabel {
+    if (!_nameLabel) {
+        _nameLabel = [[UILabel alloc] init];
+        _nameLabel.textColor = [UIColor whiteColor];
+        _nameLabel.font = [UIFont systemFontOfSize:9.0f];
+        _nameLabel.textAlignment = NSTextAlignmentCenter;
+    }
+    return _nameLabel;
+}
+
+- (void)queryUserInfoWithUserId:(NSString *)userId {
+    [KSRequestManager queryFriendDetailRequest:KS_GET userId:userId success:^(NSDictionary * _Nonnull dic) {
+        if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
+            NSDictionary *result = [dic dictionaryValueForKey:@"data"];
+            self.nameLabel.text = [result stringValueForKey:@"friendNickname"];
+        }
+        else {
+            self.nameLabel.text = @"连麦用户";
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        self.nameLabel.text = @"连麦用户";
+    }];
+}
+
+@end
+
+@implementation SeatContentView
+
+- (instancetype)init {
+    self = [super init];
+    if (self) {
+        self.backgroundColor = [UIColor clearColor];
+    }
+    return self;
+}
+
+- (void)refreshSeatUI {
+    [self removeAllSubviews];
+    CGFloat space = 10;
+    CGFloat width = 54;
+    CGFloat height = 70;
+    for (NSInteger index = 0; index < self.seatMemberArray.count; index++) {
+        NSString *userId = self.seatMemberArray[index];
+        CGRect frame = CGRectMake(space + index * (width + space), space, width, height);
+        SeatMemberView *memberView = [[SeatMemberView alloc] initViewWithFrame:frame useId:userId];
+        [self addSubview:memberView];
+    }
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 10 - 8
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Controller/MineViewController.m

@@ -15,6 +15,7 @@
 #import "UserInfoManager.h"
 #import "UserInfoManager.h"
 #import "TeacherInfo.h"
 #import "TeacherInfo.h"
 #import "VideoCourseViewController.h"
 #import "VideoCourseViewController.h"
+#import "CreateLiveViewController.h"
 
 
 @interface MineViewController ()
 @interface MineViewController ()
 
 
@@ -125,14 +126,15 @@
             break;
             break;
         case MINEVIEWTYPE_STARTBOARDCAST: // 开启直播
         case MINEVIEWTYPE_STARTBOARDCAST: // 开启直播
         {
         {
-            if (self.mineInfo.liveFlag == 1) {
-                
-            }
-            else { // 开通直播审核
-                KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
-                webCtrl.url = [NSString stringWithFormat:@"%@%@", WEBHOST, @"/#/openLive"];
-                [self.navigationController pushViewController:webCtrl animated:YES];
-            }
+//            if (self.mineInfo.liveFlag == 1) {
+                CreateLiveViewController *ctrl = [[CreateLiveViewController alloc] init];
+                [self.navigationController pushViewController:ctrl animated:YES];
+//            }
+//            else { // 开通直播审核
+//                KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
+//                webCtrl.url = [NSString stringWithFormat:@"%@%@", WEBHOST, @"/#/openLive"];
+//                [self.navigationController pushViewController:webCtrl animated:YES];
+//            }
         }
         }
             break;
             break;
         case MINEVIEWTYPE_ORDER: // 商品订单
         case MINEVIEWTYPE_ORDER: // 商品订单

+ 1 - 0
KulexiuForTeacher/Podfile

@@ -34,6 +34,7 @@
   pod 'RongCloudIM/IMKit',  '~> 5.2.0'
   pod 'RongCloudIM/IMKit',  '~> 5.2.0'
   pod 'RongCloudIM/Sight',  '~> 5.2.0'
   pod 'RongCloudIM/Sight',  '~> 5.2.0'
   pod 'RongCloudRTC/RongRTCLib','~> 5.2.0'
   pod 'RongCloudRTC/RongRTCLib','~> 5.2.0'
+  pod 'RongCloudRTC/RongFaceBeautifier','~> 5.2.0'
 #
 #
   # Pods for KulexiuForTeacher
   # Pods for KulexiuForTeacher
 
 

+ 4 - 1
KulexiuForTeacher/Podfile.lock

@@ -49,6 +49,8 @@ PODS:
     - RongCloudIM/IMLibCore
     - RongCloudIM/IMLibCore
   - RongCloudIM/Sight (5.2.0.1):
   - RongCloudIM/Sight (5.2.0.1):
     - RongCloudIM/IMKit
     - RongCloudIM/IMKit
+  - RongCloudRTC/RongFaceBeautifier (5.2.0):
+    - RongCloudRTC/RongRTCLib
   - RongCloudRTC/RongRTCLib (5.2.0):
   - RongCloudRTC/RongRTCLib (5.2.0):
     - RongCloudIM/IMLibCore (>= 5.1.3)
     - RongCloudIM/IMLibCore (>= 5.1.3)
   - RSKImageCropper (3.0.2)
   - RSKImageCropper (3.0.2)
@@ -102,6 +104,7 @@ DEPENDENCIES:
   - RongCloudIM/IMKit (~> 5.2.0)
   - RongCloudIM/IMKit (~> 5.2.0)
   - RongCloudIM/IMLib (~> 5.2.0)
   - RongCloudIM/IMLib (~> 5.2.0)
   - RongCloudIM/Sight (~> 5.2.0)
   - RongCloudIM/Sight (~> 5.2.0)
+  - RongCloudRTC/RongFaceBeautifier (~> 5.2.0)
   - RongCloudRTC/RongRTCLib (~> 5.2.0)
   - RongCloudRTC/RongRTCLib (~> 5.2.0)
   - RSKImageCropper
   - RSKImageCropper
   - SDWebImage (~> 3.8.2)
   - SDWebImage (~> 3.8.2)
@@ -165,6 +168,6 @@ SPEC CHECKSUMS:
   Whiteboard: 16568e7e14f7f451d2aad2536f5fab9c06119934
   Whiteboard: 16568e7e14f7f451d2aad2536f5fab9c06119934
   YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
   YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
 
 
-PODFILE CHECKSUM: 52799f97ca0cfe776d7722218c16e7727368fc20
+PODFILE CHECKSUM: f6853b6be87d0acc3bcb49d0f8bc0e26f9f664f2
 
 
 COCOAPODS: 1.11.2
 COCOAPODS: 1.11.2

+ 4 - 1
KulexiuForTeacher/Pods/Manifest.lock

@@ -49,6 +49,8 @@ PODS:
     - RongCloudIM/IMLibCore
     - RongCloudIM/IMLibCore
   - RongCloudIM/Sight (5.2.0.1):
   - RongCloudIM/Sight (5.2.0.1):
     - RongCloudIM/IMKit
     - RongCloudIM/IMKit
+  - RongCloudRTC/RongFaceBeautifier (5.2.0):
+    - RongCloudRTC/RongRTCLib
   - RongCloudRTC/RongRTCLib (5.2.0):
   - RongCloudRTC/RongRTCLib (5.2.0):
     - RongCloudIM/IMLibCore (>= 5.1.3)
     - RongCloudIM/IMLibCore (>= 5.1.3)
   - RSKImageCropper (3.0.2)
   - RSKImageCropper (3.0.2)
@@ -102,6 +104,7 @@ DEPENDENCIES:
   - RongCloudIM/IMKit (~> 5.2.0)
   - RongCloudIM/IMKit (~> 5.2.0)
   - RongCloudIM/IMLib (~> 5.2.0)
   - RongCloudIM/IMLib (~> 5.2.0)
   - RongCloudIM/Sight (~> 5.2.0)
   - RongCloudIM/Sight (~> 5.2.0)
+  - RongCloudRTC/RongFaceBeautifier (~> 5.2.0)
   - RongCloudRTC/RongRTCLib (~> 5.2.0)
   - RongCloudRTC/RongRTCLib (~> 5.2.0)
   - RSKImageCropper
   - RSKImageCropper
   - SDWebImage (~> 3.8.2)
   - SDWebImage (~> 3.8.2)
@@ -165,6 +168,6 @@ SPEC CHECKSUMS:
   Whiteboard: 16568e7e14f7f451d2aad2536f5fab9c06119934
   Whiteboard: 16568e7e14f7f451d2aad2536f5fab9c06119934
   YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
   YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
 
 
-PODFILE CHECKSUM: 52799f97ca0cfe776d7722218c16e7727368fc20
+PODFILE CHECKSUM: f6853b6be87d0acc3bcb49d0f8bc0e26f9f664f2
 
 
 COCOAPODS: 1.11.2
 COCOAPODS: 1.11.2

文件差异内容过多而无法显示
+ 1192 - 1190
KulexiuForTeacher/Pods/Pods.xcodeproj/project.pbxproj


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/2d_lut.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/3d_lut.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filterFile.zip


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_chengshi.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_chulian.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_chuxin.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_danse.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_fanchase.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_fennen.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_huaijiu.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_hupo.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_landiao.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_langman.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_meiwei.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_mitaofen.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_naicha.png


二进制
KulexiuForTeacher/Pods/RongCloudRTC/RongCloudRTC/MHSDK.bundle/filter_pailide.png


部分文件因为文件数量过多而无法显示