Steven 1 рік тому
батько
коміт
6ffe4712ab
100 змінених файлів з 5695 додано та 96 видалено
  1. 328 24
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. 10 2
      KulexiuForStudent/KulexiuForStudent/AppDelegate.m
  3. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/classroom_quit.imageset/Contents.json
  4. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/classroom_quit.imageset/classroom_quit@2x.png
  5. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/classroom_quit.imageset/classroom_quit@3x.png
  6. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_off.imageset/Contents.json
  7. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_off.imageset/liveVoice_off@2x.png
  8. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_off.imageset/liveVoice_off@3x.png
  9. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_on.imageset/Contents.json
  10. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_on.imageset/liveVoice_on@2x.png
  11. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_on.imageset/liveVoice_on@3x.png
  12. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOff.imageset/Contents.json
  13. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOff.imageset/live_student_micOff@2x.png
  14. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOff.imageset/live_student_micOff@3x.png
  15. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOn.imageset/Contents.json
  16. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOn.imageset/live_student_micOn@2x.png
  17. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOn.imageset/live_student_micOn@3x.png
  18. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connected.imageset/Contents.json
  19. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connected.imageset/seat_connected@2x.png
  20. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connected.imageset/seat_connected@3x.png
  21. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connecting.imageset/Contents.json
  22. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connecting.imageset/seat_connecting@2x.png
  23. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connecting.imageset/seat_connecting@3x.png
  24. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_image.imageset/seat_image@2x.png
  25. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_image.imageset/seat_image@3x.png
  26. 5 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.h
  27. 16 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.m
  28. 1 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSTabBarViewController.m
  29. 1 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/LoginManger/KSLoginManager.m
  30. 9 7
      KulexiuForStudent/KulexiuForStudent/Common/Base/LoginManger/TXIMLinsenter.m
  31. 3 0
      KulexiuForStudent/KulexiuForStudent/Common/Define/KSDomain.h
  32. 0 1
      KulexiuForStudent/KulexiuForStudent/Module/Chat/Controller/ChatViewController.m
  33. 2 1
      KulexiuForStudent/KulexiuForStudent/Module/Chat/Group/Controller/GroupSettingViewController.m
  34. 23 19
      KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m
  35. 2 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/Model/KSEnterLiveroomManager.h
  36. 49 21
      KulexiuForStudent/KulexiuForStudent/Module/Live/Model/KSEnterLiveroomManager.m
  37. 43 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/Model/LiveModuleService.h
  38. 59 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/Model/LiveModuleService.m
  39. 7 2
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/DragWindow/KSDragWindow.h
  40. 1 1
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/DragWindow/KSDragWindowManager.h
  41. 7 1
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/DragWindow/KSDragWindowManager.m
  42. 8 2
      KulexiuForStudent/KulexiuForStudent/Module/Login/Model/UserInfoManager.m
  43. 1 1
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Setting/View/AboutUsBodyView.m
  44. 1 0
      KulexiuForStudent/KulexiuForStudent/Module/TXClassRoom/Controller/TXClassroomViewController.m
  45. 17 14
      KulexiuForStudent/KulexiuForStudent/Module/TXClassRoom/Service/TXClassroom/Model/Classroom.m
  46. 80 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/Controller/TXLiveRoomViewController.h
  47. 2792 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/Controller/TXLiveRoomViewController.m
  48. 61 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveMessageCenter.h
  49. 26 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveMessageCenter.m
  50. 41 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveMessageModel.h
  51. 129 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveMessageModel.m
  52. 59 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveURLUtils.h
  53. 105 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveURLUtils.m
  54. 19 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXTestGenerateUserSig.h
  55. 95 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXTestGenerateUserSig.m
  56. 19 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXConstMessage.h
  57. 46 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXConstMessage.m
  58. 21 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXControlMemberMic.h
  59. 49 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXControlMemberMic.m
  60. 22 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveForceKickMsg.h
  61. 47 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveForceKickMsg.m
  62. 20 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageBlockUser.h
  63. 46 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageBlockUser.m
  64. 19 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageCardMessage.h
  65. 44 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageCardMessage.m
  66. 33 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageChatBan.h
  67. 50 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageChatBan.m
  68. 17 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageClose.h
  69. 38 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageClose.m
  70. 22 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageDownSeat.h
  71. 48 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageDownSeat.m
  72. 17 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageDownSeatAll.h
  73. 42 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageDownSeatAll.m
  74. 17 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageEnter.h
  75. 46 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageEnter.m
  76. 25 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageKickOut.h
  77. 50 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageKickOut.m
  78. 17 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLeave.h
  79. 46 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLeave.m
  80. 19 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLike.h
  81. 47 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLike.m
  82. 22 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLikeCount.h
  83. 48 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLikeCount.m
  84. 21 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageMemberUp.h
  85. 46 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageMemberUp.m
  86. 17 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageOpenLive.h
  87. 43 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageOpenLive.m
  88. 17 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessagePauseLive.h
  89. 42 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessagePauseLive.m
  90. 17 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageRejectAllSeat.h
  91. 43 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageRejectAllSeat.m
  92. 43 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatApply.h
  93. 70 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatApply.m
  94. 21 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatControl.h
  95. 47 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatControl.m
  96. 36 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatResponse.h
  97. 55 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatResponse.m
  98. 17 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageShopRush.h
  99. 43 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageShopRush.m
  100. 26 0
      KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageStatSync.h

+ 328 - 24
KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj

@@ -366,6 +366,55 @@
 		BC0D1F71281015B000C5D9E5 /* VideoCourseCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0D1F6E281015AF00C5D9E5 /* VideoCourseCell.m */; };
 		BC0D1F72281015B000C5D9E5 /* VideoCourseCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC0D1F6F281015AF00C5D9E5 /* VideoCourseCell.xib */; };
 		BC0D1F752810165500C5D9E5 /* VideoCourseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0D1F742810165400C5D9E5 /* VideoCourseModel.m */; };
+		BC106BC52A9336F8000759A9 /* TXLiveRoomViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BC42A9336F8000759A9 /* TXLiveRoomViewController.m */; };
+		BC106BFE2A933829000759A9 /* TXMicStatusSync.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BC62A93381C000759A9 /* TXMicStatusSync.m */; };
+		BC106BFF2A933829000759A9 /* TXLiveMessageCardMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BC92A93381D000759A9 /* TXLiveMessageCardMessage.m */; };
+		BC106C002A933829000759A9 /* TXLiveMessageLike.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BCB2A93381D000759A9 /* TXLiveMessageLike.m */; };
+		BC106C012A933829000759A9 /* TXLiveMessageBlockUser.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BCD2A93381E000759A9 /* TXLiveMessageBlockUser.m */; };
+		BC106C022A933829000759A9 /* TXLiveUser.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BCF2A93381E000759A9 /* TXLiveUser.m */; };
+		BC106C032A933829000759A9 /* TXLiveMessageOpenLive.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BD02A93381E000759A9 /* TXLiveMessageOpenLive.m */; };
+		BC106C042A933829000759A9 /* TXLiveMessageMemberUp.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BD12A93381E000759A9 /* TXLiveMessageMemberUp.m */; };
+		BC106C052A933829000759A9 /* TXLiveMessageKickOut.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BD32A93381F000759A9 /* TXLiveMessageKickOut.m */; };
+		BC106C062A933829000759A9 /* TXLiveMessageStatSync.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BD42A93381F000759A9 /* TXLiveMessageStatSync.m */; };
+		BC106C072A933829000759A9 /* TXLiveMessageLikeCount.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BD52A93381F000759A9 /* TXLiveMessageLikeCount.m */; };
+		BC106C082A933829000759A9 /* TXLiveMessageEnter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BD72A933820000759A9 /* TXLiveMessageEnter.m */; };
+		BC106C092A933829000759A9 /* TXLiveMessageUserQuit.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BD82A933820000759A9 /* TXLiveMessageUserQuit.m */; };
+		BC106C0A2A933829000759A9 /* TXLiveMessageDownSeatAll.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BDC2A933821000759A9 /* TXLiveMessageDownSeatAll.m */; };
+		BC106C0B2A933829000759A9 /* TXLiveMessageLeave.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BDD2A933821000759A9 /* TXLiveMessageLeave.m */; };
+		BC106C0C2A933829000759A9 /* TXLiveMessageSeatControl.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BDF2A933822000759A9 /* TXLiveMessageSeatControl.m */; };
+		BC106C0D2A933829000759A9 /* TXLiveMessageClose.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BE22A933822000759A9 /* TXLiveMessageClose.m */; };
+		BC106C0E2A933829000759A9 /* TXLiveMessageChatBan.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BE32A933823000759A9 /* TXLiveMessageChatBan.m */; };
+		BC106C0F2A933829000759A9 /* TXLiveMessageSeatApply.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BE52A933823000759A9 /* TXLiveMessageSeatApply.m */; };
+		BC106C102A933829000759A9 /* TXLiveMessageUnBlockUser.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BE62A933823000759A9 /* TXLiveMessageUnBlockUser.m */; };
+		BC106C112A933829000759A9 /* TXConstMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BE72A933824000759A9 /* TXConstMessage.m */; };
+		BC106C122A933829000759A9 /* TXLiveMessagePauseLive.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BEB2A933825000759A9 /* TXLiveMessagePauseLive.m */; };
+		BC106C132A933829000759A9 /* TXControlMemberMic.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BEC2A933825000759A9 /* TXControlMemberMic.m */; };
+		BC106C142A933829000759A9 /* TXLiveMessageSeatResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BF02A933826000759A9 /* TXLiveMessageSeatResponse.m */; };
+		BC106C152A933829000759A9 /* TXLiveMessageWelcome.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BF12A933826000759A9 /* TXLiveMessageWelcome.m */; };
+		BC106C162A933829000759A9 /* TXLiveTextMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BF42A933827000759A9 /* TXLiveTextMessage.m */; };
+		BC106C172A933829000759A9 /* TXLiveMessageRejectAllSeat.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BF82A933828000759A9 /* TXLiveMessageRejectAllSeat.m */; };
+		BC106C182A933829000759A9 /* TXLiveMessageShopRush.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BFA2A933828000759A9 /* TXLiveMessageShopRush.m */; };
+		BC106C192A933829000759A9 /* TXLiveMessageDownSeat.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BFB2A933828000759A9 /* TXLiveMessageDownSeat.m */; };
+		BC106C222A933869000759A9 /* TXLiveMessageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C1A2A933867000759A9 /* TXLiveMessageModel.m */; };
+		BC106C232A933869000759A9 /* TXLiveMessageCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C1C2A933867000759A9 /* TXLiveMessageCenter.m */; };
+		BC106C242A933869000759A9 /* TXTestGenerateUserSig.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C1F2A933868000759A9 /* TXTestGenerateUserSig.m */; };
+		BC106C252A933869000759A9 /* TXLiveURLUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C212A933869000759A9 /* TXLiveURLUtils.m */; };
+		BC106C342A9338A7000759A9 /* TXLiveLoadingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC106C272A9338A3000759A9 /* TXLiveLoadingView.xib */; };
+		BC106C352A9338A7000759A9 /* TXUISeatMember.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C282A9338A3000759A9 /* TXUISeatMember.m */; };
+		BC106C362A9338A7000759A9 /* TXLiveLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C292A9338A4000759A9 /* TXLiveLoadingView.m */; };
+		BC106C372A9338A7000759A9 /* TXLiveChatListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C2B2A9338A4000759A9 /* TXLiveChatListCell.m */; };
+		BC106C382A9338A7000759A9 /* LiveRoomConfirmAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C2D2A9338A5000759A9 /* LiveRoomConfirmAlert.m */; };
+		BC106C392A9338A7000759A9 /* TXLiveVideoView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C2E2A9338A5000759A9 /* TXLiveVideoView.m */; };
+		BC106C3A2A9338A7000759A9 /* TXSeatContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C2F2A9338A5000759A9 /* TXSeatContainerView.m */; };
+		BC106C3B2A9338A7000759A9 /* custom_loading.json in Resources */ = {isa = PBXBuildFile; fileRef = BC106C312A9338A6000759A9 /* custom_loading.json */; };
+		BC106C3E2A9338F6000759A9 /* TXLiveForceKickMsg.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C3D2A9338F6000759A9 /* TXLiveForceKickMsg.m */; };
+		BC106C422A9339FB000759A9 /* LiveAlertView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC106C402A9339FB000759A9 /* LiveAlertView.xib */; };
+		BC106C432A9339FB000759A9 /* LiveAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C412A9339FB000759A9 /* LiveAlertView.m */; };
+		BC106C472A933B8B000759A9 /* LiveRoomBottomView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC106C442A933B8B000759A9 /* LiveRoomBottomView.xib */; };
+		BC106C482A933B8B000759A9 /* LiveRoomBottomView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C462A933B8B000759A9 /* LiveRoomBottomView.m */; };
+		BC106C4C2A933E75000759A9 /* LiveRoomHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC106C492A933E73000759A9 /* LiveRoomHeadView.xib */; };
+		BC106C4D2A933E75000759A9 /* LiveRoomHeadView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C4A2A933E74000759A9 /* LiveRoomHeadView.m */; };
+		BC106C502A9351DA000759A9 /* LiveModuleService.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106C4F2A9351DA000759A9 /* LiveModuleService.m */; };
 		BC1191FF280ED64E00A716F7 /* MyCourseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1191FE280ED64E00A716F7 /* MyCourseViewController.m */; };
 		BC119213280ED6A900A716F7 /* MyLessonBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC119200280ED6A600A716F7 /* MyLessonBodyView.m */; };
 		BC119215280ED6A900A716F7 /* MyLiveCourseCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC119203280ED6A700A716F7 /* MyLiveCourseCell.xib */; };
@@ -739,10 +788,6 @@
 		BCB6348627F6D29600ACFDCF /* LiveSeatApplyCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6345C27F6D29600ACFDCF /* LiveSeatApplyCell.m */; };
 		BCB635A627F6D90600ACFDCF /* KSLiveEmptyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB635A427F6D90600ACFDCF /* KSLiveEmptyView.m */; };
 		BCB635A927F6D93300ACFDCF /* KSChatVideoView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB635A727F6D93300ACFDCF /* KSChatVideoView.m */; };
-		BCB635AD27F6E06500ACFDCF /* LiveRoomHeadView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB635AB27F6E06500ACFDCF /* LiveRoomHeadView.m */; };
-		BCB635AE27F6E06500ACFDCF /* LiveRoomHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCB635AC27F6E06500ACFDCF /* LiveRoomHeadView.xib */; };
-		BCB635B227F6E1A600ACFDCF /* LiveRoomBottomView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB635B027F6E1A600ACFDCF /* LiveRoomBottomView.m */; };
-		BCB635B327F6E1A600ACFDCF /* LiveRoomBottomView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCB635B127F6E1A600ACFDCF /* LiveRoomBottomView.xib */; };
 		BCB908E22850B07300F5FF69 /* KSChatMusicMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB908DE2850B07300F5FF69 /* KSChatMusicMessage.m */; };
 		BCB908E32850B07300F5FF69 /* KSChatLiveMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB908DF2850B07300F5FF69 /* KSChatLiveMessage.m */; };
 		BCB908EE2850B08D00F5FF69 /* ShareLiveCellContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB908E42850B08C00F5FF69 /* ShareLiveCellContentView.m */; };
@@ -1682,6 +1727,99 @@
 		BC0D1F70281015B000C5D9E5 /* VideoCourseCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoCourseCell.h; sourceTree = "<group>"; };
 		BC0D1F732810165400C5D9E5 /* VideoCourseModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoCourseModel.h; sourceTree = "<group>"; };
 		BC0D1F742810165400C5D9E5 /* VideoCourseModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoCourseModel.m; sourceTree = "<group>"; };
+		BC106BC32A9336F8000759A9 /* TXLiveRoomViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TXLiveRoomViewController.h; sourceTree = "<group>"; };
+		BC106BC42A9336F8000759A9 /* TXLiveRoomViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TXLiveRoomViewController.m; sourceTree = "<group>"; };
+		BC106BC62A93381C000759A9 /* TXMicStatusSync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXMicStatusSync.m; sourceTree = "<group>"; };
+		BC106BC72A93381C000759A9 /* TXLiveMessageOpenLive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageOpenLive.h; sourceTree = "<group>"; };
+		BC106BC82A93381C000759A9 /* TXLiveTextMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveTextMessage.h; sourceTree = "<group>"; };
+		BC106BC92A93381D000759A9 /* TXLiveMessageCardMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageCardMessage.m; sourceTree = "<group>"; };
+		BC106BCA2A93381D000759A9 /* TXLiveMessageCardMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageCardMessage.h; sourceTree = "<group>"; };
+		BC106BCB2A93381D000759A9 /* TXLiveMessageLike.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageLike.m; sourceTree = "<group>"; };
+		BC106BCC2A93381D000759A9 /* TXLiveMessageWelcome.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageWelcome.h; sourceTree = "<group>"; };
+		BC106BCD2A93381E000759A9 /* TXLiveMessageBlockUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageBlockUser.m; sourceTree = "<group>"; };
+		BC106BCE2A93381E000759A9 /* TXLiveMessageDownSeat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageDownSeat.h; sourceTree = "<group>"; };
+		BC106BCF2A93381E000759A9 /* TXLiveUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveUser.m; sourceTree = "<group>"; };
+		BC106BD02A93381E000759A9 /* TXLiveMessageOpenLive.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageOpenLive.m; sourceTree = "<group>"; };
+		BC106BD12A93381E000759A9 /* TXLiveMessageMemberUp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageMemberUp.m; sourceTree = "<group>"; };
+		BC106BD22A93381F000759A9 /* TXLiveMessageSeatResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageSeatResponse.h; sourceTree = "<group>"; };
+		BC106BD32A93381F000759A9 /* TXLiveMessageKickOut.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageKickOut.m; sourceTree = "<group>"; };
+		BC106BD42A93381F000759A9 /* TXLiveMessageStatSync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageStatSync.m; sourceTree = "<group>"; };
+		BC106BD52A93381F000759A9 /* TXLiveMessageLikeCount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageLikeCount.m; sourceTree = "<group>"; };
+		BC106BD62A933820000759A9 /* TXMicStatusSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXMicStatusSync.h; sourceTree = "<group>"; };
+		BC106BD72A933820000759A9 /* TXLiveMessageEnter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageEnter.m; sourceTree = "<group>"; };
+		BC106BD82A933820000759A9 /* TXLiveMessageUserQuit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageUserQuit.m; sourceTree = "<group>"; };
+		BC106BD92A933820000759A9 /* TXControlMemberMic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXControlMemberMic.h; sourceTree = "<group>"; };
+		BC106BDA2A933821000759A9 /* TXLiveMessageMemberUp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageMemberUp.h; sourceTree = "<group>"; };
+		BC106BDB2A933821000759A9 /* TXLiveMessageSeatApply.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageSeatApply.h; sourceTree = "<group>"; };
+		BC106BDC2A933821000759A9 /* TXLiveMessageDownSeatAll.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageDownSeatAll.m; sourceTree = "<group>"; };
+		BC106BDD2A933821000759A9 /* TXLiveMessageLeave.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageLeave.m; sourceTree = "<group>"; };
+		BC106BDE2A933821000759A9 /* TXLiveMessageEnter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageEnter.h; sourceTree = "<group>"; };
+		BC106BDF2A933822000759A9 /* TXLiveMessageSeatControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageSeatControl.m; sourceTree = "<group>"; };
+		BC106BE02A933822000759A9 /* TXLiveMessageShopRush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageShopRush.h; sourceTree = "<group>"; };
+		BC106BE12A933822000759A9 /* TXLiveMessageSeatControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageSeatControl.h; sourceTree = "<group>"; };
+		BC106BE22A933822000759A9 /* TXLiveMessageClose.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageClose.m; sourceTree = "<group>"; };
+		BC106BE32A933823000759A9 /* TXLiveMessageChatBan.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageChatBan.m; sourceTree = "<group>"; };
+		BC106BE42A933823000759A9 /* TXLiveMessageLikeCount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageLikeCount.h; sourceTree = "<group>"; };
+		BC106BE52A933823000759A9 /* TXLiveMessageSeatApply.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageSeatApply.m; sourceTree = "<group>"; };
+		BC106BE62A933823000759A9 /* TXLiveMessageUnBlockUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageUnBlockUser.m; sourceTree = "<group>"; };
+		BC106BE72A933824000759A9 /* TXConstMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXConstMessage.m; sourceTree = "<group>"; };
+		BC106BE82A933824000759A9 /* TXLiveMessageStatSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageStatSync.h; sourceTree = "<group>"; };
+		BC106BE92A933824000759A9 /* TXLiveMessageBlockUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageBlockUser.h; sourceTree = "<group>"; };
+		BC106BEA2A933824000759A9 /* TXLiveMessageRejectAllSeat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageRejectAllSeat.h; sourceTree = "<group>"; };
+		BC106BEB2A933825000759A9 /* TXLiveMessagePauseLive.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessagePauseLive.m; sourceTree = "<group>"; };
+		BC106BEC2A933825000759A9 /* TXControlMemberMic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXControlMemberMic.m; sourceTree = "<group>"; };
+		BC106BED2A933825000759A9 /* TXLiveMessageLike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageLike.h; sourceTree = "<group>"; };
+		BC106BEE2A933825000759A9 /* TXLiveMessageDownSeatAll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageDownSeatAll.h; sourceTree = "<group>"; };
+		BC106BEF2A933825000759A9 /* TXLiveMessagePauseLive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessagePauseLive.h; sourceTree = "<group>"; };
+		BC106BF02A933826000759A9 /* TXLiveMessageSeatResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageSeatResponse.m; sourceTree = "<group>"; };
+		BC106BF12A933826000759A9 /* TXLiveMessageWelcome.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageWelcome.m; sourceTree = "<group>"; };
+		BC106BF22A933826000759A9 /* TXLiveUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveUser.h; sourceTree = "<group>"; };
+		BC106BF32A933826000759A9 /* TXConstMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXConstMessage.h; sourceTree = "<group>"; };
+		BC106BF42A933827000759A9 /* TXLiveTextMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveTextMessage.m; sourceTree = "<group>"; };
+		BC106BF52A933827000759A9 /* TXLiveMessageUnBlockUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageUnBlockUser.h; sourceTree = "<group>"; };
+		BC106BF62A933827000759A9 /* TXLiveMessageUserQuit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageUserQuit.h; sourceTree = "<group>"; };
+		BC106BF72A933827000759A9 /* TXLiveMessageLeave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageLeave.h; sourceTree = "<group>"; };
+		BC106BF82A933828000759A9 /* TXLiveMessageRejectAllSeat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageRejectAllSeat.m; sourceTree = "<group>"; };
+		BC106BF92A933828000759A9 /* TXLiveMessageClose.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageClose.h; sourceTree = "<group>"; };
+		BC106BFA2A933828000759A9 /* TXLiveMessageShopRush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageShopRush.m; sourceTree = "<group>"; };
+		BC106BFB2A933828000759A9 /* TXLiveMessageDownSeat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageDownSeat.m; sourceTree = "<group>"; };
+		BC106BFC2A933828000759A9 /* TXLiveMessageKickOut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageKickOut.h; sourceTree = "<group>"; };
+		BC106BFD2A933829000759A9 /* TXLiveMessageChatBan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageChatBan.h; sourceTree = "<group>"; };
+		BC106C1A2A933867000759A9 /* TXLiveMessageModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageModel.m; sourceTree = "<group>"; };
+		BC106C1B2A933867000759A9 /* TXTestGenerateUserSig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXTestGenerateUserSig.h; sourceTree = "<group>"; };
+		BC106C1C2A933867000759A9 /* TXLiveMessageCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageCenter.m; sourceTree = "<group>"; };
+		BC106C1D2A933868000759A9 /* TXLiveMessageCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageCenter.h; sourceTree = "<group>"; };
+		BC106C1E2A933868000759A9 /* TXLiveURLUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveURLUtils.h; sourceTree = "<group>"; };
+		BC106C1F2A933868000759A9 /* TXTestGenerateUserSig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXTestGenerateUserSig.m; sourceTree = "<group>"; };
+		BC106C202A933868000759A9 /* TXLiveMessageModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageModel.h; sourceTree = "<group>"; };
+		BC106C212A933869000759A9 /* TXLiveURLUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveURLUtils.m; sourceTree = "<group>"; };
+		BC106C262A9338A3000759A9 /* TXLiveVideoView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveVideoView.h; sourceTree = "<group>"; };
+		BC106C272A9338A3000759A9 /* TXLiveLoadingView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TXLiveLoadingView.xib; sourceTree = "<group>"; };
+		BC106C282A9338A3000759A9 /* TXUISeatMember.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXUISeatMember.m; sourceTree = "<group>"; };
+		BC106C292A9338A4000759A9 /* TXLiveLoadingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveLoadingView.m; sourceTree = "<group>"; };
+		BC106C2A2A9338A4000759A9 /* TXLiveChatListCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveChatListCell.h; sourceTree = "<group>"; };
+		BC106C2B2A9338A4000759A9 /* TXLiveChatListCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveChatListCell.m; sourceTree = "<group>"; };
+		BC106C2C2A9338A5000759A9 /* TXUISeatMember.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXUISeatMember.h; sourceTree = "<group>"; };
+		BC106C2D2A9338A5000759A9 /* LiveRoomConfirmAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveRoomConfirmAlert.m; sourceTree = "<group>"; };
+		BC106C2E2A9338A5000759A9 /* TXLiveVideoView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveVideoView.m; sourceTree = "<group>"; };
+		BC106C2F2A9338A5000759A9 /* TXSeatContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXSeatContainerView.m; sourceTree = "<group>"; };
+		BC106C302A9338A6000759A9 /* TXSeatContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXSeatContainerView.h; sourceTree = "<group>"; };
+		BC106C312A9338A6000759A9 /* custom_loading.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = custom_loading.json; sourceTree = "<group>"; };
+		BC106C322A9338A6000759A9 /* TXLiveLoadingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveLoadingView.h; sourceTree = "<group>"; };
+		BC106C332A9338A7000759A9 /* LiveRoomConfirmAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveRoomConfirmAlert.h; sourceTree = "<group>"; };
+		BC106C3C2A9338F5000759A9 /* TXLiveForceKickMsg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveForceKickMsg.h; sourceTree = "<group>"; };
+		BC106C3D2A9338F6000759A9 /* TXLiveForceKickMsg.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveForceKickMsg.m; sourceTree = "<group>"; };
+		BC106C3F2A9339FB000759A9 /* LiveAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveAlertView.h; sourceTree = "<group>"; };
+		BC106C402A9339FB000759A9 /* LiveAlertView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LiveAlertView.xib; sourceTree = "<group>"; };
+		BC106C412A9339FB000759A9 /* LiveAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveAlertView.m; sourceTree = "<group>"; };
+		BC106C442A933B8B000759A9 /* LiveRoomBottomView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LiveRoomBottomView.xib; sourceTree = "<group>"; };
+		BC106C452A933B8B000759A9 /* LiveRoomBottomView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveRoomBottomView.h; sourceTree = "<group>"; };
+		BC106C462A933B8B000759A9 /* LiveRoomBottomView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveRoomBottomView.m; sourceTree = "<group>"; };
+		BC106C492A933E73000759A9 /* LiveRoomHeadView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LiveRoomHeadView.xib; sourceTree = "<group>"; };
+		BC106C4A2A933E74000759A9 /* LiveRoomHeadView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveRoomHeadView.m; sourceTree = "<group>"; };
+		BC106C4B2A933E74000759A9 /* LiveRoomHeadView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveRoomHeadView.h; sourceTree = "<group>"; };
+		BC106C4E2A9351DA000759A9 /* LiveModuleService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveModuleService.h; sourceTree = "<group>"; };
+		BC106C4F2A9351DA000759A9 /* LiveModuleService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiveModuleService.m; sourceTree = "<group>"; };
 		BC1191FD280ED64E00A716F7 /* MyCourseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyCourseViewController.h; sourceTree = "<group>"; };
 		BC1191FE280ED64E00A716F7 /* MyCourseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyCourseViewController.m; sourceTree = "<group>"; };
 		BC119200280ED6A600A716F7 /* MyLessonBodyView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyLessonBodyView.m; sourceTree = "<group>"; };
@@ -2262,12 +2400,6 @@
 		BCB635A527F6D90600ACFDCF /* KSLiveEmptyView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSLiveEmptyView.h; sourceTree = "<group>"; };
 		BCB635A727F6D93300ACFDCF /* KSChatVideoView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSChatVideoView.m; sourceTree = "<group>"; };
 		BCB635A827F6D93300ACFDCF /* KSChatVideoView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSChatVideoView.h; sourceTree = "<group>"; };
-		BCB635AA27F6E06500ACFDCF /* LiveRoomHeadView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveRoomHeadView.h; sourceTree = "<group>"; };
-		BCB635AB27F6E06500ACFDCF /* LiveRoomHeadView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveRoomHeadView.m; sourceTree = "<group>"; };
-		BCB635AC27F6E06500ACFDCF /* LiveRoomHeadView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LiveRoomHeadView.xib; sourceTree = "<group>"; };
-		BCB635AF27F6E1A600ACFDCF /* LiveRoomBottomView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveRoomBottomView.h; sourceTree = "<group>"; };
-		BCB635B027F6E1A600ACFDCF /* LiveRoomBottomView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveRoomBottomView.m; sourceTree = "<group>"; };
-		BCB635B127F6E1A600ACFDCF /* LiveRoomBottomView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LiveRoomBottomView.xib; sourceTree = "<group>"; };
 		BCB908DE2850B07300F5FF69 /* KSChatMusicMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSChatMusicMessage.m; sourceTree = "<group>"; };
 		BCB908DF2850B07300F5FF69 /* KSChatLiveMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSChatLiveMessage.m; sourceTree = "<group>"; };
 		BCB908E02850B07300F5FF69 /* KSChatMusicMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSChatMusicMessage.h; sourceTree = "<group>"; };
@@ -2922,6 +3054,7 @@
 		275FA1F027E7356A00CFEA2E /* Module */ = {
 			isa = PBXGroup;
 			children = (
+				BC106BBE2A933688000759A9 /* TXLive */,
 				BCC0F5E52A8CD7A600C4EFA4 /* TXClassRoom */,
 				BC4CF28828D058E600961C61 /* Widget */,
 				BC71D1342887CD470010F14B /* AnimationLaunch */,
@@ -4286,6 +4419,136 @@
 			path = AnimationView;
 			sourceTree = "<group>";
 		};
+		BC106BBE2A933688000759A9 /* TXLive */ = {
+			isa = PBXGroup;
+			children = (
+				BC106BC12A9336B0000759A9 /* Controller */,
+				BC106BC02A9336B0000759A9 /* Model */,
+				BC106BC22A9336B0000759A9 /* TXLiveMessage */,
+				BC106BBF2A9336AF000759A9 /* View */,
+			);
+			path = TXLive;
+			sourceTree = "<group>";
+		};
+		BC106BBF2A9336AF000759A9 /* View */ = {
+			isa = PBXGroup;
+			children = (
+				BC106C3F2A9339FB000759A9 /* LiveAlertView.h */,
+				BC106C412A9339FB000759A9 /* LiveAlertView.m */,
+				BC106C402A9339FB000759A9 /* LiveAlertView.xib */,
+				BC106C312A9338A6000759A9 /* custom_loading.json */,
+				BC106C332A9338A7000759A9 /* LiveRoomConfirmAlert.h */,
+				BC106C2D2A9338A5000759A9 /* LiveRoomConfirmAlert.m */,
+				BC106C2A2A9338A4000759A9 /* TXLiveChatListCell.h */,
+				BC106C2B2A9338A4000759A9 /* TXLiveChatListCell.m */,
+				BC106C322A9338A6000759A9 /* TXLiveLoadingView.h */,
+				BC106C292A9338A4000759A9 /* TXLiveLoadingView.m */,
+				BC106C272A9338A3000759A9 /* TXLiveLoadingView.xib */,
+				BC106C262A9338A3000759A9 /* TXLiveVideoView.h */,
+				BC106C2E2A9338A5000759A9 /* TXLiveVideoView.m */,
+				BC106C302A9338A6000759A9 /* TXSeatContainerView.h */,
+				BC106C2F2A9338A5000759A9 /* TXSeatContainerView.m */,
+				BC106C2C2A9338A5000759A9 /* TXUISeatMember.h */,
+				BC106C282A9338A3000759A9 /* TXUISeatMember.m */,
+				BC106C452A933B8B000759A9 /* LiveRoomBottomView.h */,
+				BC106C462A933B8B000759A9 /* LiveRoomBottomView.m */,
+				BC106C442A933B8B000759A9 /* LiveRoomBottomView.xib */,
+				BC106C4B2A933E74000759A9 /* LiveRoomHeadView.h */,
+				BC106C4A2A933E74000759A9 /* LiveRoomHeadView.m */,
+				BC106C492A933E73000759A9 /* LiveRoomHeadView.xib */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		BC106BC02A9336B0000759A9 /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				BC106C1D2A933868000759A9 /* TXLiveMessageCenter.h */,
+				BC106C1C2A933867000759A9 /* TXLiveMessageCenter.m */,
+				BC106C202A933868000759A9 /* TXLiveMessageModel.h */,
+				BC106C1A2A933867000759A9 /* TXLiveMessageModel.m */,
+				BC106C1E2A933868000759A9 /* TXLiveURLUtils.h */,
+				BC106C212A933869000759A9 /* TXLiveURLUtils.m */,
+				BC106C1B2A933867000759A9 /* TXTestGenerateUserSig.h */,
+				BC106C1F2A933868000759A9 /* TXTestGenerateUserSig.m */,
+			);
+			path = Model;
+			sourceTree = "<group>";
+		};
+		BC106BC12A9336B0000759A9 /* Controller */ = {
+			isa = PBXGroup;
+			children = (
+				BC106BC32A9336F8000759A9 /* TXLiveRoomViewController.h */,
+				BC106BC42A9336F8000759A9 /* TXLiveRoomViewController.m */,
+			);
+			path = Controller;
+			sourceTree = "<group>";
+		};
+		BC106BC22A9336B0000759A9 /* TXLiveMessage */ = {
+			isa = PBXGroup;
+			children = (
+				BC106BF32A933826000759A9 /* TXConstMessage.h */,
+				BC106BE72A933824000759A9 /* TXConstMessage.m */,
+				BC106BD92A933820000759A9 /* TXControlMemberMic.h */,
+				BC106BEC2A933825000759A9 /* TXControlMemberMic.m */,
+				BC106BE92A933824000759A9 /* TXLiveMessageBlockUser.h */,
+				BC106BCD2A93381E000759A9 /* TXLiveMessageBlockUser.m */,
+				BC106BCA2A93381D000759A9 /* TXLiveMessageCardMessage.h */,
+				BC106BC92A93381D000759A9 /* TXLiveMessageCardMessage.m */,
+				BC106BFD2A933829000759A9 /* TXLiveMessageChatBan.h */,
+				BC106BE32A933823000759A9 /* TXLiveMessageChatBan.m */,
+				BC106BF92A933828000759A9 /* TXLiveMessageClose.h */,
+				BC106BE22A933822000759A9 /* TXLiveMessageClose.m */,
+				BC106BCE2A93381E000759A9 /* TXLiveMessageDownSeat.h */,
+				BC106BFB2A933828000759A9 /* TXLiveMessageDownSeat.m */,
+				BC106BEE2A933825000759A9 /* TXLiveMessageDownSeatAll.h */,
+				BC106BDC2A933821000759A9 /* TXLiveMessageDownSeatAll.m */,
+				BC106BDE2A933821000759A9 /* TXLiveMessageEnter.h */,
+				BC106BD72A933820000759A9 /* TXLiveMessageEnter.m */,
+				BC106BFC2A933828000759A9 /* TXLiveMessageKickOut.h */,
+				BC106BD32A93381F000759A9 /* TXLiveMessageKickOut.m */,
+				BC106BF72A933827000759A9 /* TXLiveMessageLeave.h */,
+				BC106BDD2A933821000759A9 /* TXLiveMessageLeave.m */,
+				BC106BED2A933825000759A9 /* TXLiveMessageLike.h */,
+				BC106BCB2A93381D000759A9 /* TXLiveMessageLike.m */,
+				BC106BE42A933823000759A9 /* TXLiveMessageLikeCount.h */,
+				BC106BD52A93381F000759A9 /* TXLiveMessageLikeCount.m */,
+				BC106BDA2A933821000759A9 /* TXLiveMessageMemberUp.h */,
+				BC106BD12A93381E000759A9 /* TXLiveMessageMemberUp.m */,
+				BC106BC72A93381C000759A9 /* TXLiveMessageOpenLive.h */,
+				BC106BD02A93381E000759A9 /* TXLiveMessageOpenLive.m */,
+				BC106BEF2A933825000759A9 /* TXLiveMessagePauseLive.h */,
+				BC106BEB2A933825000759A9 /* TXLiveMessagePauseLive.m */,
+				BC106BEA2A933824000759A9 /* TXLiveMessageRejectAllSeat.h */,
+				BC106BF82A933828000759A9 /* TXLiveMessageRejectAllSeat.m */,
+				BC106BDB2A933821000759A9 /* TXLiveMessageSeatApply.h */,
+				BC106BE52A933823000759A9 /* TXLiveMessageSeatApply.m */,
+				BC106BE12A933822000759A9 /* TXLiveMessageSeatControl.h */,
+				BC106BDF2A933822000759A9 /* TXLiveMessageSeatControl.m */,
+				BC106BD22A93381F000759A9 /* TXLiveMessageSeatResponse.h */,
+				BC106BF02A933826000759A9 /* TXLiveMessageSeatResponse.m */,
+				BC106BE02A933822000759A9 /* TXLiveMessageShopRush.h */,
+				BC106BFA2A933828000759A9 /* TXLiveMessageShopRush.m */,
+				BC106BE82A933824000759A9 /* TXLiveMessageStatSync.h */,
+				BC106BD42A93381F000759A9 /* TXLiveMessageStatSync.m */,
+				BC106BF52A933827000759A9 /* TXLiveMessageUnBlockUser.h */,
+				BC106BE62A933823000759A9 /* TXLiveMessageUnBlockUser.m */,
+				BC106BF62A933827000759A9 /* TXLiveMessageUserQuit.h */,
+				BC106BD82A933820000759A9 /* TXLiveMessageUserQuit.m */,
+				BC106BCC2A93381D000759A9 /* TXLiveMessageWelcome.h */,
+				BC106BF12A933826000759A9 /* TXLiveMessageWelcome.m */,
+				BC106BC82A93381C000759A9 /* TXLiveTextMessage.h */,
+				BC106BF42A933827000759A9 /* TXLiveTextMessage.m */,
+				BC106BF22A933826000759A9 /* TXLiveUser.h */,
+				BC106BCF2A93381E000759A9 /* TXLiveUser.m */,
+				BC106BD62A933820000759A9 /* TXMicStatusSync.h */,
+				BC106BC62A93381C000759A9 /* TXMicStatusSync.m */,
+				BC106C3C2A9338F5000759A9 /* TXLiveForceKickMsg.h */,
+				BC106C3D2A9338F6000759A9 /* TXLiveForceKickMsg.m */,
+			);
+			path = TXLiveMessage;
+			sourceTree = "<group>";
+		};
 		BC1191F9280ED63C00A716F7 /* MineCourse */ = {
 			isa = PBXGroup;
 			children = (
@@ -4530,9 +4793,9 @@
 		BC2888532A80F7BF0064B773 /* LoginManger */ = {
 			isa = PBXGroup;
 			children = (
-				BC2888542A80F7BF0064B773 /* TXIMLinsenter.h */,
-				BC2888552A80F7BF0064B773 /* KSLoginManager.m */,
 				BC2888562A80F7BF0064B773 /* KSLoginManager.h */,
+				BC2888552A80F7BF0064B773 /* KSLoginManager.m */,
+				BC2888542A80F7BF0064B773 /* TXIMLinsenter.h */,
 				BC2888572A80F7BF0064B773 /* TXIMLinsenter.m */,
 			);
 			path = LoginManger;
@@ -5457,6 +5720,8 @@
 			children = (
 				BCB6342E27F6D29500ACFDCF /* KSEnterLiveroomManager.h */,
 				BCB6343227F6D29500ACFDCF /* KSEnterLiveroomManager.m */,
+				BC106C4E2A9351DA000759A9 /* LiveModuleService.h */,
+				BC106C4F2A9351DA000759A9 /* LiveModuleService.m */,
 				BCB6342F27F6D29500ACFDCF /* KSLiveStreamVideo.h */,
 				BCB6343327F6D29500ACFDCF /* KSLiveStreamVideo.m */,
 				BCB6343027F6D29500ACFDCF /* LiveroomTimeManager.h */,
@@ -5485,12 +5750,6 @@
 				BCB6343727F6D29500ACFDCF /* InputBar */,
 				BCB6344D27F6D29500ACFDCF /* KSChatroomTextCell.h */,
 				BCB6345927F6D29600ACFDCF /* KSChatroomTextCell.m */,
-				BCB635AA27F6E06500ACFDCF /* LiveRoomHeadView.h */,
-				BCB635AB27F6E06500ACFDCF /* LiveRoomHeadView.m */,
-				BCB635AC27F6E06500ACFDCF /* LiveRoomHeadView.xib */,
-				BCB635AF27F6E1A600ACFDCF /* LiveRoomBottomView.h */,
-				BCB635B027F6E1A600ACFDCF /* LiveRoomBottomView.m */,
-				BCB635B127F6E1A600ACFDCF /* LiveRoomBottomView.xib */,
 				BCB6345227F6D29500ACFDCF /* LiveRoomLikeLayer.h */,
 				BCB6344427F6D29500ACFDCF /* LiveRoomLikeLayer.m */,
 				BCB6344A27F6D29500ACFDCF /* LiveSeatApplyCell.h */,
@@ -6379,6 +6638,7 @@
 				BC119258280FA85300A716F7 /* HomeworkListCell.xib in Resources */,
 				BC542E5728409EC900633781 /* InstrumentChooseBottonView.xib in Resources */,
 				BC802DAD28BC6EE40079E350 /* HomeHotTalentView.xib in Resources */,
+				BC106C3B2A9338A7000759A9 /* custom_loading.json in Resources */,
 				BCFEED6428F7E4910078A2B7 /* WidgetFunctionView.xib in Resources */,
 				2723B63227F157D500E0B90B /* GroupSettingBodyView.xib in Resources */,
 				BCA1136228A3A2D0007FAFB9 /* bassmidi.txt in Resources */,
@@ -6412,6 +6672,7 @@
 				BC71D24D288804CD0010F14B /* img_12.png in Resources */,
 				BC119275280FB01100A716F7 /* AccompanyHomeworkCell.xib in Resources */,
 				BC71D1022881A2420010F14B /* WeiboSDK.bundle in Resources */,
+				BC106C342A9338A7000759A9 /* TXLiveLoadingView.xib in Resources */,
 				BC71D2872888083B0010F14B /* tabbar3.json in Resources */,
 				BCC583C028A9EC6400BAB4CF /* cloud_animation_15.png in Resources */,
 				BC119280280FB10900A716F7 /* AccompanyRemarkCell.xib in Resources */,
@@ -6439,7 +6700,6 @@
 				BCC0F66F2A8CD8F500C4EFA4 /* TXClassRoomAlertView.xib in Resources */,
 				BC71D26A288804CD0010F14B /* img_19.png in Resources */,
 				BCC0F6032A8CD86C00C4EFA4 /* TX3ASettingView.xib in Resources */,
-				BCB635AE27F6E06500ACFDCF /* LiveRoomHeadView.xib in Resources */,
 				275FA1AD27E734C600CFEA2E /* KSImageAlert.xib in Resources */,
 				BC71D251288804CD0010F14B /* img_17.png in Resources */,
 				BCC0F65E2A8CD8F500C4EFA4 /* TXTimeView.xib in Resources */,
@@ -6469,6 +6729,7 @@
 				BC40BA202812552300DEC0D1 /* KSHomeButton.xib in Resources */,
 				BC7663162827E49900C91A1D /* NotiferHeadView.xib in Resources */,
 				BC802D9928BC4FE90079E350 /* HomeHotMusicView.xib in Resources */,
+				BC106C4C2A933E75000759A9 /* LiveRoomHeadView.xib in Resources */,
 				BCB908F22850B08D00F5FF69 /* ShareMusicCellContentView.xib in Resources */,
 				BCC583CF28A9EC6400BAB4CF /* cloud_animation_1.png in Resources */,
 				2723B5C427F157B100E0B90B /* KSChatListSearchView.xib in Resources */,
@@ -6487,7 +6748,6 @@
 				2723B66327F15CFC00E0B90B /* ModifyNameBodyView.xib in Resources */,
 				BC71D255288804CD0010F14B /* img_5.png in Resources */,
 				BCFEED6728F7E4910078A2B7 /* WidgetBottomButtonView.xib in Resources */,
-				BCB635B327F6E1A600ACFDCF /* LiveRoomBottomView.xib in Resources */,
 				BCB6348327F6D29600ACFDCF /* LiveSeatApplyView.xib in Resources */,
 				BCFDA65328BCA2000022B497 /* accomapny_animation_3.png in Resources */,
 				BC8C2C612823F57100FBA5D5 /* MyAddressListCell.xib in Resources */,
@@ -6554,9 +6814,11 @@
 				BC11926C280FAF5900A716F7 /* AccompanyAlertView.xib in Resources */,
 				BC802DA428BC5F8D0079E350 /* HomeHotMusicCellView.xib in Resources */,
 				BC12639A28FF8E1700509E90 /* HomeNewMusicView.xib in Resources */,
+				BC106C472A933B8B000759A9 /* LiveRoomBottomView.xib in Resources */,
 				2723B66F27F15CFC00E0B90B /* AboutUsBodyView.xib in Resources */,
 				275FA23827E7356B00CFEA2E /* FirstSettingBodyView.xib in Resources */,
 				BC542E622840A60E00633781 /* UseBodyView.xib in Resources */,
+				BC106C422A9339FB000759A9 /* LiveAlertView.xib in Resources */,
 				BCC583B428A9EC6400BAB4CF /* cloud_animation_9.png in Resources */,
 				BCD457AC286469600010B493 /* PublicNoticeView.xib in Resources */,
 				BC71D249288804CD0010F14B /* img_11.png in Resources */,
@@ -6818,7 +7080,9 @@
 				2779352427E324A60010E277 /* KSUtilities.m in Sources */,
 				2779359627E324A80010E277 /* TZVideoCropController.m in Sources */,
 				277935AB27E324A80010E277 /* UIImage+MSSScale.m in Sources */,
+				BC106C192A933829000759A9 /* TXLiveMessageDownSeat.m in Sources */,
 				BCB908E32850B07300F5FF69 /* KSChatLiveMessage.m in Sources */,
+				BC106C122A933829000759A9 /* TXLiveMessagePauseLive.m in Sources */,
 				BCC0F65A2A8CD8F500C4EFA4 /* TxClassroomChatMineCell.m in Sources */,
 				2779353427E324A60010E277 /* UIImageView+CornerRadius.m in Sources */,
 				2779357827E324A70010E277 /* NSString+phone.m in Sources */,
@@ -6845,6 +7109,7 @@
 				BCB6346827F6D29600ACFDCF /* KSLiveChatroomClose.m in Sources */,
 				2779357227E324A70010E277 /* SearchView.m in Sources */,
 				BC8A459C283DC33400094BBB /* KSXMLInfoParse.m in Sources */,
+				BC106C392A9338A7000759A9 /* TXLiveVideoView.m in Sources */,
 				2723B64927F15BDC00E0B90B /* KSJXBodyView.m in Sources */,
 				BC02382228685F4B005560CA /* KSRCPauseLiveMessage.m in Sources */,
 				2779356527E324A70010E277 /* KSMediaManager.m in Sources */,
@@ -6867,6 +7132,7 @@
 				2723B68327F15D3D00E0B90B /* ModifyViewController.m in Sources */,
 				2779356327E324A70010E277 /* HomeButton.m in Sources */,
 				2779358227E324A80010E277 /* NSDate+KSBaseDatePicker.m in Sources */,
+				BC106C062A933829000759A9 /* TXLiveMessageStatSync.m in Sources */,
 				277935CD27E324A90010E277 /* ALCalendarCell.m in Sources */,
 				BC8A45BE283DCADE00094BBB /* NSObject+KeyWindow.m in Sources */,
 				BC43CAC92A88C9570011EB5D /* KSTXGroupChatViewController.m in Sources */,
@@ -6875,6 +7141,7 @@
 				2779358A27E324A80010E277 /* ArchiveTools.m in Sources */,
 				BC0A2268284471460065C1AB /* KSLiveUnBlockUser.m in Sources */,
 				BCC0F6B62A8CDD4000C4EFA4 /* LocalRenderManager.m in Sources */,
+				BC106C042A933829000759A9 /* TXLiveMessageMemberUp.m in Sources */,
 				BCC0F6A92A8CDD4000C4EFA4 /* UIView+MBProgressHUD.m in Sources */,
 				BCC0F6542A8CD8F500C4EFA4 /* TXChatBottomView.m in Sources */,
 				BCB908F12850B08D00F5FF69 /* KSChatMusicShareCell.m in Sources */,
@@ -6882,6 +7149,7 @@
 				BCC0F6122A8CD89400C4EFA4 /* TXClassroomViewController.m in Sources */,
 				BC8A45AA283DC33400094BBB /* TrackChooseView.m in Sources */,
 				BCFEED4D28F7E4720078A2B7 /* SmallToolViewController.m in Sources */,
+				BC106C3A2A9338A7000759A9 /* TXSeatContainerView.m in Sources */,
 				BC8A45B2283DC33400094BBB /* CloudFeedbackView.m in Sources */,
 				BC60E3CD287D552800B05441 /* DeleteAccountBodyView.m in Sources */,
 				BC494A7C286958EC00CCD343 /* MusicRoomCourseInfoCell.m in Sources */,
@@ -6894,6 +7162,7 @@
 				2779352627E324A60010E277 /* UIAlertController+Extend.m in Sources */,
 				BC11925E280FA89A00A716F7 /* HomeworkBodyView.m in Sources */,
 				275FA1EB27E7351900CFEA2E /* KSBaseWKWebViewController.m in Sources */,
+				BC106C232A933869000759A9 /* TXLiveMessageCenter.m in Sources */,
 				BCB909142852EF0000F5FF69 /* KSDragWindow.m in Sources */,
 				BC5F765029001C8D00B433E0 /* HomeDragButton.m in Sources */,
 				BC2888802A8102A20064B773 /* KSChatConversationViewController.m in Sources */,
@@ -6904,6 +7173,7 @@
 				275FA22C27E7356B00CFEA2E /* CourseViewController.m in Sources */,
 				2779358D27E324A80010E277 /* DZNSegmentedControl.m in Sources */,
 				2779352027E324A60010E277 /* CALayer+Color.m in Sources */,
+				BC106C102A933829000759A9 /* TXLiveMessageUnBlockUser.m in Sources */,
 				BCD457A1286313D70010B493 /* NotiferNavView.m in Sources */,
 				2723B62C27F157D500E0B90B /* ApplyBottomView.m in Sources */,
 				BC8A4595283DC33400094BBB /* GCDTimer.m in Sources */,
@@ -6918,7 +7188,6 @@
 				277935B927E324A90010E277 /* FSCalendarCollectionViewLayout.m in Sources */,
 				BC8B6DC32856CAE500866917 /* KSICloudManager.m in Sources */,
 				2779359427E324A80010E277 /* TZAssetCell.m in Sources */,
-				BCB635B227F6E1A600ACFDCF /* LiveRoomBottomView.m in Sources */,
 				BCFEED5E28F7E4910078A2B7 /* WidgetFunctionView.m in Sources */,
 				2723B5CE27F157BE00E0B90B /* KSRCloudMediaManager.m in Sources */,
 				BC02381428685064005560CA /* KSLiveEndView.m in Sources */,
@@ -6953,18 +7222,21 @@
 				2779351E27E324A60010E277 /* UIViewController+zhStatusBarStyle.m in Sources */,
 				2779356B27E324A70010E277 /* pickBut.m in Sources */,
 				2779355F27E324A70010E277 /* UIView+ValueAdd.m in Sources */,
+				BC106C0A2A933829000759A9 /* TXLiveMessageDownSeatAll.m in Sources */,
 				275FA1E227E7351900CFEA2E /* KSWebBackButton.m in Sources */,
 				277935BF27E324A90010E277 /* FSCalendarHeaderView.m in Sources */,
 				275FA1AE27E734C600CFEA2E /* KSImageAlert.m in Sources */,
 				BC2888582A80F7BF0064B773 /* KSLoginManager.m in Sources */,
 				BCC0F60D2A8CD86C00C4EFA4 /* TXDeviceControlNotiferMsg.m in Sources */,
 				275FA1DE27E7351900CFEA2E /* KSLocalWebViewController.m in Sources */,
+				BC106C092A933829000759A9 /* TXLiveMessageUserQuit.m in Sources */,
 				BCC0F66D2A8CD8F500C4EFA4 /* ClassRoomTitleButton.m in Sources */,
 				2779354227E324A60010E277 /* UIImage+ResizeImage.m in Sources */,
 				277935B327E324A90010E277 /* FSCalendarCollectionView.m in Sources */,
 				2779352727E324A60010E277 /* NSArray+zh_SafeAccess.m in Sources */,
 				BCB9FA46286EDCD7005D766B /* KSTipsAlert.m in Sources */,
 				2779352227E324A60010E277 /* UITextView+ZWLimitCounter.m in Sources */,
+				BC106C222A933869000759A9 /* TXLiveMessageModel.m in Sources */,
 				27F9032927E87C2E00C08A19 /* NetworkingCheckController.m in Sources */,
 				BCFE53EC2812897600AD6786 /* HomeLiveCouseCell.m in Sources */,
 				277935A527E324A80010E277 /* MSSBrowseLoadingImageView.m in Sources */,
@@ -6973,6 +7245,7 @@
 				2723B5C027F157B100E0B90B /* ChatAddressHeaderView.m in Sources */,
 				2723B68127F15D3D00E0B90B /* ModifyNameViewController.m in Sources */,
 				BCC0F66E2A8CD8F500C4EFA4 /* TXClassRoomAlertView.m in Sources */,
+				BC106C022A933829000759A9 /* TXLiveUser.m in Sources */,
 				2779359927E324A80010E277 /* NSBundle+TZImagePicker.m in Sources */,
 				2779358E27E324A80010E277 /* WMPlayerModel.m in Sources */,
 				2779354E27E324A70010E277 /* KSAudioSessionManager.m in Sources */,
@@ -6998,9 +7271,11 @@
 				BC3A4EB428DAE202001C4428 /* UIImage+KSScreenShot.m in Sources */,
 				BC11927A280FB07F00A716F7 /* AccompanyArrangeCell.m in Sources */,
 				277935B827E324A90010E277 /* FSCalendar.m in Sources */,
+				BC106C4D2A933E75000759A9 /* LiveRoomHeadView.m in Sources */,
 				BCD9295E28F9447B006793E4 /* WMGaugeViewStyle3D.m in Sources */,
 				275FA23527E7356B00CFEA2E /* UserInfoManager.m in Sources */,
 				2779353327E324A60010E277 /* UIScreen+Extend.m in Sources */,
+				BC106C132A933829000759A9 /* TXControlMemberMic.m in Sources */,
 				BC8A45AE283DC33400094BBB /* SoundCheckView.m in Sources */,
 				BC71D13A2887CEB70010F14B /* LaunchAnimationViewController.m in Sources */,
 				2723B67E27F15D3D00E0B90B /* ModifyPhoneCheckController.m in Sources */,
@@ -7016,6 +7291,7 @@
 				2779357A27E324A70010E277 /* PIckView.m in Sources */,
 				BC119234280ED97C00A716F7 /* CourseForLiveCell.m in Sources */,
 				BCB6346027F6D29600ACFDCF /* KSLiveChatroomKickOut.m in Sources */,
+				BC106C382A9338A7000759A9 /* LiveRoomConfirmAlert.m in Sources */,
 				2779354127E324A60010E277 /* UIView+ShowProgress.m in Sources */,
 				BCFE53E72812765600AD6786 /* HomeHotAlbumCell.m in Sources */,
 				BC8A459B283DC33400094BBB /* CloudSongMessageModel.m in Sources */,
@@ -7026,6 +7302,7 @@
 				277935B427E324A90010E277 /* FSCalendarDelegationProxy.m in Sources */,
 				BCC0F6CA2A8CDDFE00C4EFA4 /* ClassroomService.m in Sources */,
 				BCC0F6C52A8CDDEB00C4EFA4 /* Classroom.m in Sources */,
+				BC106C502A9351DA000759A9 /* LiveModuleService.m in Sources */,
 				2723B5BB27F157B100E0B90B /* ChatAddressBodyView.m in Sources */,
 				2779357427E324A70010E277 /* StoreButton.m in Sources */,
 				BC71D27F288807680010F14B /* AnimationHelper.m in Sources */,
@@ -7034,6 +7311,7 @@
 				BC8B641528F3B5AC00A08D16 /* KSAwardAlertView.m in Sources */,
 				BCC0F6092A8CD86C00C4EFA4 /* TXClassroomDeviceMsg.m in Sources */,
 				BCC0F6602A8CD8F500C4EFA4 /* MainDisplayView.m in Sources */,
+				BC106BC52A9336F8000759A9 /* TXLiveRoomViewController.m in Sources */,
 				2779355627E324A70010E277 /* KSPremissionAlert.m in Sources */,
 				BC736A92288036E8004A9B0A /* MyVideoSearchView.m in Sources */,
 				BC119230280ED8F900A716F7 /* TableCourseModel.m in Sources */,
@@ -7064,6 +7342,7 @@
 				2779357727E324A70010E277 /* GRScanManager.m in Sources */,
 				277935D527E324A90010E277 /* ALCalendarManager.m in Sources */,
 				BC02130127FC6ADD0040569F /* UIView+SubViewExtension.m in Sources */,
+				BC106C162A933829000759A9 /* TXLiveTextMessage.m in Sources */,
 				BC11924E280EDD5500A716F7 /* HomeworkListViewController.m in Sources */,
 				2779351927E324A60010E277 /* NSMutableString+KSSafe.m in Sources */,
 				2723B5BC27F157B100E0B90B /* GroupCreateView.m in Sources */,
@@ -7073,11 +7352,14 @@
 				2779352327E324A60010E277 /* UILabel+Extension.m in Sources */,
 				BC802D8D28B896460079E350 /* LiveApplyView.m in Sources */,
 				2723B63027F157D500E0B90B /* GroupApplyChooseAllCell.m in Sources */,
+				BC106C372A9338A7000759A9 /* TXLiveChatListCell.m in Sources */,
+				BC106C242A933869000759A9 /* TXTestGenerateUserSig.m in Sources */,
 				2723B61F27F157D500E0B90B /* GroupNoticeModel.m in Sources */,
 				275FA1E627E7351900CFEA2E /* KSUpdateAlert.m in Sources */,
 				2779355027E324A70010E277 /* VoDiskCache.m in Sources */,
 				BCFEED6228F7E4910078A2B7 /* WidgetDotView.m in Sources */,
 				BCC0F6ED2A8CE4AF00C4EFA4 /* ZoomControl.m in Sources */,
+				BC106C032A933829000759A9 /* TXLiveMessageOpenLive.m in Sources */,
 				2779353927E324A60010E277 /* UIView+XIBView.m in Sources */,
 				2779355827E324A70010E277 /* UIImage+Addtions.m in Sources */,
 				BC2888592A80F7BF0064B773 /* TXIMLinsenter.m in Sources */,
@@ -7086,6 +7368,7 @@
 				275FA23C27E7356B00CFEA2E /* VefiBodyView.m in Sources */,
 				2779358027E324A80010E277 /* sortButton.m in Sources */,
 				BCED5CA7284F55A0009A42DE /* FriendListModel.m in Sources */,
+				BC106C012A933829000759A9 /* TXLiveMessageBlockUser.m in Sources */,
 				2779356027E324A70010E277 /* KSRecordStatusView.m in Sources */,
 				2723B62B27F157D500E0B90B /* ApplyMemberModel.m in Sources */,
 				BCD457AB286469600010B493 /* PublicNoticeView.m in Sources */,
@@ -7095,9 +7378,11 @@
 				275FA22F27E7356B00CFEA2E /* ShopMallViewController.m in Sources */,
 				BCB6347227F6D29600ACFDCF /* KSChatInputView.m in Sources */,
 				275E8AAA27E18F8800DD3F6E /* AppDelegate.m in Sources */,
+				BC106C172A933829000759A9 /* TXLiveMessageRejectAllSeat.m in Sources */,
 				BC2DFF4B28BDFE740056105A /* HomeTeacherLiveModel.m in Sources */,
 				2779356427E324A70010E277 /* KSFullDatePicker.m in Sources */,
 				BC0D1F6D281013DF00C5D9E5 /* MyVideoCourseBodyView.m in Sources */,
+				BC106C002A933829000759A9 /* TXLiveMessageLike.m in Sources */,
 				2723B5CF27F157BE00E0B90B /* GroupMemberModel.m in Sources */,
 				2723B62A27F157D500E0B90B /* GroupSettingViewController.m in Sources */,
 				2779359127E324A80010E277 /* FastForwardView.m in Sources */,
@@ -7152,12 +7437,14 @@
 				277935B227E324A90010E277 /* UIView+MSSLayout.m in Sources */,
 				BCFDA61228BC8FCE0022B497 /* HomeHotVideoCell.m in Sources */,
 				275FA1E427E7351900CFEA2E /* KSWebNavView.m in Sources */,
+				BC106C182A933829000759A9 /* TXLiveMessageShopRush.m in Sources */,
 				BC756CB928FE7D1D00AA9ECB /* KSChatUserDetailViewController.m in Sources */,
 				BC43CACA2A88C9570011EB5D /* KSTXC2CChatViewController.m in Sources */,
 				2779356D27E324A70010E277 /* StoreShopCaterview.m in Sources */,
 				BC119267280FA92700A716F7 /* HomeworkDetailViewController.m in Sources */,
 				BCB6346127F6D29600ACFDCF /* KSChatroomMessageCenter.m in Sources */,
 				BC60E3CC287D552800B05441 /* AccountDeleteViewController.m in Sources */,
+				BC106BFE2A933829000759A9 /* TXMicStatusSync.m in Sources */,
 				BC11925B280FA85300A716F7 /* HomeworkSortView.m in Sources */,
 				277935D327E324A90010E277 /* ALCalendarPicker.m in Sources */,
 				BCC0F6572A8CD8F500C4EFA4 /* TxClassroomChatOtherCell.m in Sources */,
@@ -7170,9 +7457,11 @@
 				BCB6345E27F6D29600ACFDCF /* KSLiveChatroomLeave.m in Sources */,
 				BC11929B280FD2E800A716F7 /* HomeworkBottomView.m in Sources */,
 				BC494A77286952B500CCD343 /* MusicRoomDetailViewController.m in Sources */,
+				BC106C0E2A933829000759A9 /* TXLiveMessageChatBan.m in Sources */,
 				BC8C2C602823F57100FBA5D5 /* AddressBottomView.m in Sources */,
 				BCC0F6B42A8CDD4000C4EFA4 /* KSRemoteUserManager.m in Sources */,
 				275FA1E727E7351900CFEA2E /* KSWebSocketManager.m in Sources */,
+				BC106C072A933829000759A9 /* TXLiveMessageLikeCount.m in Sources */,
 				277935AE27E324A80010E277 /* MSSBrowseRemindView.m in Sources */,
 				BCBFDF46281159990052AFE5 /* HomeHotAlbumView.m in Sources */,
 				2779356A27E324A70010E277 /* YKNodeModel.m in Sources */,
@@ -7180,6 +7469,7 @@
 				277935CE27E324A90010E277 /* ALCalendarConfig.m in Sources */,
 				2779354327E324A60010E277 /* UIButton+HasChooseImage.m in Sources */,
 				2779355927E324A70010E277 /* GRCreateManager.m in Sources */,
+				BC106C052A933829000759A9 /* TXLiveMessageKickOut.m in Sources */,
 				277935A727E324A80010E277 /* MSSBrowseCollectionViewCell.m in Sources */,
 				BCB6346727F6D29600ACFDCF /* KSLiveChatroomMemberCount.m in Sources */,
 				277935AD27E324A80010E277 /* MSSBrowseZoomScrollView.m in Sources */,
@@ -7188,6 +7478,7 @@
 				2723B68227F15D3D00E0B90B /* ModifyPhoneChangeController.m in Sources */,
 				BC5367C2283F6D4D008428E8 /* HomeLiveCourseView.m in Sources */,
 				BCC0F6E12A8CE24400C4EFA4 /* KSWhiteboardView.m in Sources */,
+				BC106C432A9339FB000759A9 /* LiveAlertView.m in Sources */,
 				BC40BA1F2812552300DEC0D1 /* KSHomeButton.m in Sources */,
 				277935C827E324A90010E277 /* TADotView.m in Sources */,
 				BC1191FF280ED64E00A716F7 /* MyCourseViewController.m in Sources */,
@@ -7195,10 +7486,12 @@
 				BCB635A927F6D93300ACFDCF /* KSChatVideoView.m in Sources */,
 				2779353027E324A60010E277 /* NSDate+Extension.m in Sources */,
 				BC542E5628409EC900633781 /* InstrumentChooseBottonView.m in Sources */,
+				BC106C082A933829000759A9 /* TXLiveMessageEnter.m in Sources */,
 				BCBFDF3728110C660052AFE5 /* HomeNavView.m in Sources */,
 				277935D127E324A90010E277 /* ALCalendarCollectionView.m in Sources */,
 				BC76630E2827E48800C91A1D /* NotiferMessageModel.m in Sources */,
 				BCFE5406281545C600AD6786 /* HomeAlbumModel.m in Sources */,
+				BC106C352A9338A7000759A9 /* TXUISeatMember.m in Sources */,
 				2779355427E324A70010E277 /* VoNetWorking.m in Sources */,
 				275FA1EE27E7351900CFEA2E /* KSBaseViewController.m in Sources */,
 				2723B63827F157D500E0B90B /* GroupApplyChooseCell.m in Sources */,
@@ -7209,7 +7502,9 @@
 				BCB6346327F6D29600ACFDCF /* KSRCMessageModel.m in Sources */,
 				277935A427E324A80010E277 /* TZImageRequestOperation.m in Sources */,
 				275FA23627E7356B00CFEA2E /* LoginBodyView.m in Sources */,
+				BC106C152A933829000759A9 /* TXLiveMessageWelcome.m in Sources */,
 				BCC0F6562A8CD8F500C4EFA4 /* TXChatAreaTopView.m in Sources */,
+				BC106C0C2A933829000759A9 /* TXLiveMessageSeatControl.m in Sources */,
 				BC49BAEC28D98C500031FF06 /* KSMetronomePlayer.m in Sources */,
 				BCD959C928DB071B00B70314 /* MusicTagView.m in Sources */,
 				2779355A27E324A70010E277 /* QCCountdownButton.m in Sources */,
@@ -7224,6 +7519,7 @@
 				275FA1DF27E7351900CFEA2E /* RCConnectionManager.m in Sources */,
 				BCD9295D28F9447B006793E4 /* WMGaugeViewStyleFlatThin.m in Sources */,
 				275FA22B27E7356B00CFEA2E /* HomeViewController.m in Sources */,
+				BC106C362A9338A7000759A9 /* TXLiveLoadingView.m in Sources */,
 				BC2888762A8101C80064B773 /* KSChatSearchBar.m in Sources */,
 				BCFE53F12812898700AD6786 /* HomeVideoCourseCell.m in Sources */,
 				BCC0F6B52A8CDD4000C4EFA4 /* OnlineClassManager.m in Sources */,
@@ -7282,6 +7578,7 @@
 				BCC0F6AA2A8CDD4000C4EFA4 /* RolePortraitView.m in Sources */,
 				BCC0F6682A8CD8F500C4EFA4 /* KSDanInputBarControl.m in Sources */,
 				2779358827E324A80010E277 /* NSObject+Archiving.m in Sources */,
+				BC106C3E2A9338F6000759A9 /* TXLiveForceKickMsg.m in Sources */,
 				2779354427E324A60010E277 /* NSObject+AutoProperty.m in Sources */,
 				BC12639528FF8D2300509E90 /* HomeMusicModel.m in Sources */,
 				BCFDA62428BC94400022B497 /* HomeNavSearchView.m in Sources */,
@@ -7315,6 +7612,7 @@
 				BCC0F66A2A8CD8F500C4EFA4 /* TXDanMuView.m in Sources */,
 				BC28885C2A80F9880064B773 /* AppDelegate+AppService.m in Sources */,
 				2779357C27E324A70010E277 /* NSString+MD5.m in Sources */,
+				BC106C112A933829000759A9 /* TXConstMessage.m in Sources */,
 				2779355D27E324A70010E277 /* KSHoldButton.m in Sources */,
 				2723B62027F157D500E0B90B /* GroupNoticeCell.m in Sources */,
 				277935A627E324A80010E277 /* MSSBrowseLocalViewController.m in Sources */,
@@ -7336,6 +7634,7 @@
 				277935C227E324A90010E277 /* QWdynamicModel.m in Sources */,
 				2779357E27E324A80010E277 /* KSInputView.m in Sources */,
 				2723B63427F157D500E0B90B /* GroupApplyMemberCell.m in Sources */,
+				BC106C0F2A933829000759A9 /* TXLiveMessageSeatApply.m in Sources */,
 				BCC0F6082A8CD86C00C4EFA4 /* TXClassroomTextMsg.m in Sources */,
 				BC5082B4283345A10031DD0A /* KSChatListCell.m in Sources */,
 				BCB6345D27F6D29600ACFDCF /* KSLiveChatroomWelcome.m in Sources */,
@@ -7343,11 +7642,13 @@
 				2779352927E324A60010E277 /* zhPopupController.m in Sources */,
 				BC12636728FEA01F00509E90 /* RecentPracticeModel.m in Sources */,
 				BC2888772A8101C80064B773 /* KSSearchViewController.m in Sources */,
+				BC106C252A933869000759A9 /* TXLiveURLUtils.m in Sources */,
 				2779359527E324A80010E277 /* TZVideoEditedPreviewController.m in Sources */,
 				BCC0F6C42A8CDDEB00C4EFA4 /* ClassSongMessage.m in Sources */,
 				2723B63127F157D500E0B90B /* GroupSettingBodyView.m in Sources */,
 				BC119290280FB46100A716F7 /* KSVideoHelper.m in Sources */,
 				2779358327E324A80010E277 /* LLPhotoBrowser.m in Sources */,
+				BC106C482A933B8B000759A9 /* LiveRoomBottomView.m in Sources */,
 				275FA23027E7356B00CFEA2E /* PasswordLoginController.m in Sources */,
 				BCD457AF28646B580010B493 /* NoticeSourceModel.m in Sources */,
 				BCC0F60A2A8CD86C00C4EFA4 /* TXClassroomUserInfo.m in Sources */,
@@ -7383,6 +7684,7 @@
 				277935C427E324A90010E277 /* SDCycleScrollView.m in Sources */,
 				BC119293280FBC1100A716F7 /* HomeworkAddView.m in Sources */,
 				BC4CC417288FD689004AD8EC /* LaunchAnimationView.m in Sources */,
+				BC106BFF2A933829000759A9 /* TXLiveMessageCardMessage.m in Sources */,
 				277935C627E324A90010E277 /* SDQWMaskCustomModel.m in Sources */,
 				BC3A4EAB28DAC0CD001C4428 /* ShareLiveDisplayView.m in Sources */,
 				BCC0F6A42A8CDD3F00C4EFA4 /* InputView.m in Sources */,
@@ -7402,11 +7704,11 @@
 				BCC0F6E92A8CE37E00C4EFA4 /* VideoMaskView.m in Sources */,
 				2779353C27E324A60010E277 /* UIButton+Property.m in Sources */,
 				BCFE53FF2814E1BE00AD6786 /* HomeLiveGroupModel.m in Sources */,
+				BC106C0B2A933829000759A9 /* TXLiveMessageLeave.m in Sources */,
 				277935CC27E324A90010E277 /* SDQWMaskCustomView.m in Sources */,
 				2779351727E324A60010E277 /* NSObject+KSSwizzling.m in Sources */,
 				2779352C27E324A60010E277 /* UIView+AddConstraints.m in Sources */,
 				277935C927E324A90010E277 /* TAPageControl.m in Sources */,
-				BCB635AD27F6E06500ACFDCF /* LiveRoomHeadView.m in Sources */,
 				2723B5A527F1578300E0B90B /* ChatAddressViewController.m in Sources */,
 				2723B66627F15CFC00E0B90B /* AboutUsBodyView.m in Sources */,
 				277935BC27E324A90010E277 /* FSCalendarExtensions.m in Sources */,
@@ -7416,6 +7718,7 @@
 				2779355527E324A70010E277 /* DiskFreeSpaceManager.m in Sources */,
 				BCC0F65D2A8CD8F500C4EFA4 /* TXClassroomMainContainer.m in Sources */,
 				2779352E27E324A60010E277 /* NSDictionary+Extension.m in Sources */,
+				BC106C0D2A933829000759A9 /* TXLiveMessageClose.m in Sources */,
 				BC542E3B284079D600633781 /* UserAuthViewController.m in Sources */,
 				2779355127E324A70010E277 /* VoCacheManager.m in Sources */,
 				BC8A4594283DC33400094BBB /* MidiPlayerEngine.m in Sources */,
@@ -7427,6 +7730,7 @@
 				2723B66927F15CFC00E0B90B /* PhoneChangeBodyView.m in Sources */,
 				BC12636428FE930C00509E90 /* ChatUserInfo.m in Sources */,
 				27F9033227E87C2E00C08A19 /* SettingViewController.m in Sources */,
+				BC106C142A933829000759A9 /* TXLiveMessageSeatResponse.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -7647,7 +7951,7 @@
 				INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
 				INFOPLIST_KEY_UIMainStoryboardFile = Main;
 				INFOPLIST_KEY_UIRequiresFullScreen = YES;
-				INFOPLIST_KEY_UIStatusBarStyle = "";
+				INFOPLIST_KEY_UIStatusBarStyle = UIStatusBarStyleDarkContent;
 				INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
 				INFOPLIST_KEY_UISupportsDocumentBrowser = YES;
 				INFOPLIST_KEY_UIUserInterfaceStyle = Light;
@@ -7726,7 +8030,7 @@
 				INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
 				INFOPLIST_KEY_UIMainStoryboardFile = Main;
 				INFOPLIST_KEY_UIRequiresFullScreen = YES;
-				INFOPLIST_KEY_UIStatusBarStyle = "";
+				INFOPLIST_KEY_UIStatusBarStyle = UIStatusBarStyleDarkContent;
 				INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
 				INFOPLIST_KEY_UISupportsDocumentBrowser = YES;
 				INFOPLIST_KEY_UIUserInterfaceStyle = Light;

+ 10 - 2
KulexiuForStudent/KulexiuForStudent/AppDelegate.m

@@ -39,7 +39,9 @@
 #import <TUICore/TUIConfig.h>
 #import <TUIChat/TUIChat.h>
 
-@interface AppDelegate ()<WXApiDelegate,JPUSHRegisterDelegate>
+@import TXLiteAVSDK_Professional;
+
+@interface AppDelegate ()<WXApiDelegate,JPUSHRegisterDelegate,V2TXLivePremierObserver>
 
 @property (nonatomic, assign) BOOL isNeedUpdate;
 
@@ -78,6 +80,7 @@
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     // Override point for customization after application launch.
     [self networkEnableCheck];
+    [self initTXRTCConfig];
     [self registerSDK];
     [Bugly startWithAppId:@"adfcb3bc3d"];
     
@@ -88,7 +91,7 @@
         [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
     }
     
-    [[UITabBar appearance] setTranslucent:NO];
+//    [[UITabBar appearance] setTranslucent:NO];
     // 全局配置光标颜色
     [[UITextField appearance] setTintColor:THEMECOLOR];
     [[UITextView appearance] setTintColor:THEMECOLOR];
@@ -268,6 +271,11 @@
             advertisingIdentifier:nil];
 }
 
+- (void)initTXRTCConfig {
+    [V2TXLivePremier setLicence:CONFIG_TXLiveLicenceURL key:CONFIG_TXLiveLicenceKey];
+    [V2TXLivePremier setObserver:self];
+    NSLog(@"SDK Version = %@", [V2TXLivePremier getSDKVersionStr]);
+}
 
 - (void)configTXIM {
     TUIConfig *config = [TUIConfig defaultConfig];

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/classroom_quit.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/classroom_quit.imageset/classroom_quit@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/classroom_quit.imageset/classroom_quit@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_off.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_off.imageset/liveVoice_off@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_off.imageset/liveVoice_off@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_on.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_on.imageset/liveVoice_on@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/liveVoice_on.imageset/liveVoice_on@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOff.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOff.imageset/live_student_micOff@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOff.imageset/live_student_micOff@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOn.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOn.imageset/live_student_micOn@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/live_student_micOn.imageset/live_student_micOn@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connected.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connected.imageset/seat_connected@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connected.imageset/seat_connected@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connecting.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connecting.imageset/seat_connecting@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_connecting.imageset/seat_connecting@3x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_image.imageset/seat_image@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/seat_image.imageset/seat_image@3x.png


+ 5 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.h

@@ -27,6 +27,11 @@ NS_ASSUME_NONNULL_BEGIN
 // 返回到登录页面
 + (void)backLoginView;
 
+#pragma mark -------- CLASS REQUEST
++ (void)classroomRequest:(NSString *)method url:(NSString *)url parms:(NSDictionary *)parms success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+#pragma mark -------- LIVE ROOM
++ (void)LiveRoomRequest:(NSString *)method url:(NSString *)url parms:(NSDictionary *)parms success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
 #pragma mark ----- version
 // api-admin/appVersionInfo/queryByPlatform
 + (void)appVersionInfoRequest:(NSString *)get success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;

+ 16 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.m

@@ -292,6 +292,22 @@
     }];
 }
 
+#pragma mark -------- CLASS REQUEST
++ (void)classroomRequest:(NSString *)method url:(NSString *)url parms:(NSDictionary *)parms success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    if ([method isEqualToString:KS_POST]) {
+        [self configRequestMethodJSON];
+    }
+    [self request:method andWithUrl:url and:parms success:success faliure:faliure];
+}
+
+#pragma mark -------- LIVE ROOM
++ (void)LiveRoomRequest:(NSString *)method url:(NSString *)url parms:(NSDictionary *)parms success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    if ([method isEqualToString:KS_POST]) {
+        [self configRequestMethodJSON];
+    }
+    [self request:method andWithUrl:url and:parms success:success faliure:faliure];
+}
+
 #pragma mark ----- version
 // api-admin/appVersionInfo/queryByPlatform
 + (void)appVersionInfoRequest:(NSString *)get success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {

+ 1 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/KSTabBarViewController.m

@@ -52,6 +52,7 @@
         [UITabBar appearance].standardAppearance = appearance;
     }
     [UITabBar appearance].backgroundColor = UIColor.whiteColor;
+    self.tabBar.translucent = NO;
 }
 
 - (void)removeControllerNotifer {

+ 1 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/LoginManger/KSLoginManager.m

@@ -50,6 +50,7 @@
     [USER_MANAGER stopCountUMEvent];
 }
 - (void)logoutAction {
+    [[NSNotificationCenter defaultCenter] postNotificationName:@"refreshLiveClickStatus" object:nil];
     [self clearUMCount];
     [KSNetworkingManager clearRequestHeader];
     

+ 9 - 7
KulexiuForStudent/KulexiuForStudent/Common/Base/LoginManger/TXIMLinsenter.m

@@ -9,6 +9,7 @@
 #import "KSTabBarViewController.h"
 #import "AppDelegate+AppService.h"
 #import "ClassroomService.h"
+#import "TXLiveTextMessage.h"
 
 @interface TXIMLinsenter ()<TUILoginListener,V2TIMConversationListener,V2TIMSimpleMsgListener,V2TIMSignalingListener,V2TIMGroupListener>
 
@@ -29,6 +30,7 @@
 
 - (void)TXIMLoginWithUserId:(NSString *)userId sig:(NSString *)userSig callback:(TXIMLoginCallback)callback {
     [TUILogin addLoginListener:self];
+    [[V2TIMManager sharedInstance] addConversationListener:self];
     [[V2TIMManager sharedInstance] addSimpleMsgListener:self];
     [[V2TIMManager sharedInstance] addGroupListener:self];
     [TUILogin login:CONFIG_TXSDKAPPID userID:userId userSig:userSig succ:^{
@@ -128,17 +130,17 @@
 - (void)onRecvGroupTextMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info text:(NSString *)text {
     // 收到群组文本消息
     if ([groupID containsString:@"LIVE"]) { // 判断是否是直播群消息
-//        TXLiveTextMessage *message = [[TXLiveTextMessage alloc] init];
-//        message.messageId = msgID;
-//        message.groupId = groupID;
-//        [[NSNotificationCenter defaultCenter] postNotificationName:OnReceiveTXLiveMessageNotification object:@{@"message":message}];
+        TXLiveTextMessage *message = [[TXLiveTextMessage alloc] init];
+        message.messageId = msgID;
+        message.groupId = groupID;
+        [[NSNotificationCenter defaultCenter] postNotificationName:OnReceiveTXLiveMessageNotification object:@{@"message":message}];
     }
 }
 
 - (void)onRecvGroupCustomMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info customData:(NSData *)data {
     // 收到自定义群组消息
     if ([groupID containsString:@"LIVE"]) { // 判断是否是直播群消息
-//        [[NSNotificationCenter defaultCenter] postNotificationName:OnReceiveTXLiveMessageNotification object:@{@"message":[data mj_JSONObject],@"msgID" : msgID, @"groupID" : groupID}];
+        [[NSNotificationCenter defaultCenter] postNotificationName:OnReceiveTXLiveMessageNotification object:@{@"message":[data mj_JSONObject],@"msgID" : msgID, @"groupID" : groupID}];
     }
     else {
         NSDictionary *receiveMsg = @{@"message":[data mj_JSONObject],@"msgID" : msgID, @"groupID" : groupID};
@@ -153,7 +155,7 @@
 - (void)onGroupAttributeChanged:(NSString *)groupID attributes:(NSMutableDictionary<NSString *,NSString *> *)attributes {
     // 收到自定义群组消息
     if ([groupID containsString:@"LIVE"]) { // 判断是否是直播群消息
-//        [[NSNotificationCenter defaultCenter] postNotificationName:OnReceiveTXLiveGroupNotification object:@{@"message":attributes, @"groupID" : groupID}];
+        [[NSNotificationCenter defaultCenter] postNotificationName:OnReceiveTXLiveGroupNotification object:@{@"message":attributes, @"groupID" : groupID}];
     }
     else {
         [[NSNotificationCenter defaultCenter] postNotificationName:OnReceiveTXClassroomGroupNotification object:@{@"message":attributes, @"groupID" : groupID}];
@@ -163,7 +165,7 @@
 - (void)onGroupCounterChanged:(NSString *)groupID key:(NSString *)key newValue:(NSInteger)newValue {
     // 收到自定义群组消息
     if ([groupID containsString:@"LIVE"]) { // 判断是否是直播群消息
-//        [[NSNotificationCenter defaultCenter] postNotificationName:OnReceiveTXLiveGroupCountNotification object:@{@"message":@{key:@(newValue)}, @"groupID" : groupID}];
+        [[NSNotificationCenter defaultCenter] postNotificationName:OnReceiveTXLiveGroupCountNotification object:@{@"message":@{key:@(newValue)}, @"groupID" : groupID}];
     }
 }
 

+ 3 - 0
KulexiuForStudent/KulexiuForStudent/Common/Define/KSDomain.h

@@ -8,6 +8,9 @@
 #ifndef KSDomain_h
 #define KSDomain_h
 
+#define CONFIG_TXLiveLicenceURL (@"https://license.vod2.myqcloud.com/license/v2/1303457149_1/v_cube.license")
+#define CONFIG_TXLiveLicenceKey (@"874d35d907c1d92a7557a4216d59c233")
+
 //#ifdef DEBUG
 
 #define hostURL (@"https://dev.colexiu.com")

+ 0 - 1
KulexiuForStudent/KulexiuForStudent/Module/Chat/Controller/ChatViewController.m

@@ -97,7 +97,6 @@
 
 - (void)viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];
-    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
     // 处于第一个item的时候,才允许屏幕边缘手势返回
     self.navigationController.interactivePopGestureRecognizer.enabled = (self.categoryView.selectedIndex == 0);
 }

+ 2 - 1
KulexiuForStudent/KulexiuForStudent/Module/Chat/Group/Controller/GroupSettingViewController.m

@@ -78,11 +78,12 @@
         if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
             NSDictionary *subDic = [dic ks_dictionaryValueForKey:@"data"];
             self.sourceModel = [[GroupListModel alloc] initWithDictionary:subDic];
-            [self refreshUI];
         }
         else {
             [self MBPShow:MESSAGEKEY];
         }
+        [self refreshUI];
+        
     } faliure:^(NSError * _Nonnull error) {
         
     }];

+ 23 - 19
KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m

@@ -431,12 +431,12 @@ static int clickPraiseBtnTimes  = 0;
     resetBottomTapGesture.delegate = self;
     [self.view addGestureRecognizer:resetBottomTapGesture];
     
-    if (self.isTempRoom) {
-        self.bottomView.hideShareButton = NO;
-    }
-    else {
-        self.bottomView.hideShareButton = YES;
-    }
+//    if (self.isTempRoom) {
+//        self.bottomView.hideShareButton = NO;
+//    }
+//    else {
+//        self.bottomView.hideShareButton = YES;
+//    }
 }
 
 - (void)connectService {
@@ -1910,14 +1910,18 @@ static int clickPraiseBtnTimes  = 0;
     if (!_headView) {
         _headView = [LiveRoomHeadView shareInstance];
         MJWeakSelf;
-        [_headView quitAction:^(BOOL isQuit) {
-            if (isQuit) {
-                [weakSelf showQuitAlert];
-            }
-            else {
-                [weakSelf displayTeacherInfo:CART_TYPE_NONE];
-            }
+        [_headView quitAction:^{
+            [weakSelf showQuitAlert];
+
         }];
+//        [_headView quitAction:^(BOOL isQuit) {
+//            if (isQuit) {
+//                [weakSelf showQuitAlert];
+//            }
+//            else {
+//                [weakSelf displayTeacherInfo:CART_TYPE_NONE];
+//            }
+//        }];
 
     }
     return _headView;
@@ -2028,11 +2032,11 @@ static int clickPraiseBtnTimes  = 0;
             }
         }
             break;
-        case LIVEROOMACTION_SHARE:
-        {
-            [self showShareAlert];
-        }
-            break;
+//        case LIVEROOMACTION_SHARE:
+//        {
+//            [self showShareAlert];
+//        }
+//            break;
         default:
             break;
     }
@@ -2300,7 +2304,7 @@ static int clickPraiseBtnTimes  = 0;
     if (videoView) {
         _hasShowSuspendView = YES;
         KSDragWindowManager *manager = [KSDragWindowManager sharedManager];
-        [manager initDragWindow];
+        [manager initDragWindowWithPhoneLive:YES];
         manager.rootVC = (CustomNavViewController *)self.navigationController;
         
         [videoView removeFromSuperview];

+ 2 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/Model/KSEnterLiveroomManager.h

@@ -15,6 +15,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 + (void)joinLiveWithRoomId:(NSString *)roomId inController:(CustomNavViewController *)navCtrl callback:(EnterCallback)callback;
 
++ (void)refreshClickStatus;
+
 @end
 
 NS_ASSUME_NONNULL_END

+ 49 - 21
KulexiuForStudent/KulexiuForStudent/Module/Live/Model/KSEnterLiveroomManager.m

@@ -6,14 +6,20 @@
 //
 
 #import "KSEnterLiveroomManager.h"
-#import "LiveVideoRoomViewController.h"
+#import "TXLiveRoomViewController.h"
+#import "LiveModuleService.h"
+
+// 用于记录防止重复点击的进入多个直播
+static BOOL isRequestRoomMsg  = NO;
 
 @implementation KSEnterLiveroomManager
 
 + (void)joinLiveWithRoomId:(NSString *)roomId inController:(CustomNavViewController *)navCtrl callback:(EnterCallback)callback {
-    [KSNetworkingManager liveRoomJoinRoomRequest:KS_GET roomUid:roomId success:^(NSDictionary * _Nonnull dic) {
-        callback();
-        
+    if (isRequestRoomMsg == YES) {
+        return;
+    }
+    [LiveModuleService imLiveBroadcastRoomQueryRoomRequest:KS_GET roomId:roomId success:^(NSDictionary * _Nonnull dic) {
+        isRequestRoomMsg = NO;
         if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
             [self joinRoomWithMessage:[dic ks_dictionaryValueForKey:@"data"] controller:navCtrl];
         }
@@ -21,35 +27,54 @@
             [self MBShowInWindow:MESSAGEKEY];
         }
     } faliure:^(NSError * _Nonnull error) {
-        callback();
+        isRequestRoomMsg = NO;
+
     }];
 }
 
 + (void)joinRoomWithMessage:(NSDictionary *)source controller:(CustomNavViewController *)navCtrl {
-    LiveVideoRoomViewController *liveVC = [[LiveVideoRoomViewController alloc] init];
+    TXLiveRoomViewController *liveVC = [[TXLiveRoomViewController alloc] init];
     liveVC.roomId = [source ks_stringValueForKey:@"roomUid"];
-    liveVC.liveRoleType = RCRTCLiveRoleTypeAudience;
-    liveVC.createrId = [source ks_stringValueForKey:@"speakerId"];
+    liveVC.createrId = [source ks_stringValueForKey:@"speakerImUserId"];
     liveVC.createrName = [source ks_stringValueForKey:@"speakerName"];
     liveVC.createrAvatal = [source ks_stringValueForKey:@"speakerPic"];
-    liveVC.likeCount = [source ks_integerValueForKey:@"likeNum"]; // 点赞数
-    NSInteger lookCount = [source ks_integerValueForKey:@"lookNum"] + 1;
+    NSInteger lookCount = [source ks_integerValueForKey:@"lookNum"];
     liveVC.blacklistFlag = [source ks_integerValueForKey:@"blacklistFlag"] == 1 ? YES : NO;
     liveVC.totalCount = lookCount; // 观看人数
-    BOOL isTemp = [[source ks_stringValueForKey:@"roomType"] isEqualToString:@"TEMP"];
-    liveVC.isTempRoom = isTemp;
-    if (isTemp == NO) {
-        liveVC.liveEndTime = [source ks_stringValueForKey:@"liveEndTime"];
-        liveVC.expiredMinute = [source ks_integerValueForKey:@"expiredMinute"];
+    // 是否需要横竖屏按钮
+    liveVC.needSwitchButton = [[source ks_stringValueForKey:@"os"] isEqualToString:@"mobile"] ? NO : YES;
+    NSString *roomConfig = [source ks_stringValueForKey:@"roomConfig"];
+    NSData *jsonData = [roomConfig dataUsingEncoding:NSUTF8StringEncoding];
+    NSError *err;
+    NSDictionary *configDic = [NSJSONSerialization JSONObjectWithData:jsonData
+                                                              options:NSJSONReadingMutableContainers
+                                                                error:&err];
+    BOOL enableRecord = NO;
+    if (configDic) {
+        liveVC.enableChat = ![configDic ks_boolValueForKey:@"whether_chat"];
+        liveVC.enableSeat = ![configDic ks_boolValueForKey:@"whether_mic"];
+        liveVC.enableLike = ![configDic ks_boolValueForKey:@"whether_like"];
+        liveVC.hideCartButton = [configDic ks_integerValueForKey:@"whether_view_shop_cart"] == 1 ? YES : NO;
+        // 是否录制
+        enableRecord = [configDic ks_boolValueForKey:@"whether_video"];
     }
-    liveVC.enableSeat = ![source ks_boolValueForKey:@"whether_mic"];
-
+    
+    
+    liveVC.UserSig = [source ks_stringValueForKey:@"userSig"];
+    
+    NSDictionary *liveRoomConfig = [source ks_dictionaryValueForKey:@"liveRoomConfig"];
+    if (liveRoomConfig) {
+        liveVC.pushDomain = [liveRoomConfig ks_stringValueForKey:@"pushUrl"];
+        liveVC.pushUrlKey = [liveRoomConfig ks_stringValueForKey:@"pushSecret"];
+        liveVC.playDomain = [liveRoomConfig ks_stringValueForKey:@"playUrl"];
+        liveVC.liveUrlKey = [liveRoomConfig ks_stringValueForKey:@"playSecret"];
+    }
+    
     CustomNavViewController *liveNav = [[CustomNavViewController alloc] initWithRootViewController:liveVC];
     liveNav.modalPresentationStyle = UIModalPresentationFullScreen;
-    
-    if ([navCtrl.visibleViewController isKindOfClass:[LiveVideoRoomViewController class]]) {
-        LiveVideoRoomViewController *ctrl = (LiveVideoRoomViewController *)navCtrl.visibleViewController;
-        [ctrl quitAction];
+    if ([navCtrl.visibleViewController isKindOfClass:[TXLiveRoomViewController class]]) {
+        TXLiveRoomViewController *ctrl = (TXLiveRoomViewController *)navCtrl.visibleViewController;
+        [ctrl quitRoom];
         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
             [navCtrl.visibleViewController presentViewController:liveNav animated:YES completion:nil];
         });
@@ -74,4 +99,7 @@
     [hud hideAnimated:YES afterDelay:hiddenTime];
 }
 
++ (void)refreshClickStatus {
+    isRequestRoomMsg = NO;
+}
 @end

+ 43 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/Model/LiveModuleService.h

@@ -0,0 +1,43 @@
+//
+//  LiveModuleService.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2023/8/21.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveModuleService : NSObject
+// 直播服务
+// /api-student/imLiveBroadcastRoom/queryRoom
+
+/// 查询直播房间信息
+/// @param get get
+/// @param roomId 房间id
+/// @param success 成功
+/// @param faliure 失败
++ (void)imLiveBroadcastRoomQueryRoomRequest:(NSString *)get roomId:(NSString *)roomId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// 进入直播间通知
+// /imLiveBroadcastRoom/joinRoom
+
+/// 进入直播间通知
+/// @param get get
+/// @param roomId 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)LiveroomJoinRequest:(NSString *)get roomId:(NSString *)roomId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// 退出直播间
+// /api-im/user/
+
+/// 退出直播间
+/// @param post post json
+/// @param success 成功
+/// @param faliure 失败
++ (void)LiveroomQuit:(NSString *)post success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+@end
+
+NS_ASSUME_NONNULL_END

+ 59 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/Model/LiveModuleService.m

@@ -0,0 +1,59 @@
+//
+//  LiveModuleService.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2023/8/21.
+//
+
+#import "LiveModuleService.h"
+
+@implementation LiveModuleService
+
+// 直播服务
+// /api-student/imLiveBroadcastRoom/queryRoom
+
+/// 查询直播房间信息
+/// @param get get
+/// @param roomId 房间id
+/// @param success 成功
+/// @param faliure 失败
++ (void)imLiveBroadcastRoomQueryRoomRequest:(NSString *)get roomId:(NSString *)roomId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-student/imLiveBroadcastRoom/queryRoom"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:roomId forKey:@"roomUid"];
+    [parm setValue:UserDefault(IM_USERID) forKey:@"userId"];
+    [KSNetworkingManager LiveRoomRequest:get url:url parms:parm success:success faliure:faliure];
+}
+
+// 进入直播间通知
+// /imLiveBroadcastRoom/joinRoom
+
+/// 进入直播间通知
+/// @param get get
+/// @param roomId 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)LiveroomJoinRequest:(NSString *)get roomId:(NSString *)roomId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-student/imLiveBroadcastRoom/joinRoom"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:roomId forKey:@"roomUid"];
+    [parm setValue:UserDefault(IM_USERID) forKey:@"userId"];
+    [KSNetworkingManager LiveRoomRequest:get url:url parms:parm success:success faliure:faliure];
+}
+
+// 退出直播间
+// /api-im/user/
+
+/// 退出直播间
+/// @param post post json
+/// @param success 成功
+/// @param faliure 失败
++ (void)LiveroomQuit:(NSString *)post success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@", SEALCLASSHOST, @"/user/statusImUser"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:@"iOS" forKey:@"os"];
+    [parm setValue:@"3" forKey:@"status"];
+    [parm setValue:UserDefault(IM_USERID) forKey:@"userid"];
+    [KSNetworkingManager LiveRoomRequest:post url:url parms:parm success:success faliure:faliure];
+}
+@end

+ 7 - 2
KulexiuForStudent/KulexiuForStudent/Module/Live/View/DragWindow/KSDragWindow.h

@@ -10,11 +10,16 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
-#define KSDragWindowWidth (KPortraitWidth / 4.0f)
-#define KSDragWindowHeight (KPortraitHeight / 4.0f)
+#define KSDragWindowWidth (KPortraitWidth / 2.0f)
+#define KSDragWindowHeight (KPortraitWidth / 2.0f / 16.0f * 9)
 #define KSDragWindowHeightBottomSpace 40.0f
 #define KSDragWindowHeightRightSpace 0
 
+#define KSDragPhoneWindowWidth (KPortraitWidth / 4.0f)
+#define KSDragPhoneWindowHeight (KPortraitHeight / 4.0f)
+#define KSDragPhoneWindowHeightBottomSpace 40.0f
+#define KSDragPhoneWindowHeightRightSpace 0
+
 typedef NS_ENUM(NSInteger, DRAG_ACTION) {
     DRAG_ACTION_CLICK,  // 返回详情
     DRAG_ACTION_CANCEL, // 取消

+ 1 - 1
KulexiuForStudent/KulexiuForStudent/Module/Live/View/DragWindow/KSDragWindowManager.h

@@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
 
 + (instancetype)sharedManager;
 
-- (void)initDragWindow;
+- (void)initDragWindowWithPhoneLive:(BOOL)isPhoneLive;
 
 - (void)resignDragWindow;
 

+ 7 - 1
KulexiuForStudent/KulexiuForStudent/Module/Live/View/DragWindow/KSDragWindowManager.m

@@ -19,11 +19,17 @@
     return manager;
 }
 
-- (void)initDragWindow {
+- (void)initDragWindowWithPhoneLive:(BOOL)isPhoneLive {
     _hasShowWindow = YES;
     CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
     CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
     self.dragWindow = [[KSDragWindow alloc] initWithFrame:CGRectMake(screenWidth - KSDragWindowWidth, screenHeight - KSDragWindowHeight - KSDragWindowHeightBottomSpace , KSDragWindowWidth, KSDragWindowHeight)];
+    if (isPhoneLive) {
+        self.dragWindow = [[KSDragWindow alloc] initWithFrame:CGRectMake(screenWidth - KSDragPhoneWindowWidth, screenHeight - KSDragPhoneWindowHeight - KSDragPhoneWindowHeightBottomSpace , KSDragPhoneWindowWidth, KSDragPhoneWindowHeight)];
+    }
+    else {
+        self.dragWindow = [[KSDragWindow alloc] initWithFrame:CGRectMake(screenWidth - KSDragWindowWidth, screenHeight - KSDragWindowHeight - KSDragWindowHeightBottomSpace , KSDragWindowWidth, KSDragWindowHeight)];
+    }
     MJWeakSelf;
     [self.dragWindow clickAction:^(DRAG_ACTION action) {
         [weakSelf dragAction:action];

+ 8 - 2
KulexiuForStudent/KulexiuForStudent/Module/Login/Model/UserInfoManager.m

@@ -13,6 +13,7 @@
 #import "KSTipsAlert.h"
 #import <UMCommon/MobClick.h>
 #import "TXIMLinsenter.h"
+#import "KSEnterLiveroomManager.h"
 
 @interface UserInfoManager ()
 
@@ -37,15 +38,20 @@
     if (self = [super init]) {
         self.userInfo = [[UserInfo alloc] init];
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(otherLogin) name:@"otherLogin" object:nil];
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshLiveClickStatus) name:@"refreshLiveClickStatus" object:nil];
     }
     return self;
 }
 
+- (void)refreshLiveClickStatus {
+    [KSEnterLiveroomManager refreshClickStatus];
+}
+
 - (void)otherLogin {
     dispatch_main_async_safe(^{
         UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
         
-        if ([vc.presentedViewController isKindOfClass:NSClassFromString(@"NewClassRoomViewController")]) {
+        if ([vc.presentedViewController isKindOfClass:NSClassFromString(@"TXClassroomViewController")]) {
             [self checkTokenEnableCallback:^(BOOL enable) {
                 if (enable) {
                     [[NSNotificationCenter defaultCenter] postNotificationName:@"classroomQuit" object:nil];
@@ -60,7 +66,7 @@
         else if ([vc isKindOfClass:[UITabBarController class]]) {
             if ([vc.presentedViewController isKindOfClass:NSClassFromString(@"CustomNavViewController")]) {
                 CustomNavViewController *nav = (CustomNavViewController *)vc.presentedViewController;
-                if ([nav.visibleViewController isKindOfClass:NSClassFromString(@"LiveVideoRoomViewController")] || [nav.visibleViewController isKindOfClass:NSClassFromString(@"KSLiveWebViewController")]) {
+                if ([nav.visibleViewController isKindOfClass:NSClassFromString(@"TXLiveRoomViewController")] || [nav.visibleViewController isKindOfClass:NSClassFromString(@"KSLiveWebViewController")]) {
                     [self checkTokenEnableCallback:^(BOOL enable) {
                         if (enable) {
                             [[NSNotificationCenter defaultCenter] postNotificationName:@"liveroomQuit" object:nil];

+ 1 - 1
KulexiuForStudent/KulexiuForStudent/Module/Mine/Setting/View/AboutUsBodyView.m

@@ -20,7 +20,7 @@
 - (void)awakeFromNib {
     [super awakeFromNib];
     self.versionLabel.text = [NSString stringWithFormat:@"版本号%@",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]];
-    self.phoneLabel.text = @"4008851569";
+    self.phoneLabel.text = @"15347100733";
     self.emailLabel.text = @"klx@kulexiu999.onexmail.com";
 }
 

+ 1 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXClassRoom/Controller/TXClassroomViewController.m

@@ -1383,6 +1383,7 @@
     else if (member.playStatus) {
         musicUrl = member.url;
     }
+
     if (![NSString isEmptyString:musicUrl]) {
         [self playSongEnable:YES];
         [self mixWithUrl:musicUrl];

+ 17 - 14
KulexiuForStudent/KulexiuForStudent/Module/TXClassRoom/Service/TXClassroom/Model/Classroom.m

@@ -23,18 +23,6 @@
     room.surplusTime = [dic ks_integerValueForKey:@"surplusTime"];
     NSString *display = [dic ks_stringValueForKey:@"display"];
     
-    NSArray *memberArray = [dic ks_arrayValueForKey:@"members"];
-    NSMutableArray *memberList = [[NSMutableArray alloc] init];
-    for (NSDictionary *memberDic in memberArray) {
-        RoomMember *member = [RoomMember memberFromJson:memberDic];
-        if (member.role == RoleTeacher && [NSString isEmptyString:display]) {
-            display = [NSString stringWithFormat:@"display://type=1?userId=%@?uri=%@", member.userId, member.userId];
-        }
-        [memberList addObject:member];
-    }
-    room.memberList = memberList;
-    [room updateDisplayUri:display];
-
     NSDictionary *userDic = [dic ks_dictionaryValueForKey:@"userInfo"];
     RoomMember *currentMember = [RoomMember memberFromJson:userDic];
     room.currentMemberId = currentMember.userId;
@@ -42,13 +30,28 @@
     room.autoCloseFlag = [dic ks_boolValueForKey:@"autoCloseFlag"];
     room.autoCloseNetworkRoomTime = [dic ks_integerValueForKey:@"autoCloseNetworkRoomTime"];
     room.soundVolume = [dic ks_integerValueForKey:@"soundVolume"];
-    
-//    room.randomNumeric = [dic ks_integerValueForKey:@"randomNumeric"];
     room.randomNumeric = 1;
 
     room.roomConfig = [TxRTCRoomConfig configFromJson:[dic ks_dictionaryValueForKey:@"rtcRoomConfig"]];
     room.serviceProvider= [dic ks_stringValueForKey:@"serviceProvider"];
     room.isSingleClass = [dic ks_integerValueForKey:@"studentNums"] > 1 ? NO : YES;
+    
+    NSArray *memberArray = [dic ks_arrayValueForKey:@"members"];
+    NSMutableArray *memberList = [[NSMutableArray alloc] init];
+    for (NSDictionary *memberDic in memberArray) {
+        RoomMember *member = [RoomMember memberFromJson:memberDic];
+        if ([member.userId isEqualToString:currentMember.userId]) {
+            member = currentMember;
+        }
+        if (member.role == RoleTeacher && [NSString isEmptyString:display]) {
+            display = [NSString stringWithFormat:@"display://type=1?userId=%@?uri=%@", member.userId, member.userId];
+        }
+        [memberList addObject:member];
+    }
+    room.memberList = memberList;
+    [room updateDisplayUri:display];
+
+   
     return room;
 }
 

+ 80 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/Controller/TXLiveRoomViewController.h

@@ -0,0 +1,80 @@
+//
+//  TXLiveRoomViewController.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/21.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "BaseViewController.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveRoomViewController : BaseViewController
+/*!
+ 加入的房间 ID
+ */
+@property (nonatomic, strong) NSString *roomId;
+
+/// 主讲人id
+@property (nonatomic, strong) NSString *createrId;
+/// 主讲人名称
+@property (nonatomic, strong) NSString *createrName;
+/// 主讲人头像
+@property (nonatomic, strong) NSString *createrAvatal;
+
+// 是否禁止连麦
+@property (nonatomic, assign) BOOL enableSeat;
+// 是否禁止聊天
+@property (nonatomic, assign) BOOL enableChat;
+// 是否允许点赞
+@property (nonatomic, assign) BOOL enableLike;
+
+@property (nonatomic, assign) NSInteger likeCount;
+
+// 是否需要横竖屏按钮 (PC直播需要横竖屏按钮)
+@property (nonatomic, assign) BOOL needSwitchButton;
+
+/// 房间人数
+@property (nonatomic, assign) NSInteger totalCount;
+
+/// 是否在黑名单中
+@property (nonatomic, assign) BOOL blacklistFlag;
+
+@property (nonatomic, assign) BOOL hideCartButton;
+// 直播sign
+@property (nonatomic, strong) NSString *UserSig;
+
+// 播放地址
+@property (nonatomic, strong) NSString *playDomain;
+// 播放权鉴密钥
+@property (nonatomic, strong) NSString *liveUrlKey;
+
+// 推流地址
+@property (nonatomic, strong) NSString *pushDomain;
+
+// 推流地址
+@property (nonatomic, strong) NSString *pushUrlKey;
+
+// 主讲人是否在房间
+@property (nonatomic, assign) BOOL isCreateInRoom;
+
+- (void)quitRoom;
+
+@property (nonatomic, assign) BOOL isLiveCourse;
+
+@property (nonatomic, assign) NSInteger surplusTime;
+
+@property (nonatomic, assign) NSInteger autoCloseNetworkRoomTime;
+
+@property (nonatomic, strong) NSString *subjectId;
+
+// 3A 参数
+@property (nonatomic, assign) NSInteger ANS;
+
+@property (nonatomic, assign) NSInteger AEC;
+
+@property (nonatomic, assign) NSInteger AGC;
+@end
+
+NS_ASSUME_NONNULL_END

+ 2792 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/Controller/TXLiveRoomViewController.m

@@ -0,0 +1,2792 @@
+//
+//  TXLiveRoomViewController.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/21.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveRoomViewController.h"
+#import "TXLiteAVSDK_Professional/TXLiteAVSDK.h"
+#import "KSLiveEmptyView.h"
+#import "TXLiveVideoView.h"
+#import "LiveRoomHeadView.h"
+#import "LiveRoomBottomView.h"
+#import <Lottie/Lottie.h>
+#import "KSChatInputBarControl.h"
+#import "TXLiveChatListCell.h"
+#import "AppDelegate.h"
+#import "UIDevice+TFDevice.h"
+#import "LiveRoomLikeLayer.h"
+#import "LiveAlertView.h"
+#import "KSShopCardView.h"
+#import "KSLiveWebViewController.h"
+#import "KSLiveBadNetView.h"
+
+#import "KSLiveEndView.h"
+#import "LiveAnimationView.h"
+#import "LiveApplyView.h"
+#import "LiveApplyingView.h"
+#import <ImSDK_Plus/ImSDK_Plus.h>
+#import "TXIMLinsenter.h"
+
+#import "TXLiveMessageModel.h"
+#import "TXLiveURLUtils.h"
+#import "TXLiveMessageCenter.h"
+#import "KSDragWindowManager.h"
+#import "TXLiveLoadingView.h"
+#import "TXUISeatMember.h"
+#import "TXSeatContainerView.h"
+#import "LiveRoomConfirmAlert.h"
+#import "LiveModuleService.h"
+
+
+#define AUTOHIDE_TIME (10.0f)
+
+typedef NS_ENUM(NSInteger, MICSTATUS) {
+    MICSTATUS_NOMAL,      // 正常状态
+    MICSTATUS_WAITING,    // 申请中
+    MICSTATUS_CONNECTING, // 连麦中
+};
+
+
+@interface TXLiveRoomViewController ()<UIGestureRecognizerDelegate,KSChatInputBarControlDelegate,UITableViewDataSource,UITableViewDelegate,V2TXLivePlayerObserver,TRTCCloudDelegate>
+
+// 是否是观众
+@property (nonatomic, assign) BOOL isAudience;
+// rtc 连麦时使用
+@property (nonatomic, strong) TRTCCloud *trtcCloud;
+
+@property (nonatomic, strong) V2TXLivePlayer *livePlayer;
+
+@property (nonatomic, strong) LiveRoomHeadView *headView;
+
+@property (nonatomic, copy) LiveRoomBottomView *bottomView;
+
+// 视频主窗口容器
+@property (nonatomic, strong) UIView *videoContainerView;
+
+// 主屏videoView
+@property (nonatomic, strong) UIView *videoView;
+
+// 画面渲染的画面
+@property (nonatomic, strong) TXLiveVideoView *videoRenderView;
+
+// 切换按钮
+@property (nonatomic, strong) UIButton *switchButton;
+
+@property (nonatomic, strong) LOTAnimationView *animationView;
+/// 连麦的视图
+@property (nonatomic, strong) TXSeatContainerView *seatContainer;
+// 聊天UI
+/*!
+ 消息列表CollectionView和输入框都在这个view里
+ */
+@property(nonatomic, strong) UIView *messageContentView;
+
+/*!
+ 会话页面的TableView
+ */
+@property (nonatomic, strong) UITableView *conversationMessageTableView;
+
+/*!
+ 聊天内容的消息Cell数据模型的数据源
+ 
+ @discussion 数据源中存放的元素为消息Cell的数据模型,即RCDLiveMessageModel对象。
+ */
+@property(nonatomic, strong) NSMutableArray<TXLiveMessageModel *> *conversationDataRepository;
+
+/**
+ 输入工具栏
+ */
+@property(nonatomic,strong) KSChatInputBarControl *inputBar;
+/**
+ *  是否需要滚动到底部
+ */
+@property(nonatomic, assign) BOOL isNeedScrollToButtom;
+
+/**
+ 上次点赞按钮点击时间
+ */
+@property(nonatomic, assign) NSTimeInterval lastClickPraiseTime;
+
+@property (nonatomic, assign) BOOL landScape;
+
+@property (nonatomic, assign) BOOL isHiddenHeadView;
+
+// 连麦状态
+@property (nonatomic, assign) MICSTATUS micStatus;
+
+@property (nonatomic, strong) LiveApplyView *applyView; // 未申请
+ 
+@property (nonatomic, strong) LiveApplyingView *applyingView; // 申请中
+
+@property (nonatomic, assign) BOOL isCreaterVideoEnable;
+
+@property (nonatomic, assign) BOOL isCloseRoom; // 是否直播结束
+/// 提示窗
+@property (nonatomic, strong) LiveAlertView *alertView;
+
+@property (nonatomic, strong) KSShopCardView *cardView;
+
+@property (nonatomic, assign) NSTimeInterval lastSendMsgTime;
+
+@property (nonatomic, strong) LiveAnimationView *enterAnimationView;
+
+@property (nonatomic, strong) KSLiveEndView *endView; // 直播结束显示的画面
+
+@property (nonatomic, strong) KSLiveEmptyView *emptyView;
+
+@property (nonatomic, strong) KSLiveBadNetView *netBadView;
+/// 是否在切换身份
+@property (nonatomic, assign) BOOL isTransferRole;
+
+@property (nonatomic, assign) BOOL hasSendWelcomeMessage;
+
+// 远端连麦用户
+@property (nonatomic, strong) NSMutableArray *remoteMemberArray;
+
+@property (nonatomic, assign) BOOL isPauseLive;
+
+@property (nonatomic, strong) TXLiveLoadingView *loadingView;
+
+@property (nonatomic, assign) BOOL hasShowSuspendView;
+
+@property (nonatomic, assign) BOOL muteRoomMic;
+
+@property (nonatomic, assign) BOOL micEnable;
+
+@property (nonatomic, strong) LiveRoomConfirmAlert *closeAlert;
+
+@end
+
+//  用于记录点赞消息连续点击的次数
+static int clickPraiseBtnTimes  = 0;
+
+@implementation TXLiveRoomViewController
+
+- (instancetype)init {
+    self = [super init];
+    if (self) {
+        [self defaultConfig];
+        [self default3AConfig];
+    }
+    return self;
+}
+
+- (void)default3AConfig {
+    self.ANS = 0;
+    self.AEC = 100;
+    self.AGC = 0;
+}
+- (void)joinChatRoom {
+    if (TXIM_LINSENTER.loginIMSuccess == NO) {
+        [TXIM_LINSENTER TXIMLoginWithUserId:UserDefault(IM_USERID) sig:self.UserSig callback:^(BOOL isSuccess, NSString * _Nullable msg) {
+            [self liveConversationJoin];
+        }];
+    }
+    else {
+        [self liveConversationJoin];
+    }
+}
+
+- (void)liveConversationJoin {
+    [[V2TIMManager sharedInstance] joinGroup:self.roomId msg:nil succ:^{
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [self addConstMessage];
+            [self sendWelcomeMessage];
+            [self getGroupAttrInfo];
+            [self getGroupCount];
+        });
+        
+    } fail:^(int code, NSString *desc) {
+        NSLog(@"");
+    }];
+}
+
+- (void)getGroupAttrInfo {
+    [[V2TIMManager sharedInstance] getGroupAttributes:self.roomId keys:nil succ:^(NSMutableDictionary<NSString *,NSString *> *groupAttributeList) {
+        NSLog(@"");
+        [self evaluateGroupInfo:groupAttributeList];
+    } fail:^(int code, NSString *desc) {
+        
+    }];
+}
+
+- (void)getGroupCount {
+    [[V2TIMManager sharedInstance] getGroupCounters:self.roomId keys:nil succ:^(NSDictionary<NSString *,NSNumber *> *groupCounters) {
+        NSLog(@"");
+        [self evaluateGroupCount:groupCounters];
+    } fail:^(int code, NSString *desc) {
+        
+    }];
+}
+
+
+
+- (void)addConstMessage {
+    TXConstMessage *statement = [[TXConstMessage alloc] init];
+    statement.userInfo = [self getCurrentUser];
+    statement.text = @"欢迎进入直播课堂,请遵守相关法规,禁止传播低俗、暴力等不良信息。为孩子创造健康绿色的学习环境。";
+    [self appendAndDisplayMessage:statement];
+}
+
+- (void)sendWelcomeMessage {
+    TXLiveMessageWelcome *welcomeMessage = [[TXLiveMessageWelcome alloc] init];
+    welcomeMessage.userInfo = [self getCurrentUser];
+    MJWeakSelf;
+    [self sendCustomMessage:welcomeMessage priority:V2TIM_PRIORITY_DEFAULT displayMessage:NO callback:^(BOOL success) {
+        weakSelf.hasSendWelcomeMessage = YES;
+        [weakSelf showEnterMessageAndJoinRoom];
+    }];
+}
+
+- (void)showEnterMessageAndJoinRoom {
+    NSString *contentString = [NSString stringWithFormat:@"%@ 进入直播间",UserDefault(NicknameKey)];
+    [self showAnimationView:YES showMessag:contentString];
+}
+
+- (void)joinLiveRoom {
+    [self changeEmptyStatusView];
+    [self resetNetTips];
+    [self startPlay];
+}
+
+
+- (void)viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+    [UIApplication sharedApplication].idleTimerDisabled = YES;
+    [IQKeyboardManager sharedManager].enableAutoToolbar = NO;
+    [IQKeyboardManager sharedManager].enable = NO;
+    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
+    // 重新渲染view
+        KSDragWindowManager *manager = [KSDragWindowManager sharedManager];
+        if (manager.hasShowWindow) {
+            [manager resignDragWindow];
+        }
+        if (self.hasShowSuspendView) {
+            [self.videoView addSubview:self.videoRenderView];
+            [self.videoRenderView mas_updateConstraints:^(MASConstraintMaker *make) {
+                make.left.right.bottom.top.mas_equalTo(self.videoView);
+            }];
+            _hasShowSuspendView = NO;
+        }
+        if (self.bottomView.isMute == NO) {
+            [self muteVoiceAction];
+        }
+}
+
+- (void)viewWillDisappear:(BOOL)animated {
+    [super viewWillDisappear:animated];
+    [UIApplication sharedApplication].idleTimerDisabled = NO;
+    if (self.landScape) {
+        [self changeOrientation:NO];
+    }
+    [IQKeyboardManager sharedManager].enableAutoToolbar = YES;
+    [IQKeyboardManager sharedManager].enable = YES;
+    if (@available(iOS 13.0, *)) {
+        [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDarkContent;
+    } else {
+        // Fallback on earlier versions
+        [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
+    }
+}
+
+- (void)defaultConfig {
+    self.enableChat = YES;
+    self.enableSeat = YES;
+    self.enableLike = YES;
+    self.needSwitchButton = NO;
+    self.micStatus = MICSTATUS_NOMAL;
+    self.isCreateInRoom = NO; // 默认主讲人不在房间
+    self.blacklistFlag = NO;
+    self.isCloseRoom = NO;
+    self.lastClickPraiseTime = 0;
+    self.isAudience = YES;
+    self.isCreaterVideoEnable = YES;
+}
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    self.ks_prefersNavigationBarHidden = YES;
+    [self setupUI];
+    [self registerNotification];
+    [self joinChatRoom];
+    [self joinLiveRoom];
+    [self notiferJoinSuccessToServiceCallback:^{
+
+    }];
+}
+
+
+- (void)registerNotification {
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMessageNotification:) name:OnReceiveTXLiveMessageNotification object:nil];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(liveroomLogOut) name:@"liveroomLogout" object:nil];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(liveroomQuit) name:@"liveroomQuit" object:nil];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(IMConnetedCallback) name:@"TXIMConnected" object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(muteAllAudio) name:@"muteLiveAudio" object:nil];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveGroupMessage:)  name:OnReceiveTXLiveGroupNotification object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveGroupCountMessage:)  name:OnReceiveTXLiveGroupCountNotification object:nil];
+    
+}
+
+- (void)IMConnetedCallback {
+    dispatch_main_async_safe(^{
+        // IM 连接成功回调
+        if (self.hasSendWelcomeMessage) { // 如果已经发送了进入消息
+
+            // 查询是否直播间开启
+            [LiveModuleService imLiveBroadcastRoomQueryRoomRequest:KS_GET roomId:self.roomId success:^(NSDictionary * _Nonnull dic) {
+                if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+                    // 回调信息
+                    MJWeakSelf;
+                    [self notiferJoinSuccessToServiceCallback:^{
+                        [weakSelf sendWelcomeMessage];
+                        [weakSelf checkPlayerStatus];
+                    }];
+                }
+                else {
+                    [self MBPShow:MESSAGEKEY];
+                    [self quitRoom];
+                }
+            } faliure:^(NSError * _Nonnull error) {
+                
+            }];
+            
+            // 查询群属性
+            [self getGroupAttrInfo];
+        }
+    });
+}
+
+- (void)checkPlayerStatus {
+    if (self.isCloseRoom) {
+        return;
+    }
+    if (self.isAudience) {
+        if (self.livePlayer.isPlaying == NO) {
+            [self resetNetTips];
+            [self startPlay];
+        }
+    }
+    else {
+        [self connectHostWithStatus:NO];
+    }
+}
+
+
+- (void)liveroomLogOut {
+    [self MBPShow:@"该账号在其他设备上登录"];
+    [self quitRoom];
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        [[NSNotificationCenter defaultCenter] postNotificationName:@"backLoginView" object:nil];
+    });
+}
+
+- (void)liveroomQuit {
+    [self quitRoom];
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        [[NSNotificationCenter defaultCenter] postNotificationName:@"backLoginView" object:nil];
+    });
+}
+- (void)muteAllAudio {
+    [self muteVoiceAction];
+}
+
+
+#pragma mark ----- // 观众上下麦
+- (void)connectHostWithStatus:(BOOL)isConnect {
+    // 如果直播结束 不转换身份
+    if (self.isCloseRoom == YES) {
+        return;
+    }
+    //  转换中,不再处理转换身份
+    if (self.isTransferRole) {
+        return;
+    }
+    if (isConnect && self.isAudience == NO) {
+        self.micStatus = MICSTATUS_CONNECTING;
+        return;
+    }
+    else if (isConnect == NO && self.isAudience) {
+        self.micStatus = MICSTATUS_NOMAL;
+        return;
+    }
+    self.isTransferRole = YES;
+    self.micEnable = YES;
+    // 清理当前视图
+    [self removeSeatContainer];
+    self.remoteMemberArray = [NSMutableArray array];
+    // 移除状态视图
+    
+    if (isConnect) {
+        [self stopPlay];
+        [self hideTipsView];
+        if (self.isCreaterVideoEnable) {
+            [self hideEmptyView];
+        }
+        self.isAudience = NO;
+        [self enterLiveRTCRoom];
+        self.isTransferRole = NO;
+        self.micStatus = MICSTATUS_CONNECTING;
+    }
+    else {
+        self.isAudience = YES;
+        if (self.isPauseLive == NO) {
+            [self startPlay];
+        }
+        if (_trtcCloud) {
+            [self.trtcCloud stopAllRemoteView];
+            [self.trtcCloud stopLocalAudio];
+            [self.trtcCloud exitRoom];
+            _trtcCloud = nil;
+            [TRTCCloud destroySharedIntance];
+        }
+        self.micStatus = MICSTATUS_NOMAL;
+        self.isTransferRole = NO;
+    }
+    [self muteVoiceAction];
+}
+
+- (void)setupUI {
+    self.view.backgroundColor = HexRGB(0x25292e);
+    [self.view addSubview:self.emptyView];
+
+    [self.view addSubview:self.endView];
+    
+    [self.view addSubview:self.videoContainerView];
+    [self.videoContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.view);
+    }];
+    [self.videoContainerView addSubview:self.videoView];
+    
+    // 异常的view
+    [self.videoContainerView addSubview:self.netBadView];
+
+    // 按钮和视频的布局
+    if (self.needSwitchButton) {
+        [self.videoView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.videoContainerView);
+            if (@available(iOS 11.0, *)) {
+                make.top.mas_equalTo(self.videoContainerView.mas_safeAreaLayoutGuideTop).offset(160);
+            } else {
+                // Fallback on earlier versions
+                make.top.mas_equalTo(self.videoContainerView.mas_top).offset(160);
+            }
+            CGFloat rate = 9 / 16.0f;
+            make.height.mas_equalTo(self.videoContainerView.mas_width).multipliedBy(rate);
+            make.width.height.mas_equalTo(self.videoContainerView).priorityLow();
+            make.width.height.lessThanOrEqualTo(self.videoContainerView);
+        }];
+        // 显示切换按钮
+        [self.videoContainerView addSubview:self.switchButton];
+        [self.switchButton mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.right.mas_equalTo(self.videoContainerView.mas_right).offset(-10);
+            make.width.height.mas_equalTo(33);
+            make.bottom.mas_equalTo(self.videoView.mas_bottom).offset(-10);
+        }];
+        self.switchButton.hidden = NO;
+        
+    }
+    else {
+        [self.videoView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.top.bottom.right.mas_equalTo(self.videoContainerView);
+        }];
+    }
+    // 添加视频预览图
+    [self.videoView addSubview:self.videoRenderView];
+    [self.videoRenderView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.videoView);
+    }];
+    
+    [self.emptyView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.videoView);
+    }];
+    self.emptyView.hidden = YES;
+    
+    // 直播结束的画面
+    [self.endView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.videoView);
+    }];
+    self.endView.hidden = YES;
+    
+    [self.netBadView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.videoView);
+    }];
+    self.netBadView.hidden = YES;
+    
+    [self.videoContainerView addSubview:self.headView];
+    self.headView.boardcastName.text = [NSString returnNoNullStringWithString:self.createrName];
+    if (![NSString isEmptyString:self.createrAvatal]) {
+        [self.headView.boardcastAvatal sd_setImageWithURL:[NSURL URLWithString:[self.createrAvatal getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"teacher_logo"]];
+    }
+    [self countLikeMessageCount];
+    [self countMemberCount];
+    [self.headView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.mas_equalTo(self.videoContainerView);
+        make.height.mas_equalTo(80);
+        if (@available(iOS 11.0, *)) {
+            make.top.mas_equalTo(self.videoContainerView.mas_safeAreaLayoutGuideTop).offset(0);
+        } else {
+            // Fallback on earlier versions
+            make.top.mas_equalTo(self.videoContainerView.mas_top).offset(0);
+        }
+    }];
+    // 聊天区域
+    [self.videoContainerView addSubview:self.messageContentView];
+    
+    if (self.hideCartButton == NO) {
+        [self.videoContainerView addSubview:self.animationView];
+        [self.animationView mas_makeConstraints:^(MASConstraintMaker *make) {
+            if (@available(iOS 11.0, *)) {
+                make.bottom.mas_equalTo(self.videoContainerView.mas_safeAreaLayoutGuideBottom).offset(-9);
+            } else {
+                // Fallback on earlier versions
+                make.bottom.mas_equalTo(self.videoContainerView.mas_bottom).offset(-9);
+            }
+            make.centerX.mas_equalTo(self.videoContainerView.mas_right).offset(-80);
+            make.width.mas_equalTo(48);
+            make.height.mas_equalTo(56);
+        }];
+        [self.animationView play];
+    }
+    [self.videoContainerView addSubview:self.bottomView];
+    self.bottomView.hideCartVButton = self.hideCartButton;
+    [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.mas_equalTo(self.videoContainerView);
+        if (@available(iOS 11.0, *)) {
+            make.bottom.mas_equalTo(self.videoContainerView.mas_safeAreaLayoutGuideBottom).offset(-5);
+        } else {
+            // Fallback on earlier versions
+            make.bottom.mas_equalTo(self.videoContainerView.mas_bottom).offset(-5);
+        }
+        make.height.mas_equalTo(44);
+    }];
+    
+    // 聊天页面
+    if (self.needSwitchButton) {
+        [self.messageContentView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(self.videoContainerView.mas_left);
+            make.right.mas_equalTo(self.videoContainerView.mas_right);
+            make.bottom.mas_equalTo(self.bottomView.mas_top).offset(-5);
+            make.top.mas_equalTo(self.videoView.mas_bottom).offset(10).priorityLow();
+        }];
+    }
+    else {
+        [self.messageContentView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(self.videoContainerView.mas_left);
+            make.right.mas_equalTo(self.videoContainerView.mas_right);
+            make.bottom.mas_equalTo(self.bottomView.mas_top).offset(-10);
+            make.height.mas_equalTo(180);
+        }];
+    }
+    
+    [self.videoContainerView addSubview:self.inputBar];
+    [_inputBar setBackgroundColor: [UIColor whiteColor]];
+    
+    [_inputBar setFrame:CGRectMake(0, KPortraitHeight, KPortraitWidth , 50)];
+    [_inputBar setHidden:YES];
+    
+    [self.messageContentView addSubview:self.conversationMessageTableView];
+    [self.conversationMessageTableView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.top.mas_equalTo(self.messageContentView);
+        make.width.mas_equalTo(KPortraitWidth);
+        make.bottom.mas_equalTo(self.messageContentView.mas_bottom);
+    }];
+    
+    UITapGestureRecognizer *resetBottomTapGesture =[[UITapGestureRecognizer alloc]
+                                                    initWithTarget:self
+                                                    action:@selector(resetBottomGesture:)];
+    resetBottomTapGesture.delegate = self;
+    [self.videoContainerView addGestureRecognizer:resetBottomTapGesture];
+    
+    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(headViewAnimation:)];
+    tapGesture.delegate = self;
+    [self.videoView addGestureRecognizer:tapGesture];
+}
+
+- (void)headViewAnimation:(UIGestureRecognizer *)gestureRecognizer {
+    if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
+        [self setDefaultBottomViewStatus];
+    }
+    if (self.landScape) {
+        self.isHiddenHeadView = !self.isHiddenHeadView;
+    }
+}
+
+#pragma mark -- 加入直播间和退出直播间回到服务
+- (void)notiferJoinSuccessToServiceCallback:(void(^)(void))callback {
+    [LiveModuleService LiveroomJoinRequest:KS_GET roomId:self.roomId success:^(NSDictionary * _Nonnull dic) {
+        callback();
+    } faliure:^(NSError * _Nonnull error) {
+        callback();
+    }];
+}
+
+- (void)quitNotiferService {
+    [LiveModuleService LiveroomQuit:KS_POST success:^(NSDictionary * _Nonnull dic) {
+        if ([dic ks_integerValueForKey:@"errCode"] == 0) {
+            NSLog(@"success");
+        }
+        else {
+            NSLog(@"----- error %@", [dic ks_stringValueForKey:@"errMsg"]);
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+}
+
+#pragma mark ------ 播放控制
+- (void)startPlay {
+    if ([self.livePlayer isPlaying] == NO) {
+        [self resetNetTips];
+        if (self.isCreaterVideoEnable) {
+            [self hideEmptyView];
+        }
+        [self showLoading];
+        self.videoRenderView.hasMainStream = YES;
+        self.videoRenderView.hasSubStream = NO;
+        [self.livePlayer setRenderView:self.videoRenderView.mainView];
+        if (self.needSwitchButton) {
+            [self.livePlayer setRenderFillMode:V2TXLiveFillModeFit];
+        }
+        else {
+            [self.livePlayer setRenderFillMode:V2TXLiveFillModeFill];
+        }
+        // 获取url的方法
+        NSString *streamId = [NSString stringWithFormat:@"%@_%@", self.roomId, self.createrId];
+        NSString *url = [TXLiveURLUtils generateRtmpPlayUrl:streamId playDomain:self.playDomain liveUrlKey:self.liveUrlKey];
+        [self.livePlayer startLivePlay:url];
+        [self muteVoiceAction];
+    }
+}
+
+- (void)stopPlay {
+    if (_livePlayer) {
+        if ([self.livePlayer isPlaying]) {
+            [self hideLoading];
+            [self.livePlayer stopPlay];
+        }
+    }
+}
+
+// 不播放声音
+- (void)pauserAudio {
+    [self.livePlayer pauseAudio];
+}
+// 恢复声音
+- (void)resumeAudio {
+    [self.livePlayer resumeAudio];
+}
+
+#pragma mark ---- V2TXLivePlayerObserver
+- (void)onError:(id<V2TXLivePlayer>)player code:(V2TXLiveCode)code message:(NSString *)msg extraInfo:(NSDictionary *)extraInfo {
+
+    if (code == V2TXLIVE_ERROR_DISCONNECTED) {
+        // 连接断开
+        if (self.isPauseLive == NO && self.isCreateInRoom) {
+            [self hideLoading];
+            [self showBadNetTips];
+        }
+    }
+    else if (code == V2TXLIVE_WARNING_VIDEO_BLOCK) {
+        
+    }
+    NSLog(@"---- V2TXLivePlayer %zd  message:%@", code, msg);
+}
+
+- (void)onConnected:(id<V2TXLivePlayer>)player extraInfo:(NSDictionary *)extraInfo {
+    NSLog(@" ------ connected %@", extraInfo);
+    self.isPauseLive = NO;
+    self.isCreateInRoom = YES;
+    if (self.isCreaterVideoEnable) {
+        [self hideEmptyView];
+    }
+}
+
+- (void)onVideoPlaying:(id<V2TXLivePlayer>)player firstPlay:(BOOL)firstPlay extraInfo:(NSDictionary *)extraInfo {
+    NSLog(@" ------ onVideoPlaying %@", extraInfo);
+    [self hideLoading];
+}
+
+
+- (void)onVideoResolutionChanged:(id<V2TXLivePlayer>)player width:(NSInteger)width height:(NSInteger)height {
+    NSLog(@" ------ onVideoResolutionChanged %zd %zd", width, height);
+}
+
+// 直播状态
+- (void)onStatisticsUpdate:(id<V2TXLivePlayer>)player statistics:(V2TXLivePlayerStatistics *)statistics {
+    NSLog(@"----- V2TXLivePlayerStatistics desc %@", statistics.description);
+}
+
+- (void)onReceiveSeiMessage:(id<V2TXLivePlayer>)player payloadType:(int)payloadType data:(NSData *)data {
+    NSLog(@"----- onReceiveSeiMessage desc %@", [data mj_JSONObject]);
+    if (self.isAudience == YES && self.isPauseLive == NO) {
+        NSDictionary *parm =  [data mj_JSONObject];
+        if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"sync"]) { // 同步连麦人数
+            NSArray *memberArray = [parm ks_arrayValueForKey:@"seatUser"];
+            NSMutableArray *remoteSeatArray = [NSMutableArray arrayWithArray:memberArray];
+            // 移除自己
+            NSMutableArray *seatArray = [NSMutableArray array];
+            for (NSDictionary *userParm in remoteSeatArray) {
+                if (![[userParm ks_stringValueForKey:@"userId"] isEqualToString:UserDefault(IM_USERID)]) {
+                    TXUISeatMember *member = [[TXUISeatMember alloc] init];
+                    member.userId = [userParm ks_stringValueForKey:@"userId"];
+                    member.muteMic = [userParm ks_boolValueForKey:@"micStatus"];
+                    [seatArray addObject:member];
+                }
+            }
+            
+            [self refreshSeatWithMember:seatArray];
+//            if (self.remoteMemberArray.count != seatArray.count) { // 如果连麦人数不同
+//                [self refreshSeatWithMember:seatArray];
+//            }
+//            else {
+//                BOOL isSameUser = YES;
+//                NSMutableArray *seatMemberArr = [self.remoteMemberArray mutableCopy];
+//
+//                for (TXUISeatMember *member in seatMemberArr) {
+//
+//                    if (![remoteSeatArray containsObject:member]) {
+//                        isSameUser = NO;
+//                    }
+//                }
+//                if (isSameUser == NO) {
+//                    [self refreshSeatWithMember:seatArray];
+//                }
+//            }
+        }
+    }
+    else {
+        [self refreshSeatWithMember:@[]];
+    }
+}
+
+- (void)refreshSeatWithMember:(NSArray *)memberArray {
+    self.remoteMemberArray = [NSMutableArray arrayWithArray:memberArray];
+    [self renderSeatView];
+}
+
+#pragma mark --- trtcCloud delegate
+// 远端主播加入房间
+- (void)onRemoteUserEnterRoom:(NSString *)userId {
+    if (![self judgeContainerRemoteUser:userId] && ![userId isEqualToString:self.createrId]) { // 如果不包含当前用户 添加 和刷新连麦
+        TXUISeatMember *member = [[TXUISeatMember alloc] init];
+        member.userId = userId;
+        member.muteMic = YES;
+        [self.remoteMemberArray addObject:member];
+    }
+    
+    [self renderSeatView];
+}
+
+// 远端主播离开
+- (void)onRemoteUserLeaveRoom:(NSString *)userId reason:(NSInteger)reason {
+    if ([self judgeContainerRemoteUser:userId]) { // 如果包含当前用户 移除当前用和刷新连麦
+        [self removeMemberUserId:userId];
+    }
+    [self renderSeatView];
+}
+
+- (BOOL)judgeContainerRemoteUser:(NSString *)userId {
+    BOOL containUser = NO;
+    NSMutableArray *remoteMemArray = [self.remoteMemberArray mutableCopy];
+    for (TXUISeatMember *member in remoteMemArray) {
+        if ([member.userId isEqualToString:userId]) {
+            containUser = YES;
+        }
+    }
+    return containUser;
+}
+
+- (void)removeMemberUserId:(NSString *)userId {
+    NSMutableArray *remoteMemArray = [self.remoteMemberArray mutableCopy];
+    for (TXUISeatMember *member in remoteMemArray) {
+        if ([member.userId isEqualToString:userId]) {
+            [self.remoteMemberArray removeObject:member];
+            return;
+        }
+    }
+}
+
+- (void)onWarning:(TXLiteAVWarning)warningCode warningMsg:(NSString *)warningMsg extInfo:(NSDictionary *)extInfo {
+    NSLog(@" warningMsg  %@  extInfo:%@", warningMsg, extInfo.description);
+}
+
+// 远端视频
+- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {
+    NSLog(@"creater remote videoStream status: %d", available);
+    if (available) {
+        self.videoRenderView.hasMainStream = YES;
+        if (self.videoRenderView.hasSubStream) {
+            [self.trtcCloud startRemoteView:self.createrId streamType:TRTCVideoStreamTypeBig view:self.videoRenderView.smallView];
+            [self.trtcCloud startRemoteView:self.createrId streamType:TRTCVideoStreamTypeSub view:self.videoRenderView.mainView];
+        }
+        else {
+            [self.trtcCloud stopRemoteView:self.createrId streamType:TRTCVideoStreamTypeSub];
+            [self.trtcCloud startRemoteView:self.createrId streamType:TRTCVideoStreamTypeBig view:self.videoRenderView.mainView];
+        }
+    }
+    else {
+        self.videoRenderView.hasMainStream = NO;
+        [self.trtcCloud stopRemoteView:self.createrId streamType:TRTCVideoStreamTypeBig];
+    }
+}
+
+
+- (void)onUserSubStreamAvailable:(NSString *)userId available:(BOOL)available {
+    NSLog(@"creater remote subStream status: %d", available);
+    if (available) {
+        self.videoRenderView.hasSubStream = YES;
+        [self.trtcCloud startRemoteView:self.createrId streamType:TRTCVideoStreamTypeSub view:self.videoRenderView.mainView];
+        if (self.videoRenderView.hasMainStream) {
+            [self.trtcCloud startRemoteView:self.createrId streamType:TRTCVideoStreamTypeBig view:self.videoRenderView.smallView];
+        }
+    }
+    else {
+        self.videoRenderView.hasSubStream = NO;
+        [self.trtcCloud stopRemoteView:self.createrId streamType:TRTCVideoStreamTypeSub];
+        if (self.videoRenderView.hasMainStream) {
+            [self.trtcCloud startRemoteView:self.createrId streamType:TRTCVideoStreamTypeBig view:self.videoRenderView.mainView];
+        }
+    }
+}
+
+- (void)onFirstVideoFrame:(NSString *)userId streamType:(TRTCVideoStreamType)streamType width:(int)width height:(int)height {
+    
+}
+
+- (void)onRecvSEIMsg:(NSString *)userId message:(NSData *)message {
+//    NSDictionary *parm =  [message mj_JSONObject];
+}
+
+- (void)onUserAudioAvailable:(NSString *)userId available:(BOOL)available {
+    for (TXUISeatMember *member in self.remoteMemberArray) {
+        if ([member.userId isEqualToString:userId]) {
+            member.muteMic = !available;
+        }
+    }
+    [self renderSeatView];
+}
+
+#pragma mark - gesture and button action
+- (void)resetBottomGesture:(UIGestureRecognizer *)gestureRecognizer {
+    if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
+        [self setDefaultBottomViewStatus];
+    }
+}
+- (void)setDefaultBottomViewStatus {
+    [self.inputBar setInputBarStatus:KSBottomBarStatusDefault];
+    [self.inputBar setHidden:YES];
+}
+
+#pragma mark --- setter
+- (void)setIsHiddenHeadView:(BOOL)isHiddenHeadView {
+    if (_isHiddenHeadView == isHiddenHeadView) {
+        return;
+    }
+    _isHiddenHeadView = isHiddenHeadView;
+    //告知需要更改约束
+    [self.view setNeedsUpdateConstraints];
+    [UIView animateWithDuration:0.5 animations:^{
+        if (isHiddenHeadView) {
+            
+            [self.headView mas_updateConstraints:^(MASConstraintMaker *make) {
+                if (@available(iOS 11.0, *)) {
+                    make.top.mas_equalTo(self.videoContainerView.mas_safeAreaLayoutGuideTop).offset(-80);
+                } else {
+                    // Fallback on earlier versions
+                    make.top.mas_equalTo(self.videoContainerView.mas_top).offset(-80);
+                }
+            }];
+        }
+        else {
+            [self.headView mas_updateConstraints:^(MASConstraintMaker *make) {
+                if (@available(iOS 11.0, *)) {
+                    make.top.mas_equalTo(self.videoContainerView.mas_safeAreaLayoutGuideTop).offset(10);
+                } else {
+                    // Fallback on earlier versions
+                    make.top.mas_equalTo(self.videoContainerView.mas_top).offset(10);
+                }
+            }];
+        }
+        [self.headView.superview layoutIfNeeded];
+    }];
+}
+
+#pragma mark ----- landscape action
+- (void)transferToLandscape {
+    [self setDefaultBottomViewStatus];
+    [self changeOrientation:!self.landScape];
+}
+
+- (void)changeOrientation:(BOOL)isLandScape {
+    self.landScape = isLandScape;
+    if (isLandScape) {
+        // 切换到横屏
+        AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
+        delegate.allowAutoRotate = YES;
+        [UIDevice switchNewOrientation:UIInterfaceOrientationLandscapeRight inController:self];
+    }
+    else {
+        AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
+        delegate.allowAutoRotate = NO;
+        [UIDevice switchNewOrientation:UIInterfaceOrientationPortrait inController:self];
+    }
+    self.isHiddenHeadView = NO;
+    [self updateConstraint];
+}
+
+- (void)updateConstraint {
+    if (self.landScape) {
+        self.bottomView.hideChatView = YES;
+        self.messageContentView.hidden = YES;
+        self.headView.hideQuitButton = YES;
+        [self.videoView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            if (IS_IPAD) {
+                make.left.right.mas_equalTo(self.videoContainerView);
+                make.centerX.mas_equalTo(self.videoContainerView.mas_centerX);
+                CGFloat rate = 9 / 16.0f;
+                make.height.mas_equalTo(self.videoContainerView.mas_width).multipliedBy(rate);
+                make.width.height.mas_equalTo(self.videoContainerView).priorityLow();
+                make.width.height.lessThanOrEqualTo(self.videoContainerView);
+            }
+            else {
+                make.top.bottom.mas_equalTo(self.videoContainerView);
+                make.centerX.mas_equalTo(self.videoContainerView.mas_centerX);
+                // 宽高设置
+                CGFloat rate = 16 / 9.0f;
+                make.width.mas_equalTo(self.videoContainerView.mas_height).multipliedBy(rate);
+                make.width.height.mas_equalTo(self.videoContainerView).priorityLow();
+                make.width.height.lessThanOrEqualTo(self.videoContainerView);
+            }
+            
+        }];
+        [self.switchButton mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.right.mas_equalTo(self.videoContainerView.mas_right).offset(-10);
+            make.width.height.mas_equalTo(33);
+            make.centerY.mas_equalTo(self.videoView.mas_centerY);
+        }];
+        
+    }
+    else {
+        self.bottomView.hideChatView = NO;
+        self.messageContentView.hidden = NO;
+        self.headView.hideQuitButton = NO;
+        [self.videoView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.videoContainerView);
+            if (@available(iOS 11.0, *)) {
+                make.top.mas_equalTo(self.videoContainerView.mas_safeAreaLayoutGuideTop).offset(160);
+            } else {
+                // Fallback on earlier versions
+                make.top.mas_equalTo(self.videoContainerView.mas_top).offset(160);
+            }
+            CGFloat rate = 9 / 16.0f;
+            make.height.mas_equalTo(self.videoContainerView.mas_width).multipliedBy(rate);
+            make.width.height.mas_equalTo(self.videoContainerView).priorityLow();
+            make.width.height.lessThanOrEqualTo(self.videoContainerView);
+        }];
+        [self.switchButton mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.right.mas_equalTo(self.videoContainerView.mas_right).offset(-10);
+            make.width.height.mas_equalTo(33);
+            make.bottom.mas_equalTo(self.videoView.mas_bottom).offset(-10);
+        }];
+    }
+    
+    // 更新连麦UI
+    if ([self.videoContainerView.subviews containsObject:self.seatContainer]) {
+        [self updateSeatContainerConstraint];
+    }
+}
+
+- (void)showEmptyViewDisplay:(BOOL)isPublish {
+    NSString *imageName = @"";
+    NSString *descMessage = @"";
+    if (isPublish) {
+        imageName = @"liveVideo_close";
+        descMessage = @"主讲人已关闭画面!";
+    }
+    else {
+        imageName = @"liveroom_empty";
+        descMessage = @"休息一下,马上回来!";
+    }
+    [self.emptyView configViewWithImageName:imageName desc:descMessage];
+    [self hideTipsView];
+    self.videoView.hidden = YES;
+    self.emptyView.hidden = NO;
+}
+
+- (void)hideEmptyView {
+    self.emptyView.hidden = YES;
+    self.videoView.hidden = NO;
+}
+
+- (void)changeEmptyStatusView {
+    if (self.isCloseRoom == NO) { // 只有在非结束直播状态下
+        if (self.isPauseLive) {  // 暂停直播
+            [self showEmptyViewDisplay:NO];
+        }
+        else { // 如果未暂停直播
+            if (self.isCreaterVideoEnable) { // 如果摄像头开启
+                [self hideTipsView];
+                [self hideEmptyView];
+            }
+            else { // 主播关闭了摄像头
+                [self showEmptyViewDisplay:YES];
+            }
+        }
+        
+    }
+}
+
+- (void)renderSeatView {
+    
+    NSMutableArray *seatArray = [NSMutableArray array];
+    NSArray *remoteUserArray = [self.remoteMemberArray mutableCopy];
+    for (TXUISeatMember *member in remoteUserArray) {
+        [seatArray addObject:member];
+    }
+    
+    BOOL isContainSelf = NO;
+    for (TXUISeatMember *member in seatArray) {
+        if ([member.userId isEqualToString:UserDefault(IM_USERID)]) {
+            isContainSelf = YES;
+            break;
+        }
+    }
+    if (self.micStatus == MICSTATUS_CONNECTING && !isContainSelf) {
+        TXUISeatMember *currentMember = [[TXUISeatMember alloc] init];
+        currentMember.userId = UserDefault(IM_USERID);
+        currentMember.muteMic = !self.micEnable;
+        [seatArray addObject:currentMember];
+    }
+    NSLog(@"-- seat member--- %zd -", seatArray.count);
+    if (seatArray.count) {
+        if (![self.videoContainerView.subviews containsObject:self.seatContainer]) {
+            [self.videoContainerView addSubview:self.seatContainer];
+        }
+        [self updateSeatContainerConstraint];
+        
+//        self.seatContainer.seatMemberArray = [NSMutableArray arrayWithArray:seatArray];
+//        [self.seatContainer refreshSeatUI];
+        [self.seatContainer refreshSeatUIWithMember:[NSMutableArray arrayWithArray:seatArray]];
+    }
+    else {
+        [self removeSeatContainer];
+    }
+}
+
+// 移除连麦视图
+- (void)removeSeatContainer {
+    if ([self.videoContainerView.subviews containsObject:self.seatContainer]) {
+        [self.seatContainer removeFromSuperview];
+    }
+}
+- (void)updateSeatContainerConstraint {
+    if (self.landScape) {
+        [self.seatContainer mas_remakeConstraints:^(MASConstraintMaker *make) {
+            if (@available(iOS 11.0, *)) {
+                make.left.mas_equalTo(self.videoContainerView.mas_safeAreaLayoutGuideLeft);
+            } else {
+                // Fallback on earlier versions
+                make.left.mas_equalTo(self.videoContainerView.mas_left);
+            }
+            make.right.mas_equalTo(self.videoContainerView.mas_right).offset(-70);
+            if (@available(iOS 11.0, *)) {
+                make.top.mas_equalTo(self.videoContainerView.mas_safeAreaLayoutGuideTop).offset(85);
+            } else {
+                // Fallback on earlier versions
+                make.top.mas_equalTo(self.videoContainerView.mas_top).offset(85);
+            }
+            make.height.mas_equalTo(70);
+        }];
+    }
+    else {
+        [self.seatContainer mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.videoContainerView);
+            make.top.mas_equalTo(self.headView.mas_bottom).offset(0);
+            make.height.mas_equalTo(70);
+        }];
+    }
+}
+
+#pragma mark ----- 加入TRC房间
+- (void)enterLiveRTCRoom {
+    self.videoRenderView.hasMainStream = NO;
+    self.videoRenderView.hasSubStream = NO;
+    TRTCParams *parms = [[TRTCParams alloc] init];
+    parms.sdkAppId = CONFIG_TXSDKAPPID;
+    parms.userSig = self.UserSig;
+    parms.role = TRTCRoleAnchor;
+    parms.strRoomId = self.roomId;
+    parms.userId = UserDefault(IM_USERID);
+    self.trtcCloud.delegate = self;
+    [self config3AParams];
+    [self configVideoAndAudioSetting];
+    [self.trtcCloud enterRoom:parms appScene:TRTCAppSceneLIVE];
+    TRTCRenderParams *rendParams = [[TRTCRenderParams alloc] init];
+    
+    if (self.needSwitchButton) {
+        rendParams.fillMode = TRTCVideoFillMode_Fit;
+        
+    }
+    else {
+        rendParams.fillMode = TRTCVideoFillMode_Fill;
+    }
+    [self.trtcCloud setRemoteRenderParams:self.createrId streamType:TRTCVideoStreamTypeBig params:rendParams];
+    [self.trtcCloud setRemoteRenderParams:self.createrId streamType:TRTCVideoStreamTypeSub params:rendParams];
+
+}
+
+
+
+- (void)configVideoAndAudioSetting {
+    [self.trtcCloud startLocalAudio:TRTCAudioQualityMusic];
+    TRTCVideoEncParam *videoEncParam = [[TRTCVideoEncParam alloc] init];
+    videoEncParam.videoFps = 24;
+    videoEncParam.resMode = TRTCVideoResolutionModePortrait;
+    videoEncParam.videoResolution = TRTCVideoResolution_960_540;
+    [self.trtcCloud setVideoEncoderParam:videoEncParam];
+    
+    if (self.muteRoomMic) {
+        [self micButtonAction:self.muteRoomMic];
+    }
+}
+
+// 配置3A参数
+- (void)config3AParams {
+    [self configANSParm:self.ANS];
+    [self configAECParm:self.AEC];
+    [self configAGCParm:self.AGC];
+}
+
+// 背景音抑制
+- (void)configANSParm:(NSInteger)number {
+    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
+    [dic setValue:@"enableAudioANS" forKey:@"api"];
+    NSMutableDictionary *subDic = [NSMutableDictionary dictionary];
+    if (number > 0) {
+        [subDic setValue:@(1) forKey:@"enable"];
+        [subDic setValue:@(number) forKey:@"level"];
+    }
+    else {
+        [subDic setValue:@(0) forKey:@"enable"];
+        [subDic setValue:@(0) forKey:@"level"];
+    }
+    [dic setValue:subDic forKey:@"params"];
+    NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:kNilOptions error:nil];
+    NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+    [self.trtcCloud callExperimentalAPI:jsonString];
+}
+
+// 回声消除
+- (void)configAECParm:(NSInteger)number  {
+    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
+    [dic setValue:@"enableAudioAEC" forKey:@"api"];
+    NSMutableDictionary *subDic = [NSMutableDictionary dictionary];
+    if (number > 0) {
+        [subDic setValue:@(1) forKey:@"enable"];
+        [subDic setValue:@(number) forKey:@"level"];
+    }
+    else {
+        [subDic setValue:@(0) forKey:@"enable"];
+        [subDic setValue:@(0) forKey:@"level"];
+    }
+    [dic setValue:subDic forKey:@"params"];
+    NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:kNilOptions error:nil];
+    NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+    [self.trtcCloud callExperimentalAPI:jsonString];
+}
+
+// 自动增益
+- (void)configAGCParm:(NSInteger)number  {
+    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
+    [dic setValue:@"enableAudioAGC" forKey:@"api"];
+    NSMutableDictionary *subDic = [NSMutableDictionary dictionary];
+    if (number > 0) {
+        [subDic setValue:@(1) forKey:@"enable"];
+        [subDic setValue:@(number) forKey:@"level"];
+    }
+    else {
+        [subDic setValue:@(0) forKey:@"enable"];
+        [subDic setValue:@(0) forKey:@"level"];
+    }
+    [dic setValue:subDic forKey:@"params"];
+    NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:kNilOptions error:nil];
+    NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+    [self.trtcCloud callExperimentalAPI:jsonString];
+}
+
+#pragma mark -------- live message handle
+
+- (NSString *)getMsgClassName:(NSString *)messageObjectName {
+    TXLiveMessageModel *configModel = [[TXLiveMessageModel alloc] init];
+    NSString *className = [configModel getMessageClassName:messageObjectName];
+    return className;
+}
+/**
+ *  接收到消息的回调
+ */
+- (void)didReceiveMessageNotification:(NSNotification *)notification {
+    NSDictionary *dic = notification.object; /// __block TXLiveMessageModel *liveMessage
+    NSDictionary *content = [dic ks_dictionaryValueForKey:@"message"];
+    NSString *objectName = [content ks_stringValueForKey:@"objectName"];
+    NSString *className = [self getMsgClassName:objectName];
+    
+    __block TXLiveMessageModel *message = [[NSClassFromString(className) alloc] init];
+    message.messageId = [dic ks_stringValueForKey:@"msgID"];
+    message.groupId = [dic ks_stringValueForKey:@"groupID"];
+    [message evaluateSource:content];
+    
+    if ([message.groupId isEqualToString:self.roomId]) {
+        __weak typeof(&*self) __blockSelf = self;
+        dispatch_async(dispatch_get_main_queue(), ^{
+            if ([message isMemberOfClass:[TXLiveMessageLike class]]) {
+                TXLiveMessageLike *likeMessage = (TXLiveMessageLike *)message;
+                NSLog(@"receive like count ------- %d",likeMessage.counts);
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageLikeCount class]]) {
+
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageWelcome class]]) {
+                TXLiveMessageWelcome *welcomeMessage = (TXLiveMessageWelcome *)message;
+                //  过滤自己发送的欢迎消息
+                if ([welcomeMessage.userInfo.sendUserId isEqualToString:UserDefault(IM_USERID)]) {
+                    return;
+                }
+                
+                if ([welcomeMessage.userInfo.sendUserId isEqual:__blockSelf.createrId]) { // 如果是老师 重置连麦申请状态
+                    [__blockSelf resetMicWaitToNomal];
+                    __blockSelf.isCreateInRoom = YES;
+
+                }
+                NSString *userName = [welcomeMessage.userInfo.sendUserName stringByAppendingString:@""];
+                NSString *contentMsg = [NSString stringWithFormat:@"%@ 进入直播间",userName];
+                [__blockSelf showAnimationView:YES showMessag:contentMsg];
+                return;
+            }
+            // 用户退出消息
+            else if ([message isMemberOfClass:[TXLiveMessageLeave class]]) {
+//                TXLiveMessageLeave *userLeaveMsg = (TXLiveMessageLeave *)message;
+//                if ([userLeaveMsg.userInfo.sendUserId isEqualToString:__blockSelf.createrId]) {
+//                    __blockSelf.isCreateInRoom = NO;
+//                    // 下麦
+//                    if (__blockSelf.micStatus == MICSTATUS_CONNECTING) {
+//                        [__blockSelf downSeatAction];
+//                    }
+//                }
+                return;
+            }
+            // 用户退出回调
+            else if ([message isMemberOfClass:[TXLiveMessageUserQuit class]]) {
+//                TXLiveMessageUserQuit *userLeaveMsg = (TXLiveMessageUserQuit *)message;
+//                if ([userLeaveMsg.targetId isEqualToString:__blockSelf.createrId]) {
+//                    __blockSelf.isCreateInRoom = NO;
+//                    // 下麦
+//                    if (__blockSelf.micStatus == MICSTATUS_CONNECTING) {
+//                        [__blockSelf downSeatAction];
+//                    }
+//                }
+                return;
+            }
+            
+            else if ([message isMemberOfClass:[TXLiveMessageMemberUp class]]) {
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageStatSync class]]) { // 数据同步 不取点赞数
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageKickOut class]]) {
+                TXLiveMessageKickOut *kickMessage = (TXLiveMessageKickOut *)message;
+                NSString *currentUserId = UserDefault(IM_USERID);
+                if ([kickMessage.targetId isEqualToString:currentUserId]) {
+                    __blockSelf.micStatus = MICSTATUS_NOMAL;
+                    [__blockSelf kickOutLiveRoom];
+                }
+                return;
+            }
+            // 禁言控制
+            else if ([message isMemberOfClass:[TXLiveMessageChatBan class]]) {
+                TXLiveMessageChatBan *banMessage = (TXLiveMessageChatBan *)message;
+                if (banMessage.chatBan) { // 禁止发言
+                    __blockSelf.enableChat = NO;
+                }
+                else { // 开启发言
+                    __blockSelf.enableChat = YES;
+                }
+                [__blockSelf insertMessage:banMessage];
+            }
+            // 连麦控制消息
+            else if ([message isMemberOfClass:[TXLiveMessageSeatControl class]]) {
+                TXLiveMessageSeatControl *seatControlMessage = (TXLiveMessageSeatControl *)message;
+                if (seatControlMessage.seatBan) { // 禁止连麦
+                    __blockSelf.enableSeat = NO;
+                    // 未连麦情况下才重置
+                    if (__blockSelf.micStatus != MICSTATUS_CONNECTING) {
+                        // 如果在申请 发送取消申请消息
+                        if (__blockSelf.micStatus == MICSTATUS_WAITING) {
+                            [__blockSelf sendSeatMessageApply:NO];
+                        }
+                        __blockSelf.micStatus = MICSTATUS_NOMAL;
+                    }
+                    [__blockSelf hideApplyView];
+                    [__blockSelf hideApplyingView];
+                }
+                else { // 开启连麦
+                    __blockSelf.enableSeat = YES;
+                }
+                [__blockSelf insertMessage:seatControlMessage];
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageSeatApply class]]) {
+                
+                // 只处理主讲人发起的连麦邀请或取消操作
+                TXLiveMessageSeatApply *seatApplyMessage = (TXLiveMessageSeatApply *)message;
+                NSLog(@"----- RCChatroomSeatApply type:%ld audienceName:%@ ",seatApplyMessage.type,seatApplyMessage.audienceName);
+                // 只处理和自己相关的消息
+                if (![seatApplyMessage.audienceId isEqualToString:UserDefault(IM_USERID)]) {
+                    // 刷新麦序
+                    return;
+                }
+                if (seatApplyMessage.type == SEATHANDLE_INVITE) { // 主讲人发起申请
+                    NSString *titles = [NSString stringWithFormat:@"%@邀请您连麦",[NSString returnNoNullStringWithString:seatApplyMessage.teacherName]];
+                    [__blockSelf showInviteAlertMessage:titles];
+                }
+                else if (seatApplyMessage.type == SEATHANDLE_DISINVITE) { // 主讲人撤回申请
+                    [__blockSelf MBPShow:@"主讲人撤回了连麦申请"];
+                    [__blockSelf closeAlertView];
+                    if (__blockSelf.micStatus == MICSTATUS_CONNECTING) {
+                        [__blockSelf downSeatAction];
+                    }
+                }
+                else if (seatApplyMessage.type == SEATHANDLE_KICKSEAT) { // 主讲人断开连麦
+                    [__blockSelf kickSeatWithMessage:@"主讲人断开连麦"];
+                }
+                [__blockSelf hideApplyingView];
+                [__blockSelf insertMessage:seatApplyMessage];
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageSeatResponse class]]) { // 只处理主讲人的回应
+                TXLiveMessageSeatResponse *seatResponseMessage = (TXLiveMessageSeatResponse *)message;
+                NSLog(@"----- RCChatroomSeatResponse type:%ld audienceName:%@ ",seatResponseMessage.type,seatResponseMessage.audienceName);
+                if (![seatResponseMessage.audienceId isEqualToString:UserDefault(IM_USERID)]) { // 只处理和自己相关的消息
+                    return;
+                }
+                if (seatResponseMessage.type == SEATRESPONSE_TEACHERAPPROVE && __blockSelf.micStatus == MICSTATUS_WAITING) { //
+                    [__blockSelf hideApplyingView];
+                    [__blockSelf connectHostWithStatus:YES];
+                    [__blockSelf insertMessage:seatResponseMessage];
+                }
+                else if (seatResponseMessage.type == SEATRESPONSE_TEACHERREJECT) {
+                    [__blockSelf MBPShow:@"主讲人拒绝了您的连麦申请"];
+                    // 处理连麦状态
+                    [__blockSelf connectHostWithStatus:NO];
+                    [__blockSelf insertMessage:seatResponseMessage];
+                }
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageDownSeat class]]) {  // 成员主动下麦消息
+
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageClose class]]) { // 直播间已关闭
+                [__blockSelf MBPShow:@"直播已结束"];
+                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+                    // 显示直播间关闭状态
+                    [__blockSelf closeAlertView];
+                    [__blockSelf displayCloseView];
+                    [__blockSelf hideApplyingView];
+                });
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveTextMessage class]]) {
+                TXLiveTextMessage *textMessage = (TXLiveTextMessage *)message;
+                [__blockSelf insertMessage:textMessage];
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageCardMessage class]]) {
+                TXLiveMessageCardMessage *cardMessage = (TXLiveMessageCardMessage *)message;
+                [__blockSelf sendCardMessage:cardMessage.goodsContent];
+            }
+            else if ([message isMemberOfClass:[TXLiveMessagePauseLive class]]) { // 主讲人暂停直播
+//                __blockSelf.isPauseLive = YES;
+//                if (__blockSelf.micStatus == MICSTATUS_WAITING) {
+//                    [__blockSelf sendSeatMessageApply:NO];
+//                }
+//                [__blockSelf resetNetTips];
+//                [__blockSelf resetConnectionStatus];
+//                [__blockSelf closeAlertView];
+//                [__blockSelf hideApplyingView];
+//                [__blockSelf changeEmptyStatusView];
+//                [__blockSelf closePlayStatus];
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageOpenLive class]]) { // 开始直播
+//                __blockSelf.isPauseLive = NO;
+//                __blockSelf.isCreateInRoom = YES;
+//                [__blockSelf resetNetTips];
+//                [__blockSelf hideEmptyView];
+//                [__blockSelf startPlay];
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageShopRush class]]) { //
+
+                TXLiveMessageShopRush *rushMsg = (TXLiveMessageShopRush *)message;
+                
+                NSString *contentMsg = [NSString stringWithFormat:@"%@ 正在抢购",[NSString returnNoNullStringWithString:rushMsg.userInfo.sendUserName]];
+                [__blockSelf showAnimationView:NO showMessag:contentMsg];
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageBlockUser class]]) { // 黑名单
+                TXLiveMessageBlockUser *blockMessage = (TXLiveMessageBlockUser *)message;
+                if ([blockMessage.userId isEqualToString:UserDefault(IM_USERID)]) {
+                    __blockSelf.blacklistFlag = YES;
+                    [__blockSelf resetConnectionStatus];
+                }
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageUnBlockUser class]]) {
+                TXLiveMessageUnBlockUser *unBlockMessage = (TXLiveMessageUnBlockUser *)message;
+                if ([unBlockMessage.userId isEqualToString:UserDefault(IM_USERID)]) {
+                    __blockSelf.blacklistFlag = NO;
+                }
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageDownSeatAll class]]) { // 所有麦上用户下麦
+                TXLiveMessageDownSeatAll *downSeatMessage = (TXLiveMessageDownSeatAll *)message;
+                if (__blockSelf.micStatus == MICSTATUS_CONNECTING) {
+                    [__blockSelf kickSeatWithMessage:@"主讲人断开连麦"];
+                    [__blockSelf insertMessage:downSeatMessage];
+                }
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageRejectAllSeat class]]) { // 拒绝所有连麦申请
+                TXLiveMessageRejectAllSeat *rejectAllMessage = (TXLiveMessageRejectAllSeat *)message;
+                if (__blockSelf.micStatus == MICSTATUS_WAITING) {
+                    [__blockSelf MBPShow:@"主讲人拒绝了您的连麦申请"];
+                    // 处理连麦状态
+                    __blockSelf.micStatus = MICSTATUS_NOMAL;
+                    [__blockSelf insertMessage:rejectAllMessage];
+                    [__blockSelf hideApplyingView];
+                }
+            }
+            else if ([message isMemberOfClass:[TXControlMemberMic class]]) { // 控制学生麦克风
+                TXControlMemberMic *micCtrlMsg = (TXControlMemberMic *)message;
+                // 如果是控制当前学生的mic
+                if ([micCtrlMsg.userId isEqualToString:UserDefault(IM_USERID)]) {
+                    [__blockSelf changeCurrentMicStatus:micCtrlMsg.muteMic];
+                }
+            }
+            else if ([message isMemberOfClass:[TXLiveForceKickMsg class]]) {
+                TXLiveForceKickMsg *changeMsg = (TXLiveForceKickMsg *)message;
+                
+                if (changeMsg.targetIds.count == 0 || changeMsg.targetIds == nil) { // 如果是全员
+                    [__blockSelf courseChangeTips:changeMsg];
+                }
+                else {
+                    for (NSString *userId in changeMsg.targetIds) { // 如果部分学员中包含自己
+                        if ([userId isEqualToString:UserDefault(IM_USERID)]) {
+                            [__blockSelf courseChangeTips:changeMsg];
+                            break;
+                        }
+                    }
+                }
+            }
+        });
+    }
+}
+
+- (void)courseChangeTips:(TXLiveForceKickMsg *)msg {
+    // 显示直播间关闭状态
+    [self closeAlertView];
+    [self displayCloseView];
+    [self hideApplyingView];
+    // 退出房间
+    NSString *tipsMsg = [NSString isEmptyString:msg.reason] ? @"当前课程已调整,请退出直播间" : msg.reason;
+    MJWeakSelf;
+    self.closeAlert = [LiveRoomConfirmAlert liveroomAlertWithTitle:tipsMsg sureTitle:@"确定" inView:self.view confirm:^{
+        [weakSelf exitRoom];
+        [weakSelf.navigationController dismissViewControllerAnimated:YES completion:nil];
+    }];
+}
+
+- (void)changeCurrentMicStatus:(BOOL)isMute {
+    if (isMute == !self.micEnable) { // 如果麦克风状态和当前状态一致,剔除
+        return;
+    }
+    if (_trtcCloud && self.isAudience == NO) {
+        self.micEnable = !self.micEnable;
+        [self.trtcCloud muteLocalAudio:!self.micEnable];
+        NSString *desc = @"";
+        if (self.micEnable) {
+            desc = @"主讲人已将您的麦克风开启";
+        }
+        else {
+            desc = @"主讲人已将您的麦克风关闭";
+        }
+        [self MBPShow:desc];
+        [self syncMicStatus:!self.micEnable];
+    }
+}
+
+- (void)didReceiveGroupMessage:(NSNotification *)notification {
+    
+    NSDictionary *dic = notification.object; /// __block TXLiveMessageModel *liveMessage
+    
+    NSString *groupId = [dic ks_stringValueForKey:@"groupID"];
+    NSDictionary *content = [dic ks_dictionaryValueForKey:@"message"];
+    if ([groupId isEqualToString:self.roomId]) {
+        [self evaluateGroupInfo:content];
+    }
+}
+
+- (void)evaluateGroupInfo:(NSDictionary *)groupInfo {
+    //  主播在房间
+    if ([[groupInfo ks_stringValueForKey:@"LIVE_STATUS"] isEqualToString:@"ON"]) { // 直播中
+        self.isPauseLive = NO;
+        if (self.isAudience) {
+            [self startPlay];
+        }
+    }
+    else if ([[groupInfo ks_stringValueForKey:@"LIVE_STATUS"] isEqualToString:@"OFF"]) { // 暂停直播
+        self.isPauseLive = YES;
+        [self closePlayStatus];
+    }
+    
+    // 摄像头状态
+    if ([[groupInfo ks_stringValueForKey:@"ANCHOR_CAMERA"] isEqualToString:@"OFF"]) {
+        self.isCreaterVideoEnable = NO;
+    }
+    else {
+        self.isCreaterVideoEnable = YES;
+    }
+    
+    // 禁言状态
+    if ([[groupInfo ks_stringValueForKey:@"GLOBAL_BAN"] isEqualToString:@"ON"]) {
+        self.enableChat = NO;
+    }
+    else  {
+        self.enableChat = YES;
+    }
+    // 在线人数
+    if ([[groupInfo allKeys] containsObject:@"MEMBER_ONLINE"]) {
+        self.totalCount = [groupInfo ks_integerValueForKey:@"MEMBER_ONLINE"];
+        [self countMemberCount];
+    }
+    
+    [self changeEmptyStatusView];
+    
+    
+    // 主播全员闭麦状态
+    if ([[groupInfo allKeys] containsObject:@"ANCHOR_MIC"]) {
+        if ([[groupInfo ks_stringValueForKey:@"ANCHOR_MIC"] isEqualToString:@"ON"]) { // 禁麦
+            if (self.muteRoomMic == NO) {
+                self.muteRoomMic = YES;
+            }
+        }
+        else {
+            if (self.muteRoomMic == YES) {
+                self.muteRoomMic = NO;
+            }
+        }
+    }
+    else {
+        if (self.muteRoomMic == YES) {
+            self.muteRoomMic = NO;
+        }
+    }
+    
+}
+
+- (void)setMuteRoomMic:(BOOL)muteRoomMic {
+    _muteRoomMic = muteRoomMic;
+    [self changeCurrentMicStatus:muteRoomMic];
+}
+
+
+// 群属性变更信息
+- (void)didReceiveGroupCountMessage:(NSNotification *)notification {
+    NSDictionary *dic = notification.object; /// __block TXLiveMessageModel *liveMessage
+    
+    NSString *groupId = [dic ks_stringValueForKey:@"groupID"];
+    NSDictionary *content = [dic ks_dictionaryValueForKey:@"message"];
+    if ([groupId isEqualToString:self.roomId]) {
+        [self evaluateGroupCount:content];
+    }
+}
+
+- (void)evaluateGroupCount:(NSDictionary *)groupCount {
+    // 点赞数据
+    if ([[groupCount allKeys] containsObject:@"LIKES"]) {
+        self.likeCount = [groupCount ks_integerValueForKey:@"LIKES"];
+        [self countLikeMessageCount];
+    }
+}
+
+- (void)closePlayStatus {
+    if (self.micStatus == MICSTATUS_WAITING) {
+        [self sendSeatMessageApply:NO];
+    }
+    [self resetNetTips];
+    [self resetConnectionStatus];
+    [self closeAlertView];
+    [self hideApplyingView];
+    if (self.isAudience) {
+        [self stopPlay];
+    }
+    else {
+        if (_trtcCloud) {
+            [self.trtcCloud stopAllRemoteView];
+            [self.trtcCloud stopLocalAudio];
+            [self.trtcCloud exitRoom];
+        }
+    }
+}
+
+- (void)kickOutLiveRoom {
+    [self MBPShow:@"您已被踢出直播间"];
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        [self quitRoom];
+    });
+}
+
+#pragma mark ------ message operation
+- (void)resetConnectionStatus {
+    if (self.micStatus == MICSTATUS_CONNECTING) {
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+            [self sendDownSeatMsg];
+            [self connectHostWithStatus:NO];
+        });
+    }
+    else {
+        self.micStatus = MICSTATUS_NOMAL;
+        [self removeSeatContainer];
+    }
+}
+
+
+- (void)resetMicWaitToNomal {
+    if (self.micStatus == MICSTATUS_WAITING) {
+        self.micStatus = MICSTATUS_NOMAL;
+    }
+}
+- (void)tipsTeacherLeaveRoom {
+    [self MBPShow:@"主讲人已离开房间"];
+}
+
+- (void)hideApplyView {
+    if (self.applyView.isShow) {
+        [self.applyView hideView];
+    }
+}
+
+- (void)hideApplyingView {
+    if (self.applyingView.isShow) {
+        [self.applyingView hideView];
+    }
+}
+
+
+- (void)closeAlertView {
+    if (self.alertView && self.alertView.isShow) {
+        if (self.alertView.isQuitAlert == NO) {
+            [self.alertView removeFromSuperview];
+            self.alertView = nil;
+        }
+    }
+}
+
+- (void)displayCloseView {
+    self.isCloseRoom = YES;
+    [self hideTipsView];
+    // 移除连麦视图
+    [self removeSeatContainer];
+    if (self.micStatus != MICSTATUS_NOMAL) {
+        self.micStatus = MICSTATUS_NOMAL;
+        if (_trtcCloud) {
+            [self.trtcCloud stopLocalAudio];
+            [self.trtcCloud exitRoom];
+        }
+    }
+    [self stopPlay];
+    self.videoView.hidden = YES;
+    self.endView.hidden = NO;
+    [self setDefaultBottomViewStatus];
+    
+    [[NSNotificationCenter defaultCenter] postNotificationName:@"LiveroomClose" object:nil];
+}
+
+- (void)sendCardMessage:(NSArray *)content {
+//    if (_webContainer) {
+//        NSMutableDictionary *sendParm = [NSMutableDictionary dictionary];
+//        [sendParm setValue:@"cardChange" forKey:@"api"];
+//        [sendParm setValue:content forKey:@"content"];
+//        [self.webContainer postMessage:sendParm];
+//    }
+}
+
+- (void)showInviteAlertMessage:(NSString *)tipsMessage {
+    if (self.alertView && self.alertView.isShow) {
+        [self.alertView removeFromSuperview];
+        self.alertView = nil;
+    }
+    MJWeakSelf;
+    self.alertView = [LiveAlertView shareInstance];
+    [self.alertView alertWithTitle:@"连麦邀请" desc:tipsMessage leftButtonTitle:@"取消" rightTitle:@"确定" inView:self.view cancel:^{
+        weakSelf.micStatus = MICSTATUS_NOMAL;
+        [weakSelf sendSeatResponseMessage:NO];
+    } confirm:^{
+        [weakSelf sendSeatResponseMessage:YES];
+    }];
+}
+
+- (void)sendSeatResponseMessage:(BOOL)isApprove {
+    SEATRESPONSE type = isApprove ? SEATRESPONSE_AUDIENCEAPPROVE : SEATRESPONSE_AUDIENCEREJECT;
+    TXLiveMessageSeatResponse *responseMessage = [[TXLiveMessageSeatResponse alloc] init];
+    responseMessage.userInfo = [self getCurrentUser];
+    responseMessage.type = type;
+    responseMessage.audienceId = UserDefault(IM_USERID);
+    responseMessage.audienceName = UserDefault(NicknameKey);
+    MJWeakSelf;
+    [self sendCustomMessage:responseMessage priority:V2TIM_PRIORITY_HIGH displayMessage:YES callback:^(BOOL success) {
+        if (success) {
+            if (isApprove) {
+                [weakSelf connectHostWithStatus:YES];
+            }
+        }
+    }];
+    
+}
+
+- (void)kickSeatWithMessage:(NSString *)message {
+    [self MBPShow:message];
+    [self sendDownSeatMsg];
+    [self connectHostWithStatus:NO];
+}
+
+- (void)insertMessage:(TXLiveMessageModel *)liveMessage {
+    [self appendAndDisplayMessage:liveMessage];
+}
+
+
+
+#pragma mark table data source
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return self.conversationDataRepository.count;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    TXLiveMessageModel *model = [self.conversationDataRepository objectAtIndex:indexPath.row];
+    TXLiveChatListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TXLiveChatListCell"];
+    if (!cell) {
+        cell = [[TXLiveChatListCell appearance] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"TXLiveChatListCell"];
+    }
+    if ([model isMemberOfClass:[TXConstMessage class]] || [model isMemberOfClass:[TXLiveTextMessage class]] || [model isMemberOfClass:[TXLiveMessageWelcome class]] || [model isMemberOfClass:[TXLiveMessageLike class]] || [model isMemberOfClass:[TXLiveMessageSeatControl class]] ||[model isMemberOfClass:[TXLiveMessageChatBan class]] || [model isMemberOfClass:[TXLiveMessageSeatApply class]] || [model isMemberOfClass:[TXLiveMessageSeatResponse class]] || [model isMemberOfClass:[TXLiveMessageShopRush class]] || [model isMemberOfClass:[TXLiveMessageDownSeatAll class]] || [model isMemberOfClass:[TXLiveMessageRejectAllSeat class]] ){
+        [cell setDataModel:model createrId:self.createrId];
+    }
+    
+    return cell;
+}
+
+#pragma mark ----- lazying
+- (TRTCCloud *)trtcCloud {
+    if (!_trtcCloud) {
+        _trtcCloud = [TRTCCloud sharedInstance];
+        _trtcCloud.delegate = self;
+    }
+    return _trtcCloud;
+}
+- (V2TXLivePlayer *)livePlayer {
+    if (!_livePlayer) {
+        _livePlayer = [[V2TXLivePlayer alloc] init];
+        [_livePlayer enableReceiveSeiMessage:YES payloadType:243];
+        [_livePlayer setObserver:self];
+        
+    }
+    return _livePlayer;
+}
+
+- (UIView *)videoContainerView {
+    if (!_videoContainerView) {
+        _videoContainerView = [[UIView alloc] initWithFrame:CGRectZero];
+        _videoContainerView.backgroundColor = [UIColor clearColor];
+    }
+    return _videoContainerView;
+}
+
+- (UIView *)videoView {
+    if (!_videoView) {
+        _videoView = [[UIView alloc] initWithFrame:CGRectZero];
+        _videoView.backgroundColor = HexRGB(0x1a1a1a);
+    }
+    return _videoView;
+}
+
+- (TXLiveVideoView *)videoRenderView {
+    if (!_videoRenderView) {
+        _videoRenderView = [[TXLiveVideoView alloc] initWithFrame:CGRectZero];
+    }
+    return _videoRenderView;
+}
+
+- (LiveRoomHeadView *)headView {
+    if (!_headView) {
+        _headView = [LiveRoomHeadView shareInstance];
+        MJWeakSelf;
+        [_headView quitAction:^{
+            [weakSelf showQuitAlert];
+        }];
+    }
+    return _headView;
+}
+
+- (void)showQuitAlert {
+    if (self.isCloseRoom) { // 如果直播结束 直接点击退出房间
+        [self quitRoom];
+    }
+    else if (self.micStatus == MICSTATUS_CONNECTING) {
+        [self quitAction];
+    }
+    else {
+        MJWeakSelf;
+        self.alertView = [LiveAlertView shareInstance];
+        self.alertView.isQuitAlert = YES;
+        [self.alertView alertWithTitle:@"确定要退出直播间吗?" desc:@"退出后如再次观看可重新进入~" leftButtonTitle:@"取消" rightTitle:@"确认" inView:self.view cancel:^{
+            
+        } confirm:^{
+            [weakSelf quitAction];
+            
+        }];
+        
+    }
+}
+
+- (void)quitRoom {
+    KSDragWindowManager *manager = [KSDragWindowManager sharedManager];
+    if (manager.hasShowWindow) {
+        [manager resignDragWindow];
+    }
+    
+    if (self.landScape) {
+        [self changeOrientation:!self.landScape];
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+
+            // 退出房间
+            [self exitRoom];
+            [self.navigationController dismissViewControllerAnimated:YES completion:nil];
+        });
+    }
+    else {
+        // 退出房间
+        [self exitRoom];
+        [self.navigationController dismissViewControllerAnimated:YES completion:nil];
+    }
+}
+
+// 顶部退出房间
+- (void)quitAction {
+    if (self.micStatus == MICSTATUS_CONNECTING) {
+        MJWeakSelf;
+        self.alertView = [LiveAlertView shareInstance];
+        [self.alertView alertWithTitle:@"提示" desc:@"连麦中,是否退出房间?" leftButtonTitle:@"取消" rightTitle:@"确定" inView:self.view cancel:^{
+            
+        } confirm:^{
+            [weakSelf quitRoom];
+            
+        }];
+    }
+    else {
+        [self quitRoom];
+    }
+    
+}
+
+- (void)exitRoom {
+    if (self.isAudience) {
+        [self stopPlay];
+    }
+    else {
+        if (_trtcCloud) {
+            [self.trtcCloud stopLocalAudio];
+            [self.trtcCloud exitRoom];
+        }
+    }
+    TXLiveMessageLeave *leaveMsg = [[TXLiveMessageLeave alloc] init];
+    leaveMsg.userInfo = [self getCurrentUser];
+    MJWeakSelf;
+    [self sendCustomMessage:leaveMsg priority:V2TIM_PRIORITY_NORMAL displayMessage:NO callback:^(BOOL success) {
+        // quit 接口
+        [weakSelf quitNotiferService];
+        [weakSelf quitChatRoom];
+    }];
+}
+
+- (void)quitChatRoom {
+    [[V2TIMManager sharedInstance] quitGroup:self.roomId succ:^{
+        
+    } fail:^(int code, NSString *desc) {
+        
+    }];
+}
+
+- (LiveRoomBottomView *)bottomView {
+    if (!_bottomView) {
+        _bottomView = [LiveRoomBottomView shareInstance];
+        MJWeakSelf;
+        [_bottomView bottomClickAction:^(LIVEROOMACTION action) {
+            [weakSelf bottomViewAction:action];
+        }];
+    }
+    return _bottomView;
+}
+
+- (void)bottomViewAction:(LIVEROOMACTION)action {
+    if (self.isCloseRoom) {
+        [self MBPShow:@"直播已结束"];
+        return;
+    }
+    if (action == LIVEROOMACTION_CHAT) {
+        if (self.blacklistFlag == YES) {
+            [self MBPShow:@"您已被管理员禁言"];
+            return;
+        }
+        if (self.enableChat) { // 判断是否全员禁言
+            [_inputBar setHidden:NO];
+            [_inputBar setInputBarStatus:KSBottomBarStatusKeyboard];
+        }
+        else {
+            [self MBPShow:@"管理员关闭聊天"];
+        }
+    }
+    else if (action == LIVEROOMACTION_SEAT) { // 连麦按钮
+        // 判断是否是连麦状态
+        if (self.micStatus == MICSTATUS_CONNECTING) { // 连麦中
+            // 是否取消连麦
+            MJWeakSelf;
+            self.alertView = [LiveAlertView shareInstance];
+            [self.alertView alertWithTitle:@"连麦中,确认取消连麦吗?" desc:@"断开后如想再次连麦可重新发起" leftButtonTitle:@"取消" rightTitle:@"确定关闭" inView:self.view cancel:^{
+                
+            } confirm:^{
+                [weakSelf downSeatAction];
+            }];
+        }
+        else if (self.micStatus == MICSTATUS_WAITING) { // 连麦申请中
+            // 弹窗取消申请
+            [self displayApplyingView];
+        }
+        else {
+            // 禁止聊天可以连麦(测试确认)
+            if (self.blacklistFlag == YES) {
+                [self MBPShow:@"您已被管理员禁言"];
+                return;
+            }
+            if (self.isPauseLive == YES) {
+                [self MBPShow:@"老师暂停中,暂时无法接受申请"];
+                return;
+            }
+            
+            if (self.enableSeat) {
+                [self displaySeatApplyView];
+            }
+            else {
+                [self MBPShow:@"管理员关闭连麦申请"];
+            }
+        }
+    }
+    else if (action == LIVEROOMACTION_LIKE) { // 点赞
+        
+        [self praiseBtnPressed];
+    }
+    else if (action == LIVEROOMACTION_SHOP) { // shop
+        [self showCartAlert];
+    }
+    else if (action == LIVEROOMACTION_MUTE) {
+        [self muteVoiceAction];
+    }
+}
+
+- (void)showCartAlert {
+    [self.cardView showViewInView:self.view];
+}
+- (void)downSeatAction {
+    [self sendDownSeatMsg];
+    [self connectHostWithStatus:NO];
+}
+
+
+- (void)sendDownSeatMsg {
+    TXLiveMessageDownSeat *downSeatMsg = [[TXLiveMessageDownSeat alloc] init];
+    TXLiveUser *mineInfo = [self getCurrentUser];
+    downSeatMsg.userInfo = mineInfo;
+    downSeatMsg.audienceId = mineInfo.sendUserId;
+    downSeatMsg.audienceName = mineInfo.sendUserName;
+   
+    [self sendCustomMessage:downSeatMsg priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+            
+    }];
+}
+
+- (KSShopCardView *)cardView {
+    if (!_cardView) {
+        _cardView = [KSShopCardView shareInstance];
+        MJWeakSelf;
+        [_cardView clickAction:^(CART_TYPE type) {
+            [weakSelf displayTeacherInfo:type];
+        }];
+    }
+    return _cardView;
+}
+// tabs=  practice | 陪练课 live | 直播课 video | 视频课 music | 乐谱 跳转到对应tab页
+
+- (void)displayTeacherInfo:(CART_TYPE)type {
+    [self sendRushMessage];
+    if (self.isPauseLive == NO) {
+        _hasShowSuspendView = YES;
+        KSDragWindowManager *manager = [KSDragWindowManager sharedManager];
+        BOOL isPhoneLive = self.needSwitchButton ? NO : YES;
+        [manager initDragWindowWithPhoneLive:isPhoneLive];
+        manager.rootVC = (CustomNavViewController *)self.navigationController;
+
+        [self.videoRenderView removeFromSuperview];
+        [manager.dragWindow.containerView addSubview:self.videoRenderView];
+        [self.videoRenderView mas_updateConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.bottom.mas_equalTo(manager.dragWindow.containerView);
+        }];
+        [manager.dragWindow bringSubviewToFront:manager.dragWindow.cancelButton];
+    }
+    
+    NSString *tabs = @"";
+    switch (type) {
+        case CART_TYPE_NONE:
+        {
+            tabs = @"";
+        }
+            break;
+        case CART_TYPE_ACCOMPANY:
+        {
+            tabs = @"practice";
+        }
+            break;
+        case CART_TYPE_LIVE:
+        {
+            tabs = @"live";
+        }
+            break;
+        case CART_TYPE_VIDEO:
+        {
+            tabs = @"video";
+        }
+            break;
+        case CART_TYPE_MUSIC:
+        {
+            tabs = @"music";
+        }
+            break;
+        default:
+            break;
+    }
+    NSString *url = @"";
+    if ([NSString isEmptyString:tabs]) {
+        url = [NSString stringWithFormat:@"%@%@%@", WEBHOST,@"/#/teacherHome?teacherId=",self.createrId];
+    }
+    else {
+        url = [NSString stringWithFormat:@"%@%@%@&tabs=%@", WEBHOST,@"/#/teacherHome?teacherId=",self.createrId,tabs];
+    }
+    KSLiveWebViewController *ctrl = [[KSLiveWebViewController alloc] init];
+    ctrl.url = url;
+    [self.navigationController pushViewController:ctrl animated:YES];
+}
+- (void)sendRushMessage {
+    TXLiveMessageShopRush *rushMessage = [[TXLiveMessageShopRush alloc] init];
+    rushMessage.userInfo = [self getCurrentUser];
+    [self sendCustomMessage:rushMessage priority:V2TIM_PRIORITY_DEFAULT displayMessage:NO callback:^(BOOL success) {
+            
+    }];
+}
+
+- (void)toDetailView:(NSString *)linkUrl {
+    [self sendRushMessage];
+    
+    if (self.isPauseLive == NO) {
+        _hasShowSuspendView = YES;
+        KSDragWindowManager *manager = [KSDragWindowManager sharedManager];
+        BOOL isPhoneLive = self.needSwitchButton ? NO : YES;
+        [manager initDragWindowWithPhoneLive:isPhoneLive];
+        manager.rootVC = (CustomNavViewController *)self.navigationController;
+
+        [self.videoRenderView removeFromSuperview];
+        [manager.dragWindow.containerView addSubview:self.videoRenderView];
+        [self.videoRenderView mas_updateConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.bottom.mas_equalTo(manager.dragWindow.containerView);
+        }];
+        [manager.dragWindow bringSubviewToFront:manager.dragWindow.cancelButton];
+    }
+    KSLiveWebViewController *ctrl = [[KSLiveWebViewController alloc] init];
+    ctrl.url = linkUrl;
+    [self.navigationController pushViewController:ctrl animated:YES];
+}
+
+
+- (void)muteVoiceAction {
+    if (self.bottomView.isMute) {
+        if ([self.livePlayer isPlaying]) {
+            [self.livePlayer setPlayoutVolume:0];
+        }
+        if (_trtcCloud) {
+            [self.trtcCloud muteAllRemoteAudio:YES];
+        }
+    }
+    else {
+        if ([self.livePlayer isPlaying]) {
+            [self.livePlayer setPlayoutVolume:100];
+        }
+        if (_trtcCloud) {
+            [self.trtcCloud muteAllRemoteAudio:NO];
+        }
+    }
+}
+
+- (KSLiveEmptyView *)emptyView {
+    if (!_emptyView) {
+        _emptyView = [[KSLiveEmptyView alloc] init];
+        BOOL isPhoneLive = self.needSwitchButton ? NO : YES;
+        [_emptyView dispPlayViewIsPhoneLive:isPhoneLive];
+    }
+    return _emptyView;
+}
+
+- (KSLiveEndView *)endView {
+    if (!_endView) {
+        _endView = [[KSLiveEndView alloc] init];
+        _endView.backgroundColor = HexRGB(0x25292e);
+        BOOL isPhoneLive = self.needSwitchButton ? NO : YES;
+        [_endView dispPlayViewIsPhoneLive:isPhoneLive];
+    }
+    return _endView;
+}
+
+- (KSLiveBadNetView *)netBadView {
+    if (!_netBadView) {
+        _netBadView = [[KSLiveBadNetView alloc] init];
+        BOOL isPhoneLive = self.needSwitchButton ? NO : YES;
+        [_netBadView dispPlayViewIsPhoneLive:isPhoneLive];
+        MJWeakSelf;
+        [_netBadView configViewWithImageName:@"liveVideo_close" desc:@"视频加载失败" callback:^{
+            [weakSelf resetAllConnection];
+        }];
+    }
+    return _netBadView;
+}
+
+- (void)resetNetTips {
+    [self hideTipsView];
+}
+
+- (void)showBadNetTips {
+    dispatch_main_async_safe(^{
+        if (self.isCloseRoom == NO) {
+            if (self.netBadView.hidden == YES) {
+                self.netBadView.hidden = NO;
+                self.videoView.hidden = YES;
+            }
+        }
+    });
+}
+
+- (void)hideTipsView {
+    dispatch_main_async_safe(^{
+        if (self.netBadView.hidden == NO) {
+            self.netBadView.hidden = YES;
+            self.videoView.hidden = NO;
+        }
+    })
+    
+}
+// 黑名单
+- (void)setBlacklistFlag:(BOOL)blacklistFlag {
+    _blacklistFlag = blacklistFlag;
+    [self refreshBottomChatStatus];
+}
+
+- (void)refreshBottomChatStatus {
+    if (self.bottomView) {
+        NSString *tipsTitle = self.blacklistFlag ? @"您已被管理员禁言" : @"快来互动吧!";
+        self.bottomView.tipsLabel.text = tipsTitle;
+        self.bottomView.tipsLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
+    }
+}
+
+
+- (void)resetAllConnection {
+    [self resetNetTips];
+    // 清理视图
+    [self hideEmptyView];
+    [self removeSeatContainer];
+    
+    // 立刻房间后重新加入房间
+    [self startPlay];
+}
+
+- (LOTAnimationView *)animationView {
+    if (!_animationView) {
+        _animationView = [LOTAnimationView animationWithFilePath:[[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"LiveCard" ofType:@"bundle"]] pathForResource:@"cardAnimation" ofType:@"json"]];
+        _animationView.loopAnimation = YES;
+    }
+    return _animationView;
+}
+
+- (UIButton *)switchButton {
+    if (!_switchButton) {
+        _switchButton = [UIButton buttonWithType:UIButtonTypeCustom];
+        [_switchButton setImage:[UIImage imageNamed:@"live_switch"] forState:UIControlStateNormal];
+        [_switchButton addTarget:self action:@selector(transferToLandscape) forControlEvents:UIControlEventTouchUpInside];
+    }
+    return _switchButton;
+}
+
+- (UIView *)messageContentView {
+    if (!_messageContentView) {
+        _messageContentView = [[UIView alloc] init];
+        [_messageContentView setBackgroundColor: [UIColor clearColor]];
+    }
+    return _messageContentView;
+}
+
+- (UITableView *)conversationMessageTableView {
+    if (!_conversationMessageTableView) {
+        _conversationMessageTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
+        _conversationMessageTableView.backgroundColor = [UIColor clearColor];
+        _conversationMessageTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+        _conversationMessageTableView.dataSource = self;
+        _conversationMessageTableView.delegate = self;
+        _conversationMessageTableView.rowHeight = UITableViewAutomaticDimension;
+        _conversationMessageTableView.estimatedRowHeight = 40.0f;
+        _conversationMessageTableView.showsVerticalScrollIndicator = NO;
+        [_conversationMessageTableView registerClass:[TXLiveChatListCell class] forCellReuseIdentifier:@"TXLiveChatListCell"];
+    }
+    return _conversationMessageTableView;
+}
+
+- (NSMutableArray<TXLiveMessageModel *> *)conversationDataRepository {
+    if (!_conversationDataRepository) {
+        _conversationDataRepository = [NSMutableArray array];
+    }
+    return _conversationDataRepository;
+}
+
+- (TXSeatContainerView *)seatContainer {
+    if (!_seatContainer) {
+        _seatContainer = [[TXSeatContainerView alloc] init];
+        MJWeakSelf;
+        [_seatContainer seatActionCallback:^(NSString * _Nonnull userId, BOOL muteMic) {
+            [weakSelf muteUserAction:userId muteStatus:muteMic];
+        }];
+    }
+    return _seatContainer;
+}
+
+- (void)muteUserAction:(NSString *)userId muteStatus:(BOOL)muteMic {
+    [self micButtonAction:muteMic];
+    TXMicStatusSync *ctrlMsg = [[TXMicStatusSync alloc] init];
+    ctrlMsg.userInfo = [self getCurrentUser];
+    ctrlMsg.userId = userId;
+    ctrlMsg.muteMic = muteMic;
+    [self sendCustomMessage:ctrlMsg priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+        
+    }];
+}
+
+- (KSChatInputBarControl *)inputBar {
+    if (!_inputBar) {
+        _inputBar = [[KSChatInputBarControl alloc] initWithStatus:KSBottomBarStatusDefault];
+        [_inputBar setDelegate:self];
+    }
+    return _inputBar;
+}
+
+- (void)setMicStatus:(MICSTATUS)micStatus {
+    _micStatus = micStatus;
+    if (self.bottomView) {
+        switch (micStatus) {
+            case MICSTATUS_NOMAL:
+            {
+                [self.bottomView.seatButton setImage:[UIImage imageNamed:@"seat_image"] forState:UIControlStateNormal];
+            }
+                break;
+            case MICSTATUS_WAITING:
+            {
+                [self.bottomView.seatButton setImage:[UIImage imageNamed:@"seat_connecting"] forState:UIControlStateNormal];
+            }
+                break;
+            case MICSTATUS_CONNECTING:
+            {
+                [self.bottomView.seatButton setImage:[UIImage imageNamed:@"seat_connected"] forState:UIControlStateNormal];
+            }
+                break;
+            default:
+                break;
+        }
+    }
+}
+#pragma mark ----- 人数和点赞数统计
+- (void)countLikeMessageCount {
+    NSInteger count = self.likeCount;
+    NSString *desc = @"";
+    if (count > 10000) {
+        count = count / 10000;
+        desc = [NSString stringWithFormat:@"本场点赞%zd万+",count];
+    }
+    else {
+        desc = [NSString stringWithFormat:@"本场点赞%zd",count];
+    }
+    self.headView.likeCount.text = desc;
+}
+
+- (void)countMemberCount {
+    NSInteger count = self.totalCount;
+    NSString *desc = @"";
+    if (count > 10000) {
+        count = count / 10000;
+        desc = [NSString stringWithFormat:@"%zd万+人",count];
+    }
+    else {
+        desc = [NSString stringWithFormat:@"%zd人",count];
+    }
+    self.headView.roomMemberCount.text = desc;
+}
+
+/**
+ *  判断消息是否在collectionView的底部
+ *
+ *  @return 是否在底部
+ */
+- (BOOL)isAtTheBottomOfTableView {
+    if (self.conversationMessageTableView.contentSize.height <= self.conversationMessageTableView.frame.size.height) {
+        return YES;
+    }
+    if(self.conversationMessageTableView.contentOffset.y +200 >= (self.conversationMessageTableView.contentSize.height - self.conversationMessageTableView.frame.size.height)) {
+        return YES;
+    }else{
+        return NO;
+    }
+}
+
+/**
+ *  消息滚动到底部
+ *
+ *  @param animated 是否开启动画效果
+ */
+- (void)scrollToBottomAnimated:(BOOL)animated {
+    if ([self.conversationMessageTableView numberOfSections] == 0) {
+        return;
+    }
+    NSUInteger finalRow = MAX(0, [self.conversationMessageTableView numberOfRowsInSection:0] - 1);
+    if (0 == finalRow) {
+        return;
+    }
+    NSIndexPath *finalIndexPath =
+    [NSIndexPath indexPathForItem:finalRow inSection:0];
+    [self.conversationMessageTableView scrollToRowAtIndexPath:finalIndexPath atScrollPosition:UITableViewScrollPositionTop animated:animated];
+}
+
+
+#pragma mark ---- dealloc
+- (void)dealloc {
+    NSLog(@"---- live room dealloc");
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+    if (_livePlayer) {
+        [self.livePlayer stopPlay];
+        _livePlayer = nil;
+    }
+    if (_trtcCloud) {
+        [self.trtcCloud stopAllRemoteView];
+        [self.trtcCloud stopLocalAudio];
+        [self.trtcCloud exitRoom];
+        _trtcCloud = nil;
+        [TRTCCloud destroySharedIntance];
+    }
+    [TXIM_LINSENTER logoutTXIM];
+}
+
+
+#pragma mark - KSChatInputBarControlDelegate
+//  根据inputBar 回调来修改页面布局
+- (void)onInputBarControlContentSizeChanged:(CGRect)frame withAnimationDuration:(CGFloat)duration andAnimationCurve:(UIViewAnimationCurve)curve {
+    CGRect originFrame = _inputBar.frame;
+    __weak __typeof(&*self)weakSelf = self;
+    //  目前只使用y值即可 -- 只修改messageContentView高度,让展示消息view和输入框随之移动
+    [UIView animateWithDuration:duration animations:^{
+        [UIView setAnimationCurve:curve];
+        [weakSelf.inputBar setFrame:CGRectMake(0, frame.origin.y - originFrame.size.height, originFrame.size.width, originFrame.size.height)];
+        [UIView commitAnimations];
+    }];
+}
+//  发送消息
+- (void)onTouchSendButton:(NSString *)text {
+    if (self.blacklistFlag == YES) {
+        [self setDefaultBottomViewStatus];
+        return;
+    }
+    NSDate *date = [NSDate date];
+    NSTimeInterval currentInterval = [date timeIntervalSince1970];
+    if (currentInterval - self.lastSendMsgTime < 3) {
+        [self MBPShow:@"您说话太快啦"];
+        return;
+    }
+    
+    if (self.lastSendMsgTime == 0) {
+        self.lastSendMsgTime = currentInterval;
+    }
+    
+    if (text.length > 40) {
+        [self MBPShow:@"聊天消息需在40个字以内哦"];
+        return;
+    }
+    if (self.enableChat) {
+        self.lastSendMsgTime = currentInterval;
+        [self touristSendMessage:text];
+    }
+    else {
+        [self setDefaultBottomViewStatus];
+    }
+}
+
+
+- (void)touristSendMessage:(NSString *)text {
+    TXLiveTextMessage *message = [[TXLiveTextMessage alloc] init];
+    message.userInfo = [self getCurrentUser];
+    message.text = text;
+    MJWeakSelf;
+    [self sendTextMessage:message priority:V2TIM_PRIORITY_NORMAL displayMessage:YES callback:^(BOOL success) {
+        [weakSelf setDefaultBottomViewStatus];
+    }];
+}
+
+
+- (TXLiveUser *)getCurrentUser {
+    TXLiveUser *user = [[TXLiveUser alloc] init];
+    user.sendUserId = UserDefault(IM_USERID);
+    user.sendUserName = UserDefault(NicknameKey);
+    user.avatarUrl = UserDefault(AvatarUrlKey);
+    return user;
+}
+/**
+ 点赞
+ */
+- (void)praiseBtnPressed {
+    if (self.enableLike == NO) {
+        [self MBPShow:@"管理员已关闭点赞功能"];
+        return;
+    }
+    NSTimeInterval currentTime =  [[NSDate date] timeIntervalSince1970];
+    __weak __typeof(&*self)weakSelf = self;
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.21 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        if ([[NSDate date] timeIntervalSince1970] - self.lastClickPraiseTime >= 0.2) {
+
+            [weakSelf modifyLikeCount:clickPraiseBtnTimes];
+            clickPraiseBtnTimes = 0;
+        }
+    });
+    clickPraiseBtnTimes++;
+    self.lastClickPraiseTime = currentTime;
+    [self presentLikeMessageAnimation];
+}
+
+
+- (void)modifyLikeCount:(NSInteger)count {
+    [[V2TIMManager sharedInstance] increaseGroupCounter:self.roomId key:@"LIKES" value:count succ:^(NSDictionary<NSString *,NSNumber *> *groupCounters) {
+        
+    } fail:^(int code, NSString *desc) {
+        
+    }];
+}
+
+/**
+ 赞动画
+ */
+- (void)presentLikeMessageAnimation {
+    LiveRoomLikeLayer *layer = [[LiveRoomLikeLayer alloc] initWithName:@"Like"];
+    [self.videoContainerView.layer addSublayer:layer];
+    CGRect tempFrame = [self.videoContainerView convertRect:self.bottomView.likeButton.frame fromView:self.bottomView];
+    CGFloat width = tempFrame.size.width;
+    CGFloat height = tempFrame.size.height;
+    
+    CGFloat dx = CGRectGetMidX(tempFrame) - width *0.5;
+    CGFloat dy = CGRectGetMidY(tempFrame) - 8 - height;
+    layer.frame = CGRectMake(dx, dy, width, height);
+    [layer startAnimation];
+}
+
+- (void)displaySeatApplyView {
+    [self.applyView showInView:self.view];
+}
+
+- (void)displayApplyingView {
+    [self.applyingView showInView:self.view];
+}
+
+- (LiveApplyView *)applyView {
+    if (!_applyView) {
+        _applyView = [LiveApplyView shareInstance];
+        MJWeakSelf;
+        [_applyView applySeatCallback:^{
+            [weakSelf applySeatAction];
+        }];
+    }
+    return _applyView;
+}
+
+- (void)applySeatAction {
+    [self sendSeatMessageApply:YES];
+}
+
+- (void)sendSeatMessageApply:(BOOL)isApply {
+    if (self.micStatus == MICSTATUS_CONNECTING) {
+        [self MBPShow:@"您已上麦"];
+        return;
+    }
+    SEATHANDLE type = isApply ? SEATHANDLE_APPLY : SEATHANDLE_CANCELAPPLY;
+    TXLiveMessageSeatApply *applyMessage = [[TXLiveMessageSeatApply alloc] init];
+    applyMessage.type = type;
+    applyMessage.audienceId = UserDefault(IM_USERID);
+    applyMessage.audienceName = UserDefault(NicknameKey);
+    applyMessage.audienceAvatar = UserDefault(AvatarUrlKey);
+    applyMessage.teacherId = self.createrId;
+    applyMessage.teacherName = self.createrName;
+    applyMessage.userInfo = [self getCurrentUser];
+    MJWeakSelf;
+    [self sendCustomMessage:applyMessage priority:V2TIM_PRIORITY_HIGH displayMessage:YES callback:^(BOOL success) {
+        if (success) {
+            weakSelf.micStatus = isApply ? MICSTATUS_WAITING : MICSTATUS_NOMAL;
+        }
+    }];
+}
+
+- (LiveApplyingView *)applyingView {
+    if (!_applyingView) {
+        _applyingView = [LiveApplyingView shareInstance];
+        NSString *avatar = UserDefaultObjectForKey(AvatarUrlKey);
+        [_applyingView.myAvatal sd_setImageWithURL:[NSURL URLWithString:[avatar getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:USERDEFAULT_LOGO]];
+        [_applyingView.teacherAvatal sd_setImageWithURL:[NSURL URLWithString:[self.createrAvatal getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:USERDEFAULT_LOGO]];
+        MJWeakSelf;
+        [_applyingView cancleApplyCallback:^{
+            [weakSelf cancleApplyAction];
+        }];
+    }
+    return _applyingView;
+}
+
+- (void)cancleApplyAction {
+    MJWeakSelf;
+    self.alertView = [LiveAlertView shareInstance];
+    [self.alertView alertWithTitle:@"连麦申请中,确认取消连麦申请吗?" desc:@"断开后如想再次连麦可重新发起" leftButtonTitle:@"取消" rightTitle:@"确定关闭" inView:self.view cancel:^{
+        
+    } confirm:^{
+        [weakSelf.applyingView hideView];
+        [weakSelf sendSeatMessageApply:NO];
+    }];
+}
+
+#pragma mark ---- sendMessage/showMessage
+// 文本消息
+- (void)sendTextMessage:(TXLiveMessageModel *)messageContent priority:(V2TIMMessagePriority)priority displayMessage:(BOOL)displayMessage callback:(void(^)(BOOL success))callback {
+    NSData *msgData = [messageContent encodeMessage];
+    if (msgData == nil) {
+        return;
+    }
+    __weak typeof(&*self) __weakself = self;
+    [TXLiveMessageCenter sendLiveChatMessage:msgData groupId:self.roomId priority:priority success:^{
+        dispatch_async(dispatch_get_main_queue(), ^{
+            
+            if (displayMessage) {
+                [__weakself appendAndDisplayMessage:messageContent];
+            }
+            [__weakself.inputBar clearInputView];
+            callback(YES);
+        });
+    } failer:^(int code, NSString * _Nonnull msg) {
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [__weakself.inputBar clearInputView];
+            NSLog(@"发送失败,errorcode is: %d message: %@",code, msg);
+            callback(NO);
+        });
+    }];
+}
+
+// 其他消息
+- (void)sendCustomMessage:(TXLiveMessageModel *)messageContent priority:(V2TIMMessagePriority)priority displayMessage:(BOOL)displayMessage callback:(void(^)(BOOL success))callback {
+    NSData *msgData = [messageContent encodeMessage];
+    if (msgData == nil) {
+        return;
+    }
+    __weak typeof(&*self) __weakself = self;
+    [TXLiveMessageCenter sendLiveChatMessage:msgData groupId:self.roomId priority:priority success:^{
+        dispatch_async(dispatch_get_main_queue(), ^{
+            
+            if (displayMessage) {
+                [__weakself appendAndDisplayMessage:messageContent];
+            }
+            callback(YES);
+        });
+    } failer:^(int code, NSString * _Nonnull msg) {
+        dispatch_async(dispatch_get_main_queue(), ^{
+            NSLog(@"发送失败,errorcode is: %d message: %@",code, msg);
+            callback(NO);
+        });
+    }];
+}
+
+/**
+ *  将消息加入本地数组
+ */
+- (void)appendAndDisplayMessage:(TXLiveMessageModel *)liveMessage {
+    if (!liveMessage) {
+        return;
+    }
+    if ([self appendMessageModel:liveMessage]) {
+        NSIndexPath *indexPath =
+        [NSIndexPath indexPathForItem:self.conversationDataRepository.count - 1
+                            inSection:0];
+        if ([self.conversationMessageTableView numberOfRowsInSection:0] !=
+            self.conversationDataRepository.count - 1) {
+            return;
+        }
+        //  view刷新
+        [self.conversationMessageTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
+        if ([self isAtTheBottomOfTableView] || self.isNeedScrollToButtom) {
+            [self scrollToBottomAnimated:NO];
+            self.isNeedScrollToButtom=NO;
+        }
+    }
+    return;
+}
+
+/**
+ *  如果当前会话没有这个消息id,把消息加入本地数组
+ */
+- (BOOL)appendMessageModel:(TXLiveMessageModel *)model {
+    
+    if (!model) {
+        return NO;
+    }
+    //这里可以根据消息类型来决定是否显示,如果不希望显示直接return NO
+    
+    //数量不可能无限制的大,这里限制收到消息过多时,就对显示消息数量进行限制。
+    //用户可以手动下拉更多消息,查看更多历史消息。
+    if (self.conversationDataRepository.count>500) {
+        [self.conversationDataRepository removeObjectAtIndex:0];
+        [self.conversationMessageTableView reloadData];
+    }
+    
+    [self.conversationDataRepository addObject:model];
+    return YES;
+}
+
+
+- (void)showAnimationView:(BOOL)isJoinRoom showMessag:(NSString *)message {
+    if (self.landScape) {
+        return;
+    }
+    if (self.enterAnimationView && self.enterAnimationView.isShow) {
+        return;
+    }
+    else {
+        ANIMATIONTYPE type = isJoinRoom ? ANIMATIONTYPE_JOIN : ANIMATIONTYPE_RUSH;
+        self.enterAnimationView = [[LiveAnimationView alloc] initWithTitle:message animationType:type];
+        [self.view addSubview:self.enterAnimationView];
+        [self.enterAnimationView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.view);
+            make.width.mas_equalTo(KPortraitWidth);
+            make.height.mas_equalTo(24.0f);
+            make.bottom.mas_equalTo(self.messageContentView.mas_top).offset(-6);
+        }];
+        [self.view bringSubviewToFront:self.enterAnimationView];
+        
+        MJWeakSelf;
+        [self.enterAnimationView startAnimationEndCallback:^{
+            
+            weakSelf.enterAnimationView.isShow = NO;
+            weakSelf.enterAnimationView = nil;
+        }];
+    }
+}
+
+- (NSMutableArray *)remoteMemberArray {
+    if (!_remoteMemberArray) {
+        _remoteMemberArray = [NSMutableArray array];
+    }
+    return _remoteMemberArray;
+}
+
+- (TXLiveLoadingView *)loadingView {
+    if (!_loadingView) {
+        _loadingView = [TXLiveLoadingView shareInstance];
+    }
+    return _loadingView;
+}
+
+- (void)showLoading {
+    if (![self.videoView.subviews containsObject:self.loadingView]) {
+        [self.loadingView showLoadingView:self.videoView];
+    }
+}
+
+- (void)hideLoading {
+    if ([self.videoView.subviews containsObject:self.loadingView]) {
+        [self.loadingView hideLoadingView];
+    }
+}
+
+
+- (void)micButtonAction:(BOOL)isMute {
+    if (isMute == !self.micEnable) {
+        return;
+    }
+    if (_trtcCloud && self.isAudience == NO) {
+        self.micEnable = !isMute;
+        [self.trtcCloud muteLocalAudio:!self.micEnable];
+        [self syncMicStatus:!self.micEnable];
+    }
+}
+
+- (void)syncMicStatus:(BOOL)isMute {
+    TXMicStatusSync *syncMic = [[TXMicStatusSync alloc] init];
+    syncMic.userInfo = [self getCurrentUser];
+    syncMic.userId = UserDefault(IM_USERID);
+    syncMic.muteMic = isMute;
+    [self sendCustomMessage:syncMic priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+        
+    }];
+    [self renderSeatView];
+}
+
+#pragma mark ---- 3A config
+- (void)setSubjectId:(NSString *)subjectId {
+    _subjectId = subjectId;
+    // 设置 3A参数
+    self.ANS = 0;
+    self.AEC = 100;
+    // 长号14和萨克斯5 AGC 一样
+    if ([subjectId isEqualToString:@"5"] || [subjectId isEqualToString:@"14"]) {
+        self.AGC = 45;
+    }
+    else if ([subjectId isEqualToString:@"16"]) { // 次中音号
+        self.AGC = 80;
+    }
+    else if ([subjectId isEqualToString:@"12"]) {
+        self.AGC = 50;
+    }
+    else {
+        self.AGC = 0;
+    }
+}
+/*
+ #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

+ 61 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveMessageCenter.h

@@ -0,0 +1,61 @@
+//
+//  TXLiveMessageCenter.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/22.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <ImSDK_Plus/V2TIMManager+Group.h>
+
+#import "TXLiveTextMessage.h"
+#import "TXLiveMessageChatBan.h"
+#import "TXLiveMessageDownSeat.h"
+#import "TXLiveMessageEnter.h"
+#import "TXLiveMessageKickOut.h"
+#import "TXLiveMessageLeave.h"
+#import "TXLiveMessageLike.h"
+#import "TXLiveMessageLikeCount.h"
+#import "TXLiveMessageSeatControl.h"
+#import "TXLiveMessageSeatApply.h"
+#import "TXLiveMessageSeatResponse.h"
+#import "TXLiveMessageUserQuit.h"
+#import "TXLiveMessageWelcome.h"
+#import "TXLiveMessageCardMessage.h"
+#import "TXLiveMessageClose.h"
+#import "TXLiveMessageMemberUp.h"
+#import "TXLiveMessagePauseLive.h"
+#import "TXLiveMessageOpenLive.h"
+#import "TXLiveMessageShopRush.h"
+#import "TXLiveMessageBlockUser.h"
+#import "TXLiveMessageUnBlockUser.h"
+#import "TXLiveMessageDownSeat.h"
+#import "TXLiveMessageDownSeatAll.h"
+#import "TXLiveMessageRejectAllSeat.h"
+#import "TXConstMessage.h"
+#import "TXLiveMessageStatSync.h"
+#import "TXControlMemberMic.h"
+#import "TXMicStatusSync.h"
+#import "TXLiveForceKickMsg.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef void(^SendMessageSuccess)(void);
+
+typedef void(^sendMessageFailer)(int code, NSString *msg);
+
+@interface TXLiveMessageCenter : NSObject
+
+///发送直播间消息
+/// - Parameters:
+///   - msgData: 消息二进制
+///   - groupId: 群ID
+///   - priority: 优先级
+///   - success: 成功
+///   - failer: 失败
++ (void)sendLiveChatMessage:(NSData *)msgData groupId:(NSString *)groupId priority:(V2TIMMessagePriority)priority success:(SendMessageSuccess)success failer:(sendMessageFailer)failer;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 26 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveMessageCenter.m

@@ -0,0 +1,26 @@
+//
+//  TXLiveMessageCenter.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/22.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageCenter.h"
+
+@implementation TXLiveMessageCenter
+
++ (void)sendLiveChatMessage:(NSData *)msgData groupId:(NSString *)groupId priority:(V2TIMMessagePriority)priority success:(SendMessageSuccess)success failer:(sendMessageFailer)failer {
+    V2TIMMessage *timMessage = [[V2TIMManager sharedInstance] createCustomMessage:msgData];
+    [[V2TIMManager sharedInstance] sendMessage:timMessage
+                                      receiver:nil
+                                       groupID:groupId
+                                      priority:priority
+                                onlineUserOnly:NO
+                               offlinePushInfo:nil
+                                      progress:nil
+                                          succ:success
+                                          fail:failer];
+}
+
+@end

+ 41 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveMessageModel.h

@@ -0,0 +1,41 @@
+//
+//  TXLiveMessageModel.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/22.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "TXLiveUser.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageModel : NSObject
+
+/// 发送id
+@property (nonatomic, strong) TXLiveUser *userInfo;
+
+/**
+ 目标会话ID
+ */
+@property (nonatomic, strong) NSString *groupId;
+/**
+ 消息ID
+ */
+@property (nonatomic, strong) NSString *messageId;
+
+@property (nonatomic, strong) NSString *objectName;
+
+- (NSData *)encodeMessage;
+
+- (NSDictionary *)decodeData:(NSData *)data;
+
+- (void)evaluateSource:(NSDictionary *)msgDic;
+
++ (NSString *)getObjectName;
+
+- (NSString *)getMessageClassName:(NSString *)objectName;
+@end
+
+NS_ASSUME_NONNULL_END

+ 129 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveMessageModel.m

@@ -0,0 +1,129 @@
+//
+//  TXLiveMessageModel.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/22.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+@implementation TXLiveMessageModel
+
+
+
+- (NSData *)encodeMessage {
+    return [[NSData alloc] init];
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) {
+        return nil;
+    }
+    else {
+        return json;
+    }
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    
+}
+
++ (NSString *)getObjectName {
+    return @"TX_MESSAGE";
+}
+
+- (NSString *)getMessageClassName:(NSString *)objectName {
+    if ([objectName isEqualToString:@"RC:Chatroom:Text"]) {
+        return @"TXLiveTextMessage";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:ChatBan"]) {
+        return @"TXLiveMessageChatBan";
+    }
+    else if ([objectName isEqualToString:@"RC:ForcedOffline"]) {
+        return @"TXLiveMessageClose";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:downSeat"]) {
+        return @"TXLiveMessageDownSeat";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:Enter"]) {
+        return @"TXLiveMessageEnter";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:KickOut"]) {
+        return @"TXLiveMessageKickOut";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:Leave"]) {
+        return @"TXLiveMessageLeave";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:Like"]) {
+        return @"TXLiveMessageLike";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:LikeCount"]) {
+        return @"TXLiveMessageLikeCount";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:SeatsCtrl"]) {
+        return @"TXLiveMessageSeatControl";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:SeatApply"]) {
+        return @"TXLiveMessageSeatApply";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:SeatResponse"]) {
+        return @"TXLiveMessageSeatResponse";
+    }
+    else if ([objectName isEqualToString:@"RC:LookerLoginOut"]) {
+        return @"TXLiveMessageUserQuit";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:Welcome"]) {
+        return @"TXLiveMessageWelcome";
+    }
+    else if ([objectName isEqualToString:@"DY:LIVE_GOODS_CHANGE"]) {
+        return @"TXLiveMessageCardMessage";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:MemberCountUp"]) {
+        return @"TXLiveMessageMemberUp";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:PauseLive"]) {
+        return @"TXLiveMessagePauseLive";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:StartLive"]) {
+        return @"TXLiveMessageOpenLive";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:SnapUp"]) {
+        return @"TXLiveMessageShopRush";
+    }
+    else if ([objectName isEqualToString:@"RC:BLOCK_BLACK_USER"]) {
+        return @"TXLiveMessageBlockUser";
+    }
+    else if ([objectName isEqualToString:@"RC:UNBLOCK_BLACK_USER"]) {
+        return @"TXLiveMessageUnBlockUser";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:DownSeatAll"]) {
+        return @"TXLiveMessageDownSeatAll";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:RejectSeatAll"]) {
+        return @"TXLiveMessageRejectAllSeat";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:ConstText"]) {
+        return @"TXConstMessage";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:StatSync"]) {
+        return @"TXLiveMessageStatSync";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:ControlMemberMic"]) {
+        return @"TXControlMemberMic";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:MicSync"]) {
+        return @"TXMicStatusSync";
+    }
+    else if ([objectName isEqualToString:@"RC:Chatroom:LiveCourseStatusChange"]) {
+        return @"TXLiveCourseChangeMsg";
+    }
+    else {
+        return @"TX_MESSAGE";
+    }
+}
+@end
+

+ 59 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveURLUtils.h

@@ -0,0 +1,59 @@
+//
+//  TXLiveURLUtils.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/22.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveURLUtils : NSObject
+
+/// rtmp 推流
+/// - Parameters:
+///   - streamId: 流ID
+///   - pushDomain: 推送域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateRtmpPushUrl:(NSString *)streamId pushDomain:(NSString *)pushDomain liveUrlKey:(NSString *)liveUrlKey;
+
+/// rtmp拉流
+/// - Parameters:
+///   - streamId: 流ID
+///   - playDomain: 播放域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateRtmpPlayUrl:(NSString *)streamId playDomain:(NSString *)playDomain liveUrlKey:(NSString *)liveUrlKey;
+
+/// FLV 推流
+/// - Parameters:
+///   - streamId: 流ID
+///   - pushDomain: 推送域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateFlvPushUrl:(NSString *)streamId pushDomain:(NSString *)pushDomain liveUrlKey:(NSString *)liveUrlKey;
+
+/// FLV拉流
+/// - Parameters:
+///   - streamId: 流ID
+///   - playDomain: 播放域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateFlvPlayUrl:(NSString *)streamId playDomain:(NSString *)playDomain liveUrlKey:(NSString *)liveUrlKey;
+
+/// HLS 推流
+/// - Parameters:
+///   - streamId: 流ID
+///   - pushDomain: 推送域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateHlsPushUrl:(NSString *)streamId pushDomain:(NSString *)pushDomain liveUrlKey:(NSString *)liveUrlKey;
+
+/// HLS拉流
+/// - Parameters:
+///   - streamId: 流ID
+///   - playDomain: 播放域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateHlsPlayUrl:(NSString *)streamId playDomain:(NSString *)playDomain liveUrlKey:(NSString *)liveUrlKey;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 105 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXLiveURLUtils.m

@@ -0,0 +1,105 @@
+//
+//  TXLiveURLUtils.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/22.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveURLUtils.h"
+#import <CommonCrypto/CommonCrypto.h>
+
+@implementation TXLiveURLUtils
+
+/// rtmp 推流
+/// - Parameters:
+///   - streamId: 流ID
+///   - pushDomain: 推送域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateRtmpPushUrl:(NSString *)streamId pushDomain:(NSString *)pushDomain liveUrlKey:(NSString *)liveUrlKey {
+    NSString *url = [NSString stringWithFormat:@"rtmp://%@/live/%@?%@",
+                     pushDomain, streamId, [self getSafeUrl:streamId liveUrlKey:liveUrlKey]];
+    return url;
+}
+
+/// rtmp拉流
+/// - Parameters:
+///   - streamId: 流ID
+///   - playDomain: 播放域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateRtmpPlayUrl:(NSString *)streamId playDomain:(NSString *)playDomain liveUrlKey:(NSString *)liveUrlKey {
+    NSString *url = [NSString stringWithFormat:@"rtmp://%@/live/%@?%@",
+                     playDomain, streamId, [self getSafeUrl:streamId liveUrlKey:liveUrlKey]];
+    return url;
+}
+
+/// FLV 推流
+/// - Parameters:
+///   - streamId: 流ID
+///   - pushDomain: 推送域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateFlvPushUrl:(NSString *)streamId pushDomain:(NSString *)pushDomain liveUrlKey:(NSString *)liveUrlKey {
+    NSString *url = [NSString stringWithFormat:@"http://%@/live/%@.flv",
+                     pushDomain, [self getSafeUrl:streamId liveUrlKey:liveUrlKey]];
+    return url;
+}
+
+/// FLV拉流
+/// - Parameters:
+///   - streamId: 流ID
+///   - playDomain: 播放域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateFlvPlayUrl:(NSString *)streamId playDomain:(NSString *)playDomain liveUrlKey:(NSString *)liveUrlKey {
+    NSString *url = [NSString stringWithFormat:@"http://%@/live/%@.flv",
+                     playDomain, [self getSafeUrl:streamId liveUrlKey:liveUrlKey]];
+    return url;
+}
+
+/// HLS 推流
+/// - Parameters:
+///   - streamId: 流ID
+///   - pushDomain: 推送域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateHlsPushUrl:(NSString *)streamId pushDomain:(NSString *)pushDomain liveUrlKey:(NSString *)liveUrlKey {
+    NSString *url = [NSString stringWithFormat:@"http://%@/live/%@.m3u8",
+                     pushDomain, [self getSafeUrl:streamId liveUrlKey:liveUrlKey]];
+    return url;
+}
+
+/// HLS拉流
+/// - Parameters:
+///   - streamId: 流ID
+///   - playDomain: 播放域名
+///   - liveUrlKey: URL 鉴权Key
++ (NSString *)generateHlsPlayUrl:(NSString *)streamId playDomain:(NSString *)playDomain liveUrlKey:(NSString *)liveUrlKey {
+    NSString *url = [NSString stringWithFormat:@"http://%@/live/%@.m3u8",
+                     playDomain, [self getSafeUrl:streamId liveUrlKey:liveUrlKey]];
+    return url;
+}
+
+
+
++ (NSString*)getSafeUrl:(NSString*)streamId liveUrlKey:(NSString *)liveUrlKey  {
+    if ([NSString isEmptyString:liveUrlKey]) {
+        return @"";
+    }
+    NSDate* date = [NSDate dateWithTimeIntervalSinceNow:0];
+    NSTimeInterval time= [date timeIntervalSince1970] + 60 * 60 * 24;
+
+    NSString *hexTxTime = [[NSString alloc] initWithFormat:@"%X", (int)time];
+    NSString *secret = [[liveUrlKey stringByAppendingString:streamId] stringByAppendingString:hexTxTime];
+    NSString *txSecret = [self getMd5WithString:secret];
+    return [[NSString alloc] initWithFormat:@"txSecret=%@&txTime=%@", txSecret, hexTxTime];
+}
+
++ (NSString *)getMd5WithString:(NSString *)string {
+    const char* original_str=[string UTF8String];
+    unsigned char digist[16];
+    CC_MD5(original_str, (uint)strlen(original_str), digist);
+    NSMutableString *outPutStr = [NSMutableString stringWithCapacity:10];
+    for(int  i = 0; i < 16; i++){
+        [outPutStr appendFormat:@"%02x", digist[i]];
+    }
+    return [outPutStr lowercaseString];
+}
+@end

+ 19 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXTestGenerateUserSig.h

@@ -0,0 +1,19 @@
+//
+//  TXTestGenerateUserSig.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/22.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXTestGenerateUserSig : NSObject
+
++ (NSString *)genTestUserSig:(NSString *)identifier;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 95 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/Model/TXTestGenerateUserSig.m

@@ -0,0 +1,95 @@
+//
+//  TXTestGenerateUserSig.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/22.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXTestGenerateUserSig.h"
+#import <CommonCrypto/CommonCrypto.h>
+#import <zlib.h>
+@implementation TXTestGenerateUserSig
+
++ (NSString *)genTestUserSig:(NSString *)identifier {
+    CFTimeInterval current = CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970;
+    long tlsTime = floor(current);
+    NSMutableDictionary *obj = [@{@"TLS.ver": @"2.0",
+                                  @"TLS.identifier": identifier,
+                                  @"TLS.sdkappid": @(CONFIG_TXSDKAPPID),
+                                  @"TLS.expire": @(604800),
+                                  @"TLS.time": @(tlsTime)} mutableCopy];
+    NSMutableString *stringToSign = [[NSMutableString alloc] init];
+    NSArray *keyOrder = @[@"TLS.identifier",
+                          @"TLS.sdkappid",
+                          @"TLS.time",
+                          @"TLS.expire"];
+    for (NSString *key in keyOrder) {
+        [stringToSign appendFormat:@"%@:%@\n", key, obj[key]];
+    }
+    NSLog(@"%@", stringToSign);
+    //NSString *sig = [self sigString:stringToSign];
+    NSString *sig = [self hmac:stringToSign];
+
+    obj[@"TLS.sig"] = sig;
+    NSLog(@"sig: %@", sig);
+    NSError *error = nil;
+    NSData *jsonToZipData = [NSJSONSerialization dataWithJSONObject:obj options:0 error:&error];
+    if (error) {
+        NSLog(@"[Error] json serialization failed: %@", error);
+        return @"";
+    }
+
+    const Bytef* zipsrc = (const Bytef*)[jsonToZipData bytes];
+    uLongf srcLen = jsonToZipData.length;
+    uLong upperBound = compressBound(srcLen);
+    Bytef *dest = (Bytef*)malloc(upperBound);
+    uLongf destLen = upperBound;
+    int ret = compress2(dest, &destLen, (const Bytef*)zipsrc, srcLen, Z_BEST_SPEED);
+    if (ret != Z_OK) {
+        NSLog(@"[Error] Compress Error %d, upper bound: %lu", ret, upperBound);
+        free(dest);
+        return @"";
+    }
+    NSString *result = [self base64URL: [NSData dataWithBytesNoCopy:dest length:destLen]];
+    return result;
+}
+
++ (NSString *)hmac:(NSString *)plainText
+{
+    const char *cKey  = [@"b4143f5814b9335c7587049ced22e997d8746a1ed8f5ac5c05153c67a0d769de" cStringUsingEncoding:NSUTF8StringEncoding];
+    const char *cData = [plainText cStringUsingEncoding:NSUTF8StringEncoding];
+
+    unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
+
+    CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
+
+    NSData *hmacData = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
+    return [hmacData base64EncodedStringWithOptions:0];
+}
+
++ (NSString *)base64URL:(NSData *)data
+{
+    NSString *result = [data base64EncodedStringWithOptions:0];
+    NSMutableString *final = [[NSMutableString alloc] init];
+    const char *cString = [result cStringUsingEncoding:NSUTF8StringEncoding];
+    for (int i = 0; i < result.length; ++ i) {
+        char x = cString[i];
+        switch(x){
+            case '+':
+                [final appendString:@"*"];
+                break;
+            case '/':
+                [final appendString:@"-"];
+                break;
+            case '=':
+                [final appendString:@"_"];
+                break;
+            default:
+                [final appendFormat:@"%c", x];
+                break;
+        }
+    }
+    return final;
+}
+@end

+ 19 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXConstMessage.h

@@ -0,0 +1,19 @@
+//
+//  TXConstMessage.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/3/1.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXConstMessage : TXLiveMessageModel
+
+@property (nonatomic, strong) NSString *text;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 46 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXConstMessage.m

@@ -0,0 +1,46 @@
+//
+//  TXConstMessage.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/3/1.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXConstMessage.h"
+
+@implementation TXConstMessage
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setValue:self.text forKey:@"text"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    [parm setValue:content forKey:@"content"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.text = [content ks_stringValueForKey:@"text"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:ConstText";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:ConstText";
+}
+
+@end

+ 21 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXControlMemberMic.h

@@ -0,0 +1,21 @@
+//
+//  TXControlMemberMic.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/4/4.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXControlMemberMic : TXLiveMessageModel
+
+@property (nonatomic, strong) NSString *userId;
+// 是否关闭麦克风
+@property (nonatomic, assign) BOOL muteMic;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 49 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXControlMemberMic.m

@@ -0,0 +1,49 @@
+//
+//  TXControlMemberMic.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/4/4.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXControlMemberMic.h"
+
+@implementation TXControlMemberMic
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setObject:self.userId forKey:@"userId"];
+    [content setObject:@(self.muteMic) forKey:@"muteMic"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    [parm setValue:content forKey:@"content"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.userId = [content ks_stringValueForKey:@"userId"];
+    self.muteMic = [content ks_boolValueForKey:@"muteMic"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:ControlMemberMic";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:ControlMemberMic";
+}
+
+@end

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveForceKickMsg.h

@@ -0,0 +1,22 @@
+//
+//  TXLiveForceKickMsg.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/6/14.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveForceKickMsg : TXLiveMessageModel
+
+// 原因
+@property (nonatomic, strong) NSString *reason;
+
+@property (nonatomic, strong) NSArray *targetIds;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 47 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveForceKickMsg.m

@@ -0,0 +1,47 @@
+//
+//  TXLiveForceKickMsg.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/6/14.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveForceKickMsg.h"
+
+@implementation TXLiveForceKickMsg
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setValue:self.reason forKey:@"reason"];
+    [content setValue:self.targetIds forKey:@"targetIds"];
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.reason = [content ks_stringValueForKey:@"reason"];
+    self.targetIds = [content ks_arrayValueForKey:@"targetIds"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:ForcedKick";
+}
+- (NSString *)objectName {
+    return @"RC:Chatroom:ForcedKick";
+}
+
+@end

+ 20 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageBlockUser.h

@@ -0,0 +1,20 @@
+//
+//  TXLiveMessageBlockUser.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageBlockUser : TXLiveMessageModel
+/**
+ 用户 Id
+*/
+@property(nonatomic, copy, nonnull) NSString *userId;
+@end
+
+NS_ASSUME_NONNULL_END

+ 46 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageBlockUser.m

@@ -0,0 +1,46 @@
+//
+//  TXLiveMessageBlockUser.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageBlockUser.h"
+
+@implementation TXLiveMessageBlockUser
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setValue:self.userId forKey:@"userId"];
+
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.userId = [content ks_stringValueForKey:@"userId"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:BLOCK_BLACK_USER";
+}
+
+- (NSString *)objectName {
+    return @"RC:BLOCK_BLACK_USER";
+}
+@end

+ 19 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageCardMessage.h

@@ -0,0 +1,19 @@
+//
+//  TXLiveMessageCardMessage.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageCardMessage : TXLiveMessageModel
+
+@property(nonatomic, copy, nonnull) NSArray *goodsContent;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 44 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageCardMessage.m

@@ -0,0 +1,44 @@
+//
+//  TXLiveMessageCardMessage.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageCardMessage.h"
+
+@implementation TXLiveMessageCardMessage
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setValue:self.goodsContent forKey:@"goodsContent"];
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.goodsContent = [content ks_arrayValueForKey:@"goodsContent"];
+}
+
++ (NSString *)getObjectName {
+    return @"DY:LIVE_GOODS_CHANGE";
+}
+- (NSString *)objectName {
+    return @"DY:LIVE_GOODS_CHANGE";
+}
+@end

+ 33 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageChatBan.h

@@ -0,0 +1,33 @@
+//
+//  TXLiveMessageChatBan.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageChatBan : TXLiveMessageModel
+
+/**
+ 用户id
+*/
+@property(nonatomic, copy, nonnull) NSString *userId;
+
+/**
+ 用户名称
+*/
+@property(nonatomic, copy, nonnull) NSString *userName;
+
+/**
+ 是否禁止聊天 YES 禁止 NO 开启
+ */
+@property(nonatomic, assign) BOOL chatBan;
+
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 50 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageChatBan.m

@@ -0,0 +1,50 @@
+//
+//  TXLiveMessageChatBan.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageChatBan.h"
+
+@implementation TXLiveMessageChatBan
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setValue:self.userId forKey:@"userId"];
+    [content setValue:self.userName forKey:@"userName"];
+    [content setValue:[NSNumber numberWithBool:self.chatBan] forKey:@"chatBan"];
+    
+    [parm setValue:self.objectName forKey:@"objectName"];
+    [parm setValue:content forKey:@"content"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.userId = [content ks_stringValueForKey:@"userId"];
+    self.userName = [content ks_stringValueForKey:@"userName"];
+    self.chatBan = [content ks_boolValueForKey:@"chatBan"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:ChatBan";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:ChatBan";
+}
+@end

+ 17 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageClose.h

@@ -0,0 +1,17 @@
+//
+//  TXLiveMessageClose.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageClose : TXLiveMessageModel
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 38 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageClose.m

@@ -0,0 +1,38 @@
+//
+//  TXLiveMessageClose.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageClose.h"
+
+@implementation TXLiveMessageClose
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    [parm setValue:content forKey:@"content"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
++ (NSString *)getObjectName {
+  return @"RC:ForcedOffline";
+}
+
+- (NSString *)objectName {
+  return @"RC:ForcedOffline";
+}
+@end

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageDownSeat.h

@@ -0,0 +1,22 @@
+//
+//  TXLiveMessageDownSeat.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageDownSeat : TXLiveMessageModel
+
+// 观众名称
+@property (nonatomic, strong) NSString *audienceName;
+// 观众id
+@property (nonatomic, strong) NSString *audienceId;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 48 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageDownSeat.m

@@ -0,0 +1,48 @@
+//
+//  TXLiveMessageDownSeat.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageDownSeat.h"
+
+@implementation TXLiveMessageDownSeat
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setValue:self.audienceId forKey:@"audienceId"];
+    [content setValue:self.audienceName forKey:@"audienceName"];
+    
+    [parm setValue:self.objectName forKey:@"objectName"];
+    [parm setValue:content forKey:@"content"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.audienceId = [content ks_stringValueForKey:@"audienceId"];
+    self.audienceName = [content ks_stringValueForKey:@"audienceName"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:downSeat";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:downSeat";
+}
+@end

+ 17 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageDownSeatAll.h

@@ -0,0 +1,17 @@
+//
+//  TXLiveMessageDownSeatAll.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageDownSeatAll : TXLiveMessageModel
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 42 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageDownSeatAll.m

@@ -0,0 +1,42 @@
+//
+//  TXLiveMessageDownSeatAll.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageDownSeatAll.h"
+
+@implementation TXLiveMessageDownSeatAll
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:DownSeatAll";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:DownSeatAll";
+}
+@end

+ 17 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageEnter.h

@@ -0,0 +1,17 @@
+//
+//  TXLiveMessageEnter.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageEnter : TXLiveMessageModel
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 46 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageEnter.m

@@ -0,0 +1,46 @@
+//
+//  TXLiveMessageEnter.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageEnter.h"
+
+@implementation TXLiveMessageEnter
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    
+    [parm setValue:self.objectName forKey:@"objectName"];
+    [parm setValue:content forKey:@"content"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:Enter";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:Enter";
+}
+
+@end

+ 25 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageKickOut.h

@@ -0,0 +1,25 @@
+//
+//  TXLiveMessageKickOut.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageKickOut : TXLiveMessageModel
+/**
+ 被踢出用户 Id
+*/
+@property(nonatomic, copy) NSString *targetId;
+
+/**
+ 被踢出用户 名称
+*/
+@property(nonatomic, copy) NSString *targetName;
+@end
+
+NS_ASSUME_NONNULL_END

+ 50 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageKickOut.m

@@ -0,0 +1,50 @@
+//
+//  TXLiveMessageKickOut.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageKickOut.h"
+
+@implementation TXLiveMessageKickOut
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setValue:self.targetId forKey:@"targetId"];
+    [content setValue:self.targetName forKey:@"targetName"];
+    
+    [parm setValue:self.objectName forKey:@"objectName"];
+    [parm setValue:content forKey:@"content"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.targetId = [content ks_stringValueForKey:@"targetId"];
+    self.targetName = [content ks_stringValueForKey:@"targetName"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:KickOut";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:KickOut";
+}
+@end

+ 17 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLeave.h

@@ -0,0 +1,17 @@
+//
+//  TXLiveMessageLeave.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageLeave : TXLiveMessageModel
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 46 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLeave.m

@@ -0,0 +1,46 @@
+//
+//  TXLiveMessageLeave.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageLeave.h"
+
+@implementation TXLiveMessageLeave
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    
+    [parm setValue:self.objectName forKey:@"objectName"];
+    [parm setValue:content forKey:@"content"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:Leave";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:Leave";
+}
+
+
+@end

+ 19 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLike.h

@@ -0,0 +1,19 @@
+//
+//  TXLiveMessageLike.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageLike : TXLiveMessageModel
+
+@property(nonatomic, assign) int counts;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 47 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLike.m

@@ -0,0 +1,47 @@
+//
+//  TXLiveMessageLike.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageLike.h"
+
+@implementation TXLiveMessageLike
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setObject:@(self.counts) forKey:@"counts"];
+    
+    [parm setValue:self.objectName forKey:@"objectName"];
+    [parm setValue:content forKey:@"content"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.counts = [content ks_intValueForKey:@"counts"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:Like";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:Like";
+}
+@end

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLikeCount.h

@@ -0,0 +1,22 @@
+//
+//  TXLiveMessageLikeCount.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageLikeCount : TXLiveMessageModel
+
+/**
+    当前点赞数量
+*/
+@property(nonatomic, assign) NSInteger count;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 48 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageLikeCount.m

@@ -0,0 +1,48 @@
+//
+//  TXLiveMessageLikeCount.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/27.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageLikeCount.h"
+
+@implementation TXLiveMessageLikeCount
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setObject:@(self.count) forKey:@"count"];
+    
+    [parm setValue:self.objectName forKey:@"objectName"];
+    [parm setValue:content forKey:@"content"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.count = [content ks_integerValueForKey:@"count"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:LikeCount";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:LikeCount";
+}
+@end
+

+ 21 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageMemberUp.h

@@ -0,0 +1,21 @@
+//
+//  TXLiveMessageMemberUp.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageMemberUp : TXLiveMessageModel
+/**
+    当前观众数量
+*/
+@property(nonatomic, assign) NSInteger count;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 46 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageMemberUp.m

@@ -0,0 +1,46 @@
+//
+//  TXLiveMessageMemberUp.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageMemberUp.h"
+
+@implementation TXLiveMessageMemberUp
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setObject:@(self.count) forKey:@"count"];
+
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.count = [content ks_integerValueForKey:@"count"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:MemberCountUp";
+}
+- (NSString *)objectName {
+    return @"RC:Chatroom:MemberCountUp";
+}
+@end

+ 17 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageOpenLive.h

@@ -0,0 +1,17 @@
+//
+//  TXLiveMessageOpenLive.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/3/8.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageOpenLive : TXLiveMessageModel
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 43 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageOpenLive.m

@@ -0,0 +1,43 @@
+//
+//  TXLiveMessageOpenLive.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/3/8.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageOpenLive.h"
+
+@implementation TXLiveMessageOpenLive
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:StartLive";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:StartLive";
+}
+
+@end

+ 17 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessagePauseLive.h

@@ -0,0 +1,17 @@
+//
+//  TXLiveMessagePauseLive.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessagePauseLive : TXLiveMessageModel
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 42 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessagePauseLive.m

@@ -0,0 +1,42 @@
+//
+//  TXLiveMessagePauseLive.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessagePauseLive.h"
+
+@implementation TXLiveMessagePauseLive
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:PauseLive";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:PauseLive";
+}
+@end
+

+ 17 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageRejectAllSeat.h

@@ -0,0 +1,17 @@
+//
+//  TXLiveMessageRejectAllSeat.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageRejectAllSeat : TXLiveMessageModel
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 43 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageRejectAllSeat.m

@@ -0,0 +1,43 @@
+//
+//  TXLiveMessageRejectAllSeat.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageRejectAllSeat.h"
+
+@implementation TXLiveMessageRejectAllSeat
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:RejectSeatAll";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:RejectSeatAll";
+}
+@end

+ 43 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatApply.h

@@ -0,0 +1,43 @@
+//
+//  TXLiveMessageSeatApply.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+typedef NS_ENUM(NSInteger, SEATHANDLE) {
+    SEATHANDLE_INVITE = 1,     // 主讲人邀请连麦
+    SEATHANDLE_DISINVITE = 2,  // 主讲人取消邀请
+    SEATHANDLE_APPLY = 3,      // 观众申请连麦
+    SEATHANDLE_CANCELAPPLY = 4,// 观众取消申请
+    SEATHANDLE_KICKSEAT = 5,   // 主讲人将连麦人抱下麦
+};
+
+NS_ASSUME_NONNULL_BEGIN
+/// 连麦邀请或申请操作
+@interface TXLiveMessageSeatApply : TXLiveMessageModel
+
+/**
+ 操作类型 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;
+
+/// 观众头像
+@property (nonatomic, strong) NSString *audienceAvatar;
+// 观众学习声部
+@property (nonatomic, strong) NSString *audienceSubjectName;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 70 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatApply.m

@@ -0,0 +1,70 @@
+//
+//  TXLiveMessageSeatApply.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageSeatApply.h"
+
+/**
+ self.teacherName = [json ks_stringValueForKey:@"teacherName"];
+ self.teacherId = [json ks_stringValueForKey:@"teacherId"];
+ self.audienceName = [json ks_stringValueForKey:@"audienceName"];
+ self.audienceId = [json ks_stringValueForKey:@"audienceId"];
+ self.type = [json ks_integerValueForKey:@"type"];
+ self.audienceAvatar = [json ks_stringValueForKey:@"audienceAvatar"];
+ self.audienceSubjectName = [json ks_stringValueForKey:@"audienceSubjectName"];
+ */
+
+@implementation TXLiveMessageSeatApply
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    
+    [content setValue:self.teacherName forKey:@"teacherName"];
+    [content setValue:self.teacherId forKey:@"teacherId"];
+    [content setValue:self.audienceName forKey:@"audienceName"];
+    [content setValue:self.audienceId forKey:@"audienceId"];
+    [content setValue:@(self.type) forKey:@"type"];
+    [content setValue:self.audienceAvatar forKey:@"audienceAvatar"];
+    [content setValue:self.audienceSubjectName forKey:@"audienceSubjectName"];
+    
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    
+    self.teacherName = [content ks_stringValueForKey:@"teacherName"];
+    self.teacherId = [content ks_stringValueForKey:@"teacherId"];
+    self.audienceName = [content ks_stringValueForKey:@"audienceName"];
+    self.audienceId = [content ks_stringValueForKey:@"audienceId"];
+    self.type = [content ks_integerValueForKey:@"type"];
+    self.audienceAvatar = [content ks_stringValueForKey:@"audienceAvatar"];
+    self.audienceSubjectName = [content ks_stringValueForKey:@"audienceSubjectName"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:SeatApply";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:SeatApply";
+}
+@end

+ 21 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatControl.h

@@ -0,0 +1,21 @@
+//
+//  TXLiveMessageSeatControl.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageSeatControl : TXLiveMessageModel
+/**
+ 是否禁止连麦 YES 禁止 NO 开启
+ */
+@property(nonatomic, assign) BOOL seatBan;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 47 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatControl.m

@@ -0,0 +1,47 @@
+//
+//  TXLiveMessageSeatControl.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageSeatControl.h"
+
+@implementation TXLiveMessageSeatControl
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setObject:@(self.seatBan) forKey:@"seatBan"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.seatBan = [content ks_boolValueForKey:@"seatBan"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:SeatsCtrl";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:SeatsCtrl";
+}
+@end

+ 36 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatResponse.h

@@ -0,0 +1,36 @@
+//
+//  TXLiveMessageSeatResponse.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+typedef NS_ENUM(NSInteger, SEATRESPONSE) {
+    SEATRESPONSE_TEACHERAPPROVE = 1,       // 主讲人同意连麦
+    SEATRESPONSE_TEACHERREJECT = 2,        // 主讲人拒绝连麦
+    SEATRESPONSE_AUDIENCEAPPROVE = 3,      // 观众同意连麦
+    SEATRESPONSE_AUDIENCEREJECT = 4,       // 观众拒绝连麦
+};
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageSeatResponse : TXLiveMessageModel
+/**
+ 操作类型 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

+ 55 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageSeatResponse.m

@@ -0,0 +1,55 @@
+//
+//  TXLiveMessageSeatResponse.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageSeatResponse.h"
+
+@implementation TXLiveMessageSeatResponse
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setValue:self.teacherName forKey:@"teacherName"];
+    [content setValue:self.teacherId forKey:@"teacherId"];
+    [content setValue:self.audienceName forKey:@"audienceName"];
+    [content setValue:self.audienceId forKey:@"audienceId"];
+    [content setValue:@(self.type) forKey:@"type"];
+    
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+    self.teacherName = [content ks_stringValueForKey:@"teacherName"];
+    self.teacherId = [content ks_stringValueForKey:@"teacherId"];
+    self.audienceName = [content ks_stringValueForKey:@"audienceName"];
+    self.audienceId = [content ks_stringValueForKey:@"audienceId"];
+    self.type = [content ks_integerValueForKey:@"type"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:SeatResponse";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:SeatResponse";
+}
+@end

+ 17 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageShopRush.h

@@ -0,0 +1,17 @@
+//
+//  TXLiveMessageShopRush.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageShopRush : TXLiveMessageModel
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 43 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageShopRush.m

@@ -0,0 +1,43 @@
+//
+//  TXLiveMessageShopRush.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageShopRush.h"
+
+@implementation TXLiveMessageShopRush
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:self.objectName forKey:@"objectName"];
+    return [NSJSONSerialization dataWithJSONObject:parm options:kNilOptions error:nil];
+}
+
+- (NSDictionary *)decodeData:(NSData *)data {
+    if (data == nil) return nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return nil;
+    return json;
+}
+
+- (void)evaluateSource:(NSDictionary *)msgDic {
+    NSDictionary *content = [msgDic ks_dictionaryValueForKey:@"content"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:SnapUp";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:SnapUp";
+}
+
+@end

+ 26 - 0
KulexiuForStudent/KulexiuForStudent/Module/TXLive/TXLiveMessage/TXLiveMessageStatSync.h

@@ -0,0 +1,26 @@
+//
+//  TXLiveMessageStatSync.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/3/9.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveMessageStatSync : TXLiveMessageModel
+
+// 在线用户数量
+@property(nonatomic, assign) NSInteger onlineUsers;
+
+// 累计观看人数
+@property(nonatomic, assign) NSInteger viewers;
+
+// 点赞数量
+@property(nonatomic, assign) NSInteger likes;
+
+@end
+
+NS_ASSUME_NONNULL_END

Деякі файли не було показано, через те що забагато файлів було змінено