Pārlūkot izejas kodu

酷乐秀老师端直播

Steven 1 gadu atpakaļ
vecāks
revīzija
78b0b98a62
100 mainītis faili ar 6130 papildinājumiem un 227 dzēšanām
  1. 351 13
      KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj
  2. 1 1
      KulexiuForTeacher/KulexiuForTeacher/AppDelegate.m
  3. 7 13
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSBaseWKWebViewController.m
  4. 2 2
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSDocumentViewController.m
  5. 3 1
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.h
  6. 8 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.m
  7. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSTabBarViewController.m
  8. 2 2
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/LoginManger/TXIMLinsenter.m
  9. 7 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Extension/NSDictionary+Extension.h
  10. 10 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Extension/NSDictionary+Extension.m
  11. 0 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Controller/ChatViewController.m
  12. 6 13
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/CreateLiveViewController.m
  13. 4 7
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LiveRoomViewController.m
  14. 0 43
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/KSEnterLiveroomManager.m
  15. 1 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/LiveSeatMember.h
  16. 11 55
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LivePreviewBodyView.xib
  17. 5 3
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.h
  18. 10 8
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.m
  19. 35 51
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.xib
  20. 5 8
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/LiveList/View/LiveListBodyView.m
  21. 1 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Setting/View/AboutUsBodyView.m
  22. 1 2
      KulexiuForTeacher/KulexiuForTeacher/Module/TXClassRoom/Controller/TXClassroomViewController.m
  23. 58 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Controller/TXLiveRoomViewController.h
  24. 2474 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Controller/TXLiveRoomViewController.m
  25. 19 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXConstMessage.h
  26. 46 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXConstMessage.m
  27. 21 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXControlMemberMic.h
  28. 49 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXControlMemberMic.m
  29. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveCourseTimeChange.h
  30. 38 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveCourseTimeChange.m
  31. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveForceKickMsg.h
  32. 47 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveForceKickMsg.m
  33. 20 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageBlockUser.h
  34. 45 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageBlockUser.m
  35. 19 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageCardMessage.h
  36. 44 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageCardMessage.m
  37. 33 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageChatBan.h
  38. 50 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageChatBan.m
  39. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageClose.h
  40. 37 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageClose.m
  41. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageDownSeat.h
  42. 48 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageDownSeat.m
  43. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageDownSeatAll.h
  44. 42 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageDownSeatAll.m
  45. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageEnter.h
  46. 46 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageEnter.m
  47. 25 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageKickOut.h
  48. 50 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageKickOut.m
  49. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageLeave.h
  50. 46 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageLeave.m
  51. 19 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageLike.h
  52. 47 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageLike.m
  53. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageLikeCount.h
  54. 48 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageLikeCount.m
  55. 21 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageMemberUp.h
  56. 46 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageMemberUp.m
  57. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageOpenLive.h
  58. 43 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageOpenLive.m
  59. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessagePauseLive.h
  60. 42 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessagePauseLive.m
  61. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageRejectAllSeat.h
  62. 43 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageRejectAllSeat.m
  63. 43 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageSeatApply.h
  64. 70 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageSeatApply.m
  65. 21 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageSeatControl.h
  66. 47 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageSeatControl.m
  67. 36 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageSeatResponse.h
  68. 55 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageSeatResponse.m
  69. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageShopRush.h
  70. 43 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageShopRush.m
  71. 26 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageStatSync.h
  72. 50 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageStatSync.m
  73. 20 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageUnBlockUser.h
  74. 46 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageUnBlockUser.m
  75. 19 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageUserQuit.h
  76. 45 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageUserQuit.m
  77. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageWelcome.h
  78. 42 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageWelcome.m
  79. 20 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveTextMessage.h
  80. 45 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveTextMessage.m
  81. 28 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveUser.h
  82. 31 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveUser.m
  83. 21 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXMicStatusSync.h
  84. 49 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXMicStatusSync.m
  85. 62 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveMessageCenter.h
  86. 26 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveMessageCenter.m
  87. 41 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveMessageModel.h
  88. 132 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveMessageModel.m
  89. 50 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveRoomTimeManager.h
  90. 291 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveRoomTimeManager.m
  91. 59 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveURLUtils.h
  92. 105 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveURLUtils.m
  93. 9 2
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Service/KSEnterLiveroomManager.h
  94. 102 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Service/KSEnterLiveroomManager.m
  95. 81 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Service/LiveModuleService.h
  96. 117 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Service/LiveModuleService.m
  97. 0 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/View/LiveMoreDisplayView.h
  98. 0 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/View/LiveMoreDisplayView.m
  99. 0 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/View/LiveMoreDisplayView.xib
  100. 25 0
      KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/View/LiveRoomConfirmAlert.h

+ 351 - 13
KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj

@@ -439,6 +439,56 @@
 		BC0A22C0284752900065C1AB /* WhiteboardListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0A22BE284752900065C1AB /* WhiteboardListCell.m */; };
 		BC0A22C1284752900065C1AB /* WhiteboardListView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0A22BF284752900065C1AB /* WhiteboardListView.m */; };
 		BC0A22C528475E060065C1AB /* SongListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0A22C428475E060065C1AB /* SongListViewController.m */; };
+		BC106B252A8F44F8000759A9 /* TXLiveRoomViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B242A8F44F8000759A9 /* TXLiveRoomViewController.m */; };
+		BC106B302A8F4541000759A9 /* TXLiveRoomTimeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B272A8F453F000759A9 /* TXLiveRoomTimeManager.m */; };
+		BC106B312A8F4541000759A9 /* TXLiveURLUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B282A8F453F000759A9 /* TXLiveURLUtils.m */; };
+		BC106B322A8F4541000759A9 /* TXLiveMessageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B292A8F453F000759A9 /* TXLiveMessageModel.m */; };
+		BC106B332A8F4541000759A9 /* TXLiveMessageCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B2B2A8F4540000759A9 /* TXLiveMessageCenter.m */; };
+		BC106B712A8F4586000759A9 /* TXLiveUser.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B372A8F4575000759A9 /* TXLiveUser.m */; };
+		BC106B722A8F4586000759A9 /* TXLiveMessageShopRush.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B382A8F4576000759A9 /* TXLiveMessageShopRush.m */; };
+		BC106B732A8F4586000759A9 /* TXLiveTextMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B392A8F4576000759A9 /* TXLiveTextMessage.m */; };
+		BC106B742A8F4586000759A9 /* TXLiveMessageClose.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B3B2A8F4576000759A9 /* TXLiveMessageClose.m */; };
+		BC106B752A8F4586000759A9 /* TXLiveMessageChatBan.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B3C2A8F4577000759A9 /* TXLiveMessageChatBan.m */; };
+		BC106B762A8F4586000759A9 /* TXLiveForceKickMsg.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B3D2A8F4577000759A9 /* TXLiveForceKickMsg.m */; };
+		BC106B772A8F4586000759A9 /* TXLiveMessageDownSeat.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B402A8F4578000759A9 /* TXLiveMessageDownSeat.m */; };
+		BC106B782A8F4586000759A9 /* TXLiveMessageSeatApply.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B432A8F4579000759A9 /* TXLiveMessageSeatApply.m */; };
+		BC106B792A8F4586000759A9 /* TXLiveMessageRejectAllSeat.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B442A8F4579000759A9 /* TXLiveMessageRejectAllSeat.m */; };
+		BC106B7A2A8F4586000759A9 /* TXLiveMessageLikeCount.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B462A8F457A000759A9 /* TXLiveMessageLikeCount.m */; };
+		BC106B7B2A8F4586000759A9 /* TXLiveMessageUnBlockUser.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B472A8F457A000759A9 /* TXLiveMessageUnBlockUser.m */; };
+		BC106B7C2A8F4586000759A9 /* TXLiveMessageSeatControl.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B4A2A8F457B000759A9 /* TXLiveMessageSeatControl.m */; };
+		BC106B7D2A8F4586000759A9 /* TXLiveMessageOpenLive.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B4E2A8F457C000759A9 /* TXLiveMessageOpenLive.m */; };
+		BC106B7E2A8F4586000759A9 /* TXLiveMessageDownSeatAll.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B4F2A8F457C000759A9 /* TXLiveMessageDownSeatAll.m */; };
+		BC106B7F2A8F4586000759A9 /* TXLiveMessagePauseLive.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B522A8F457D000759A9 /* TXLiveMessagePauseLive.m */; };
+		BC106B802A8F4586000759A9 /* TXLiveCourseTimeChange.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B552A8F457E000759A9 /* TXLiveCourseTimeChange.m */; };
+		BC106B812A8F4586000759A9 /* TXLiveMessageEnter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B582A8F457F000759A9 /* TXLiveMessageEnter.m */; };
+		BC106B822A8F4586000759A9 /* TXLiveMessageUserQuit.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B5A2A8F457F000759A9 /* TXLiveMessageUserQuit.m */; };
+		BC106B832A8F4586000759A9 /* TXLiveMessageLeave.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B5B2A8F457F000759A9 /* TXLiveMessageLeave.m */; };
+		BC106B842A8F4586000759A9 /* TXControlMemberMic.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B5C2A8F4580000759A9 /* TXControlMemberMic.m */; };
+		BC106B852A8F4586000759A9 /* TXLiveMessageCardMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B5F2A8F4581000759A9 /* TXLiveMessageCardMessage.m */; };
+		BC106B862A8F4586000759A9 /* TXLiveMessageKickOut.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B612A8F4581000759A9 /* TXLiveMessageKickOut.m */; };
+		BC106B872A8F4586000759A9 /* TXConstMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B622A8F4581000759A9 /* TXConstMessage.m */; };
+		BC106B882A8F4586000759A9 /* TXLiveMessageBlockUser.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B642A8F4582000759A9 /* TXLiveMessageBlockUser.m */; };
+		BC106B892A8F4586000759A9 /* TXLiveMessageLike.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B662A8F4583000759A9 /* TXLiveMessageLike.m */; };
+		BC106B8A2A8F4586000759A9 /* TXLiveMessageStatSync.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B692A8F4583000759A9 /* TXLiveMessageStatSync.m */; };
+		BC106B8B2A8F4586000759A9 /* TXLiveMessageMemberUp.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B6A2A8F4584000759A9 /* TXLiveMessageMemberUp.m */; };
+		BC106B8C2A8F4586000759A9 /* TXLiveMessageSeatResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B6C2A8F4584000759A9 /* TXLiveMessageSeatResponse.m */; };
+		BC106B8D2A8F4586000759A9 /* TXLiveMessageWelcome.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B6D2A8F4585000759A9 /* TXLiveMessageWelcome.m */; };
+		BC106B8E2A8F4586000759A9 /* TXMicStatusSync.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B6F2A8F4585000759A9 /* TXMicStatusSync.m */; };
+		BC106BA32A8F45AA000759A9 /* TXLiveRoomHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC106B902A8F45A8000759A9 /* TXLiveRoomHeadView.xib */; };
+		BC106BA42A8F45AA000759A9 /* TXLiveChatListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B912A8F45A8000759A9 /* TXLiveChatListCell.m */; };
+		BC106BA52A8F45AA000759A9 /* TXLiveMemberSeatCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B932A8F45A9000759A9 /* TXLiveMemberSeatCell.m */; };
+		BC106BA62A8F45AA000759A9 /* TXLiveDownSeatView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC106B952A8F45A9000759A9 /* TXLiveDownSeatView.xib */; };
+		BC106BA72A8F45AA000759A9 /* TXLiveSeatActionView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B962A8F45A9000759A9 /* TXLiveSeatActionView.m */; };
+		BC106BA82A8F45AA000759A9 /* TXLiveSeatBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B972A8F45A9000759A9 /* TXLiveSeatBodyView.m */; };
+		BC106BA92A8F45AA000759A9 /* TXLiveDownSeatView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B982A8F45A9000759A9 /* TXLiveDownSeatView.m */; };
+		BC106BAA2A8F45AA000759A9 /* TXLiveMemberSeatCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC106B9A2A8F45A9000759A9 /* TXLiveMemberSeatCell.xib */; };
+		BC106BAB2A8F45AA000759A9 /* TXSeatContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106B9D2A8F45A9000759A9 /* TXSeatContainerView.m */; };
+		BC106BAC2A8F45AA000759A9 /* TXUISeatMember.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BA02A8F45AA000759A9 /* TXUISeatMember.m */; };
+		BC106BAD2A8F45AA000759A9 /* TXLiveRoomHeadView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BA12A8F45AA000759A9 /* TXLiveRoomHeadView.m */; };
+		BC106BB02A8F46C0000759A9 /* LiveRoomConfirmAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BAF2A8F46C0000759A9 /* LiveRoomConfirmAlert.m */; };
+		BC106BB42A8F4BC9000759A9 /* LiveModuleService.m in Sources */ = {isa = PBXBuildFile; fileRef = BC106BB32A8F4BC9000759A9 /* LiveModuleService.m */; };
+		BC106BB62A8F6E94000759A9 /* ShareMusicCellContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC106BB52A8F6E93000759A9 /* ShareMusicCellContentView.xib */; };
+		BC106BB82A8F6EAB000759A9 /* ShareLiveCellContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC106BB72A8F6EAB000759A9 /* ShareLiveCellContentView.xib */; };
 		BC1191ED280E55CB00A716F7 /* EvaluateDetailModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1191EB280E55CA00A716F7 /* EvaluateDetailModel.m */; };
 		BC1191F0280E8A2800A716F7 /* TableCourseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1191EF280E8A2800A716F7 /* TableCourseModel.m */; };
 		BC1191F3280EAB9600A716F7 /* AccompanyDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1191F1280EAB9600A716F7 /* AccompanyDetailViewController.m */; };
@@ -901,7 +951,6 @@
 		BCB635BE27F7256B00ACFDCF /* KSICloudManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB635BA27F7256B00ACFDCF /* KSICloudManager.m */; };
 		BCB635BF27F7256B00ACFDCF /* KSDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB635BD27F7256B00ACFDCF /* KSDocument.m */; };
 		BCB908DB2850A71100F5FF69 /* ShareMusicCellContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB908DA2850A71100F5FF69 /* ShareMusicCellContentView.m */; };
-		BCB908DD2850A71800F5FF69 /* ShareMusicCellContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCB908DC2850A71800F5FF69 /* ShareMusicCellContentView.xib */; };
 		BCB908F72850C6EF00F5FF69 /* MusicChooseCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB908F52850C6EF00F5FF69 /* MusicChooseCell.m */; };
 		BCB908F82850C6EF00F5FF69 /* MusicChooseCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCB908F62850C6EF00F5FF69 /* MusicChooseCell.xib */; };
 		BCB908FB2850C9C300F5FF69 /* MusicChooseSearchView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB908FA2850C9C300F5FF69 /* MusicChooseSearchView.m */; };
@@ -1083,7 +1132,6 @@
 		BCED5CBB28508823009A42DE /* KSChatLiveShareCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCED5CBA28508823009A42DE /* KSChatLiveShareCell.m */; };
 		BCED5CBE28508831009A42DE /* KSChatMusicShareCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCED5CBD28508831009A42DE /* KSChatMusicShareCell.m */; };
 		BCED5CC128508F21009A42DE /* ShareLiveCellContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCED5CC028508F21009A42DE /* ShareLiveCellContentView.m */; };
-		BCED5CC328508F28009A42DE /* ShareLiveCellContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCED5CC228508F28009A42DE /* ShareLiveCellContentView.xib */; };
 		BCF1BA5127F5C4DD00FA36C4 /* KSLiveChatroomMemberCount.m in Sources */ = {isa = PBXBuildFile; fileRef = BCF1BA5027F5C4DD00FA36C4 /* KSLiveChatroomMemberCount.m */; };
 		BCF1BA5427F5CB5800FA36C4 /* LiveSeatApplyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCF1BA5327F5CB5800FA36C4 /* LiveSeatApplyView.m */; };
 		BCF1BA5627F5CBA100FA36C4 /* LiveSeatApplyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCF1BA5527F5CBA100FA36C4 /* LiveSeatApplyView.xib */; };
@@ -1915,6 +1963,101 @@
 		BC0A22BF284752900065C1AB /* WhiteboardListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WhiteboardListView.m; sourceTree = "<group>"; };
 		BC0A22C328475E060065C1AB /* SongListViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SongListViewController.h; sourceTree = "<group>"; };
 		BC0A22C428475E060065C1AB /* SongListViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SongListViewController.m; sourceTree = "<group>"; };
+		BC106B232A8F44F8000759A9 /* TXLiveRoomViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveRoomViewController.h; sourceTree = "<group>"; };
+		BC106B242A8F44F8000759A9 /* TXLiveRoomViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveRoomViewController.m; sourceTree = "<group>"; };
+		BC106B262A8F453E000759A9 /* TXLiveMessageCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageCenter.h; sourceTree = "<group>"; };
+		BC106B272A8F453F000759A9 /* TXLiveRoomTimeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveRoomTimeManager.m; sourceTree = "<group>"; };
+		BC106B282A8F453F000759A9 /* TXLiveURLUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveURLUtils.m; sourceTree = "<group>"; };
+		BC106B292A8F453F000759A9 /* TXLiveMessageModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageModel.m; sourceTree = "<group>"; };
+		BC106B2A2A8F453F000759A9 /* TXLiveMessageModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageModel.h; sourceTree = "<group>"; };
+		BC106B2B2A8F4540000759A9 /* TXLiveMessageCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageCenter.m; sourceTree = "<group>"; };
+		BC106B2D2A8F4540000759A9 /* TXLiveRoomTimeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveRoomTimeManager.h; sourceTree = "<group>"; };
+		BC106B2E2A8F4540000759A9 /* TXLiveURLUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveURLUtils.h; sourceTree = "<group>"; };
+		BC106B352A8F4575000759A9 /* TXLiveMessageMemberUp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageMemberUp.h; sourceTree = "<group>"; };
+		BC106B362A8F4575000759A9 /* TXLiveUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveUser.h; sourceTree = "<group>"; };
+		BC106B372A8F4575000759A9 /* TXLiveUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveUser.m; sourceTree = "<group>"; };
+		BC106B382A8F4576000759A9 /* TXLiveMessageShopRush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageShopRush.m; sourceTree = "<group>"; };
+		BC106B392A8F4576000759A9 /* TXLiveTextMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveTextMessage.m; sourceTree = "<group>"; };
+		BC106B3A2A8F4576000759A9 /* TXLiveMessageSeatResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageSeatResponse.h; sourceTree = "<group>"; };
+		BC106B3B2A8F4576000759A9 /* TXLiveMessageClose.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageClose.m; sourceTree = "<group>"; };
+		BC106B3C2A8F4577000759A9 /* TXLiveMessageChatBan.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageChatBan.m; sourceTree = "<group>"; };
+		BC106B3D2A8F4577000759A9 /* TXLiveForceKickMsg.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveForceKickMsg.m; sourceTree = "<group>"; };
+		BC106B3E2A8F4577000759A9 /* TXLiveCourseTimeChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveCourseTimeChange.h; sourceTree = "<group>"; };
+		BC106B3F2A8F4578000759A9 /* TXControlMemberMic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXControlMemberMic.h; sourceTree = "<group>"; };
+		BC106B402A8F4578000759A9 /* TXLiveMessageDownSeat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageDownSeat.m; sourceTree = "<group>"; };
+		BC106B412A8F4578000759A9 /* TXLiveMessageWelcome.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageWelcome.h; sourceTree = "<group>"; };
+		BC106B422A8F4579000759A9 /* TXLiveTextMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveTextMessage.h; sourceTree = "<group>"; };
+		BC106B432A8F4579000759A9 /* TXLiveMessageSeatApply.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageSeatApply.m; sourceTree = "<group>"; };
+		BC106B442A8F4579000759A9 /* TXLiveMessageRejectAllSeat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageRejectAllSeat.m; sourceTree = "<group>"; };
+		BC106B452A8F4579000759A9 /* TXLiveMessageCardMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageCardMessage.h; sourceTree = "<group>"; };
+		BC106B462A8F457A000759A9 /* TXLiveMessageLikeCount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageLikeCount.m; sourceTree = "<group>"; };
+		BC106B472A8F457A000759A9 /* TXLiveMessageUnBlockUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageUnBlockUser.m; sourceTree = "<group>"; };
+		BC106B482A8F457A000759A9 /* TXLiveMessageShopRush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageShopRush.h; sourceTree = "<group>"; };
+		BC106B492A8F457A000759A9 /* TXLiveMessageBlockUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageBlockUser.h; sourceTree = "<group>"; };
+		BC106B4A2A8F457B000759A9 /* TXLiveMessageSeatControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageSeatControl.m; sourceTree = "<group>"; };
+		BC106B4B2A8F457B000759A9 /* TXLiveMessagePauseLive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessagePauseLive.h; sourceTree = "<group>"; };
+		BC106B4C2A8F457B000759A9 /* TXConstMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXConstMessage.h; sourceTree = "<group>"; };
+		BC106B4D2A8F457C000759A9 /* TXLiveMessageKickOut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageKickOut.h; sourceTree = "<group>"; };
+		BC106B4E2A8F457C000759A9 /* TXLiveMessageOpenLive.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageOpenLive.m; sourceTree = "<group>"; };
+		BC106B4F2A8F457C000759A9 /* TXLiveMessageDownSeatAll.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageDownSeatAll.m; sourceTree = "<group>"; };
+		BC106B502A8F457C000759A9 /* TXLiveMessageDownSeat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageDownSeat.h; sourceTree = "<group>"; };
+		BC106B512A8F457D000759A9 /* TXLiveMessageStatSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageStatSync.h; sourceTree = "<group>"; };
+		BC106B522A8F457D000759A9 /* TXLiveMessagePauseLive.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessagePauseLive.m; sourceTree = "<group>"; };
+		BC106B532A8F457D000759A9 /* TXLiveMessageEnter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageEnter.h; sourceTree = "<group>"; };
+		BC106B542A8F457D000759A9 /* TXLiveMessageLikeCount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageLikeCount.h; sourceTree = "<group>"; };
+		BC106B552A8F457E000759A9 /* TXLiveCourseTimeChange.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveCourseTimeChange.m; sourceTree = "<group>"; };
+		BC106B562A8F457E000759A9 /* TXLiveMessageLike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageLike.h; sourceTree = "<group>"; };
+		BC106B572A8F457E000759A9 /* TXLiveMessageRejectAllSeat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageRejectAllSeat.h; sourceTree = "<group>"; };
+		BC106B582A8F457F000759A9 /* TXLiveMessageEnter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageEnter.m; sourceTree = "<group>"; };
+		BC106B592A8F457F000759A9 /* TXLiveMessageUserQuit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageUserQuit.h; sourceTree = "<group>"; };
+		BC106B5A2A8F457F000759A9 /* TXLiveMessageUserQuit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageUserQuit.m; sourceTree = "<group>"; };
+		BC106B5B2A8F457F000759A9 /* TXLiveMessageLeave.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageLeave.m; sourceTree = "<group>"; };
+		BC106B5C2A8F4580000759A9 /* TXControlMemberMic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXControlMemberMic.m; sourceTree = "<group>"; };
+		BC106B5D2A8F4580000759A9 /* TXLiveMessageClose.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageClose.h; sourceTree = "<group>"; };
+		BC106B5E2A8F4580000759A9 /* TXLiveMessageChatBan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageChatBan.h; sourceTree = "<group>"; };
+		BC106B5F2A8F4581000759A9 /* TXLiveMessageCardMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageCardMessage.m; sourceTree = "<group>"; };
+		BC106B602A8F4581000759A9 /* TXMicStatusSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXMicStatusSync.h; sourceTree = "<group>"; };
+		BC106B612A8F4581000759A9 /* TXLiveMessageKickOut.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageKickOut.m; sourceTree = "<group>"; };
+		BC106B622A8F4581000759A9 /* TXConstMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXConstMessage.m; sourceTree = "<group>"; };
+		BC106B632A8F4582000759A9 /* TXLiveForceKickMsg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveForceKickMsg.h; sourceTree = "<group>"; };
+		BC106B642A8F4582000759A9 /* TXLiveMessageBlockUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageBlockUser.m; sourceTree = "<group>"; };
+		BC106B652A8F4582000759A9 /* TXLiveMessageUnBlockUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageUnBlockUser.h; sourceTree = "<group>"; };
+		BC106B662A8F4583000759A9 /* TXLiveMessageLike.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageLike.m; sourceTree = "<group>"; };
+		BC106B672A8F4583000759A9 /* TXLiveMessageSeatControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageSeatControl.h; sourceTree = "<group>"; };
+		BC106B682A8F4583000759A9 /* TXLiveMessageOpenLive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageOpenLive.h; sourceTree = "<group>"; };
+		BC106B692A8F4583000759A9 /* TXLiveMessageStatSync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageStatSync.m; sourceTree = "<group>"; };
+		BC106B6A2A8F4584000759A9 /* TXLiveMessageMemberUp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageMemberUp.m; sourceTree = "<group>"; };
+		BC106B6B2A8F4584000759A9 /* TXLiveMessageLeave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageLeave.h; sourceTree = "<group>"; };
+		BC106B6C2A8F4584000759A9 /* TXLiveMessageSeatResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageSeatResponse.m; sourceTree = "<group>"; };
+		BC106B6D2A8F4585000759A9 /* TXLiveMessageWelcome.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMessageWelcome.m; sourceTree = "<group>"; };
+		BC106B6E2A8F4585000759A9 /* TXLiveMessageSeatApply.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageSeatApply.h; sourceTree = "<group>"; };
+		BC106B6F2A8F4585000759A9 /* TXMicStatusSync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXMicStatusSync.m; sourceTree = "<group>"; };
+		BC106B702A8F4586000759A9 /* TXLiveMessageDownSeatAll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMessageDownSeatAll.h; sourceTree = "<group>"; };
+		BC106B8F2A8F45A8000759A9 /* TXSeatContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXSeatContainerView.h; sourceTree = "<group>"; };
+		BC106B902A8F45A8000759A9 /* TXLiveRoomHeadView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TXLiveRoomHeadView.xib; sourceTree = "<group>"; };
+		BC106B912A8F45A8000759A9 /* TXLiveChatListCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveChatListCell.m; sourceTree = "<group>"; };
+		BC106B932A8F45A9000759A9 /* TXLiveMemberSeatCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveMemberSeatCell.m; sourceTree = "<group>"; };
+		BC106B942A8F45A9000759A9 /* TXLiveDownSeatView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveDownSeatView.h; sourceTree = "<group>"; };
+		BC106B952A8F45A9000759A9 /* TXLiveDownSeatView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TXLiveDownSeatView.xib; sourceTree = "<group>"; };
+		BC106B962A8F45A9000759A9 /* TXLiveSeatActionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveSeatActionView.m; sourceTree = "<group>"; };
+		BC106B972A8F45A9000759A9 /* TXLiveSeatBodyView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveSeatBodyView.m; sourceTree = "<group>"; };
+		BC106B982A8F45A9000759A9 /* TXLiveDownSeatView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveDownSeatView.m; sourceTree = "<group>"; };
+		BC106B992A8F45A9000759A9 /* TXLiveMemberSeatCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveMemberSeatCell.h; sourceTree = "<group>"; };
+		BC106B9A2A8F45A9000759A9 /* TXLiveMemberSeatCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TXLiveMemberSeatCell.xib; sourceTree = "<group>"; };
+		BC106B9B2A8F45A9000759A9 /* TXLiveSeatBodyView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveSeatBodyView.h; sourceTree = "<group>"; };
+		BC106B9C2A8F45A9000759A9 /* TXLiveSeatActionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveSeatActionView.h; sourceTree = "<group>"; };
+		BC106B9D2A8F45A9000759A9 /* TXSeatContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXSeatContainerView.m; sourceTree = "<group>"; };
+		BC106B9E2A8F45A9000759A9 /* TXUISeatMember.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXUISeatMember.h; sourceTree = "<group>"; };
+		BC106B9F2A8F45A9000759A9 /* TXLiveRoomHeadView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveRoomHeadView.h; sourceTree = "<group>"; };
+		BC106BA02A8F45AA000759A9 /* TXUISeatMember.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXUISeatMember.m; sourceTree = "<group>"; };
+		BC106BA12A8F45AA000759A9 /* TXLiveRoomHeadView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXLiveRoomHeadView.m; sourceTree = "<group>"; };
+		BC106BA22A8F45AA000759A9 /* TXLiveChatListCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXLiveChatListCell.h; sourceTree = "<group>"; };
+		BC106BAE2A8F46C0000759A9 /* LiveRoomConfirmAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveRoomConfirmAlert.h; sourceTree = "<group>"; };
+		BC106BAF2A8F46C0000759A9 /* LiveRoomConfirmAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveRoomConfirmAlert.m; sourceTree = "<group>"; };
+		BC106BB22A8F4BC9000759A9 /* LiveModuleService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveModuleService.h; sourceTree = "<group>"; };
+		BC106BB32A8F4BC9000759A9 /* LiveModuleService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiveModuleService.m; sourceTree = "<group>"; };
+		BC106BB52A8F6E93000759A9 /* ShareMusicCellContentView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShareMusicCellContentView.xib; sourceTree = "<group>"; };
+		BC106BB72A8F6EAB000759A9 /* ShareLiveCellContentView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShareLiveCellContentView.xib; sourceTree = "<group>"; };
 		BC1191EB280E55CA00A716F7 /* EvaluateDetailModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EvaluateDetailModel.m; sourceTree = "<group>"; };
 		BC1191EC280E55CB00A716F7 /* EvaluateDetailModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EvaluateDetailModel.h; sourceTree = "<group>"; };
 		BC1191EE280E8A2700A716F7 /* TableCourseModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableCourseModel.h; sourceTree = "<group>"; };
@@ -2645,7 +2788,6 @@
 		BCB635BD27F7256B00ACFDCF /* KSDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSDocument.m; sourceTree = "<group>"; };
 		BCB908D92850A71100F5FF69 /* ShareMusicCellContentView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShareMusicCellContentView.h; sourceTree = "<group>"; };
 		BCB908DA2850A71100F5FF69 /* ShareMusicCellContentView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShareMusicCellContentView.m; sourceTree = "<group>"; };
-		BCB908DC2850A71800F5FF69 /* ShareMusicCellContentView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ShareMusicCellContentView.xib; sourceTree = "<group>"; };
 		BCB908F42850C6EF00F5FF69 /* MusicChooseCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MusicChooseCell.h; sourceTree = "<group>"; };
 		BCB908F52850C6EF00F5FF69 /* MusicChooseCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MusicChooseCell.m; sourceTree = "<group>"; };
 		BCB908F62850C6EF00F5FF69 /* MusicChooseCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MusicChooseCell.xib; sourceTree = "<group>"; };
@@ -2939,7 +3081,6 @@
 		BCED5CBD28508831009A42DE /* KSChatMusicShareCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSChatMusicShareCell.m; sourceTree = "<group>"; };
 		BCED5CBF28508F21009A42DE /* ShareLiveCellContentView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShareLiveCellContentView.h; sourceTree = "<group>"; };
 		BCED5CC028508F21009A42DE /* ShareLiveCellContentView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShareLiveCellContentView.m; sourceTree = "<group>"; };
-		BCED5CC228508F28009A42DE /* ShareLiveCellContentView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ShareLiveCellContentView.xib; sourceTree = "<group>"; };
 		BCF1BA4F27F5C4DD00FA36C4 /* KSLiveChatroomMemberCount.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomMemberCount.h; sourceTree = "<group>"; };
 		BCF1BA5027F5C4DD00FA36C4 /* KSLiveChatroomMemberCount.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomMemberCount.m; sourceTree = "<group>"; };
 		BCF1BA5227F5CB5800FA36C4 /* LiveSeatApplyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveSeatApplyView.h; sourceTree = "<group>"; };
@@ -4045,6 +4186,7 @@
 		277935D927E325B90010E277 /* Module */ = {
 			isa = PBXGroup;
 			children = (
+				BC106B1E2A8F448E000759A9 /* TXLiveModule */,
 				BC71DE732A89C7D1003F165E /* TXClassRoom */,
 				BC5E4AD7291E5E26001BBCD2 /* Widget */,
 				BC71D17E2887FDAB0010F14B /* AnimationLaunch */,
@@ -4406,12 +4548,12 @@
 				BCED5CBA28508823009A42DE /* KSChatLiveShareCell.m */,
 				BCED5CBF28508F21009A42DE /* ShareLiveCellContentView.h */,
 				BCED5CC028508F21009A42DE /* ShareLiveCellContentView.m */,
-				BCED5CC228508F28009A42DE /* ShareLiveCellContentView.xib */,
+				BC106BB72A8F6EAB000759A9 /* ShareLiveCellContentView.xib */,
 				BCED5CBC28508831009A42DE /* KSChatMusicShareCell.h */,
 				BCED5CBD28508831009A42DE /* KSChatMusicShareCell.m */,
 				BCB908D92850A71100F5FF69 /* ShareMusicCellContentView.h */,
 				BCB908DA2850A71100F5FF69 /* ShareMusicCellContentView.m */,
-				BCB908DC2850A71800F5FF69 /* ShareMusicCellContentView.xib */,
+				BC106BB52A8F6E93000759A9 /* ShareMusicCellContentView.xib */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -4487,8 +4629,6 @@
 		27D83F4527F3EBAA00062476 /* Model */ = {
 			isa = PBXGroup;
 			children = (
-				275E3DA127F441EC0010EC30 /* KSEnterLiveroomManager.h */,
-				275E3DA227F441EC0010EC30 /* KSEnterLiveroomManager.m */,
 				275E3DA727F45A8A0010EC30 /* KSLiveStreamVideo.h */,
 				275E3DA827F45A8A0010EC30 /* KSLiveStreamVideo.m */,
 				BCC9F35327F5F4FD00647449 /* LiveSeatMember.h */,
@@ -4504,9 +4644,6 @@
 			children = (
 				BC02BCD728B32418005CB483 /* SeatListView */,
 				BCD457B82865652C0010B493 /* AnimationView */,
-				BCD457B3286565190010B493 /* LiveMoreDisplayView.h */,
-				BCD457B52865651A0010B493 /* LiveMoreDisplayView.m */,
-				BCD457B42865651A0010B493 /* LiveMoreDisplayView.xib */,
 				BCD457B0286564DB0010B493 /* LiveRoomAlertView.h */,
 				BCD457B1286564DB0010B493 /* LiveRoomAlertView.m */,
 				275E3DD527F467410010EC30 /* InputBar */,
@@ -5053,6 +5190,159 @@
 			path = ClassroomSong;
 			sourceTree = "<group>";
 		};
+		BC106B1E2A8F448E000759A9 /* TXLiveModule */ = {
+			isa = PBXGroup;
+			children = (
+				BC106BB12A8F4BAC000759A9 /* Service */,
+				BC106B202A8F44DE000759A9 /* Controller */,
+				BC106B212A8F44DE000759A9 /* Message */,
+				BC106B1F2A8F44DE000759A9 /* Model */,
+				BC106B222A8F44DE000759A9 /* View */,
+			);
+			path = TXLiveModule;
+			sourceTree = "<group>";
+		};
+		BC106B1F2A8F44DE000759A9 /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				BC106B262A8F453E000759A9 /* TXLiveMessageCenter.h */,
+				BC106B2B2A8F4540000759A9 /* TXLiveMessageCenter.m */,
+				BC106B2A2A8F453F000759A9 /* TXLiveMessageModel.h */,
+				BC106B292A8F453F000759A9 /* TXLiveMessageModel.m */,
+				BC106B2D2A8F4540000759A9 /* TXLiveRoomTimeManager.h */,
+				BC106B272A8F453F000759A9 /* TXLiveRoomTimeManager.m */,
+				BC106B2E2A8F4540000759A9 /* TXLiveURLUtils.h */,
+				BC106B282A8F453F000759A9 /* TXLiveURLUtils.m */,
+			);
+			path = Model;
+			sourceTree = "<group>";
+		};
+		BC106B202A8F44DE000759A9 /* Controller */ = {
+			isa = PBXGroup;
+			children = (
+				BC106B232A8F44F8000759A9 /* TXLiveRoomViewController.h */,
+				BC106B242A8F44F8000759A9 /* TXLiveRoomViewController.m */,
+			);
+			path = Controller;
+			sourceTree = "<group>";
+		};
+		BC106B212A8F44DE000759A9 /* Message */ = {
+			isa = PBXGroup;
+			children = (
+				BC106B4C2A8F457B000759A9 /* TXConstMessage.h */,
+				BC106B622A8F4581000759A9 /* TXConstMessage.m */,
+				BC106B3F2A8F4578000759A9 /* TXControlMemberMic.h */,
+				BC106B5C2A8F4580000759A9 /* TXControlMemberMic.m */,
+				BC106B3E2A8F4577000759A9 /* TXLiveCourseTimeChange.h */,
+				BC106B552A8F457E000759A9 /* TXLiveCourseTimeChange.m */,
+				BC106B632A8F4582000759A9 /* TXLiveForceKickMsg.h */,
+				BC106B3D2A8F4577000759A9 /* TXLiveForceKickMsg.m */,
+				BC106B492A8F457A000759A9 /* TXLiveMessageBlockUser.h */,
+				BC106B642A8F4582000759A9 /* TXLiveMessageBlockUser.m */,
+				BC106B452A8F4579000759A9 /* TXLiveMessageCardMessage.h */,
+				BC106B5F2A8F4581000759A9 /* TXLiveMessageCardMessage.m */,
+				BC106B5E2A8F4580000759A9 /* TXLiveMessageChatBan.h */,
+				BC106B3C2A8F4577000759A9 /* TXLiveMessageChatBan.m */,
+				BC106B5D2A8F4580000759A9 /* TXLiveMessageClose.h */,
+				BC106B3B2A8F4576000759A9 /* TXLiveMessageClose.m */,
+				BC106B502A8F457C000759A9 /* TXLiveMessageDownSeat.h */,
+				BC106B402A8F4578000759A9 /* TXLiveMessageDownSeat.m */,
+				BC106B702A8F4586000759A9 /* TXLiveMessageDownSeatAll.h */,
+				BC106B4F2A8F457C000759A9 /* TXLiveMessageDownSeatAll.m */,
+				BC106B532A8F457D000759A9 /* TXLiveMessageEnter.h */,
+				BC106B582A8F457F000759A9 /* TXLiveMessageEnter.m */,
+				BC106B4D2A8F457C000759A9 /* TXLiveMessageKickOut.h */,
+				BC106B612A8F4581000759A9 /* TXLiveMessageKickOut.m */,
+				BC106B6B2A8F4584000759A9 /* TXLiveMessageLeave.h */,
+				BC106B5B2A8F457F000759A9 /* TXLiveMessageLeave.m */,
+				BC106B562A8F457E000759A9 /* TXLiveMessageLike.h */,
+				BC106B662A8F4583000759A9 /* TXLiveMessageLike.m */,
+				BC106B542A8F457D000759A9 /* TXLiveMessageLikeCount.h */,
+				BC106B462A8F457A000759A9 /* TXLiveMessageLikeCount.m */,
+				BC106B352A8F4575000759A9 /* TXLiveMessageMemberUp.h */,
+				BC106B6A2A8F4584000759A9 /* TXLiveMessageMemberUp.m */,
+				BC106B682A8F4583000759A9 /* TXLiveMessageOpenLive.h */,
+				BC106B4E2A8F457C000759A9 /* TXLiveMessageOpenLive.m */,
+				BC106B4B2A8F457B000759A9 /* TXLiveMessagePauseLive.h */,
+				BC106B522A8F457D000759A9 /* TXLiveMessagePauseLive.m */,
+				BC106B572A8F457E000759A9 /* TXLiveMessageRejectAllSeat.h */,
+				BC106B442A8F4579000759A9 /* TXLiveMessageRejectAllSeat.m */,
+				BC106B6E2A8F4585000759A9 /* TXLiveMessageSeatApply.h */,
+				BC106B432A8F4579000759A9 /* TXLiveMessageSeatApply.m */,
+				BC106B672A8F4583000759A9 /* TXLiveMessageSeatControl.h */,
+				BC106B4A2A8F457B000759A9 /* TXLiveMessageSeatControl.m */,
+				BC106B3A2A8F4576000759A9 /* TXLiveMessageSeatResponse.h */,
+				BC106B6C2A8F4584000759A9 /* TXLiveMessageSeatResponse.m */,
+				BC106B482A8F457A000759A9 /* TXLiveMessageShopRush.h */,
+				BC106B382A8F4576000759A9 /* TXLiveMessageShopRush.m */,
+				BC106B512A8F457D000759A9 /* TXLiveMessageStatSync.h */,
+				BC106B692A8F4583000759A9 /* TXLiveMessageStatSync.m */,
+				BC106B652A8F4582000759A9 /* TXLiveMessageUnBlockUser.h */,
+				BC106B472A8F457A000759A9 /* TXLiveMessageUnBlockUser.m */,
+				BC106B592A8F457F000759A9 /* TXLiveMessageUserQuit.h */,
+				BC106B5A2A8F457F000759A9 /* TXLiveMessageUserQuit.m */,
+				BC106B412A8F4578000759A9 /* TXLiveMessageWelcome.h */,
+				BC106B6D2A8F4585000759A9 /* TXLiveMessageWelcome.m */,
+				BC106B422A8F4579000759A9 /* TXLiveTextMessage.h */,
+				BC106B392A8F4576000759A9 /* TXLiveTextMessage.m */,
+				BC106B362A8F4575000759A9 /* TXLiveUser.h */,
+				BC106B372A8F4575000759A9 /* TXLiveUser.m */,
+				BC106B602A8F4581000759A9 /* TXMicStatusSync.h */,
+				BC106B6F2A8F4585000759A9 /* TXMicStatusSync.m */,
+			);
+			path = Message;
+			sourceTree = "<group>";
+		};
+		BC106B222A8F44DE000759A9 /* View */ = {
+			isa = PBXGroup;
+			children = (
+				BC106BA22A8F45AA000759A9 /* TXLiveChatListCell.h */,
+				BC106B912A8F45A8000759A9 /* TXLiveChatListCell.m */,
+				BC106B9F2A8F45A9000759A9 /* TXLiveRoomHeadView.h */,
+				BC106BA12A8F45AA000759A9 /* TXLiveRoomHeadView.m */,
+				BC106B902A8F45A8000759A9 /* TXLiveRoomHeadView.xib */,
+				BC106B922A8F45A9000759A9 /* TXLiveSeat */,
+				BC106B8F2A8F45A8000759A9 /* TXSeatContainerView.h */,
+				BC106B9D2A8F45A9000759A9 /* TXSeatContainerView.m */,
+				BC106BAE2A8F46C0000759A9 /* LiveRoomConfirmAlert.h */,
+				BC106BAF2A8F46C0000759A9 /* LiveRoomConfirmAlert.m */,
+				BC106B9E2A8F45A9000759A9 /* TXUISeatMember.h */,
+				BC106BA02A8F45AA000759A9 /* TXUISeatMember.m */,
+				BCD457B3286565190010B493 /* LiveMoreDisplayView.h */,
+				BCD457B52865651A0010B493 /* LiveMoreDisplayView.m */,
+				BCD457B42865651A0010B493 /* LiveMoreDisplayView.xib */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		BC106B922A8F45A9000759A9 /* TXLiveSeat */ = {
+			isa = PBXGroup;
+			children = (
+				BC106B932A8F45A9000759A9 /* TXLiveMemberSeatCell.m */,
+				BC106B942A8F45A9000759A9 /* TXLiveDownSeatView.h */,
+				BC106B952A8F45A9000759A9 /* TXLiveDownSeatView.xib */,
+				BC106B962A8F45A9000759A9 /* TXLiveSeatActionView.m */,
+				BC106B972A8F45A9000759A9 /* TXLiveSeatBodyView.m */,
+				BC106B982A8F45A9000759A9 /* TXLiveDownSeatView.m */,
+				BC106B992A8F45A9000759A9 /* TXLiveMemberSeatCell.h */,
+				BC106B9A2A8F45A9000759A9 /* TXLiveMemberSeatCell.xib */,
+				BC106B9B2A8F45A9000759A9 /* TXLiveSeatBodyView.h */,
+				BC106B9C2A8F45A9000759A9 /* TXLiveSeatActionView.h */,
+			);
+			path = TXLiveSeat;
+			sourceTree = "<group>";
+		};
+		BC106BB12A8F4BAC000759A9 /* Service */ = {
+			isa = PBXGroup;
+			children = (
+				BC106BB22A8F4BC9000759A9 /* LiveModuleService.h */,
+				BC106BB32A8F4BC9000759A9 /* LiveModuleService.m */,
+				275E3DA127F441EC0010EC30 /* KSEnterLiveroomManager.h */,
+				275E3DA227F441EC0010EC30 /* KSEnterLiveroomManager.m */,
+			);
+			path = Service;
+			sourceTree = "<group>";
+		};
 		BC12637128FEB5B900509E90 /* ChatUserInfo */ = {
 			isa = PBXGroup;
 			children = (
@@ -7403,7 +7693,6 @@
 				BC023802286594EA005560CA /* KSTipsAlert.xib in Resources */,
 				BC4BCE6D28239EEB00522C8B /* MyAddressListCell.xib in Resources */,
 				27BC3B2B27F2DB9600D81E30 /* MusicUploadView.xib in Resources */,
-				BCED5CC328508F28009A42DE /* ShareLiveCellContentView.xib in Resources */,
 				BC56C95A29233F1D00AF301F /* CoursewareBottomView.xib in Resources */,
 				BC3673DA28A606A500059721 /* accomapny_animation_0.png in Resources */,
 				BC2456F4286BEFDA00D1F7C0 /* MineEmptyVideoCell.xib in Resources */,
@@ -7456,6 +7745,7 @@
 				BCC5840028A9FA8100BAB4CF /* cloud_animation_15.png in Resources */,
 				BC5E4B2B291E5E26001BBCD2 /* ToneTuningBodyView.xib in Resources */,
 				BC4BCE772823AA3F00522C8B /* areainfo.json in Resources */,
+				BC106BAA2A8F45AA000759A9 /* TXLiveMemberSeatCell.xib in Resources */,
 				BC71D1F62887FDD40010F14B /* img_29.png in Resources */,
 				BCF1BA5627F5CBA100FA36C4 /* LiveSeatApplyView.xib in Resources */,
 				BC8B6E562856ED0600866917 /* iOS集成升级必读.pdf in Resources */,
@@ -7464,6 +7754,7 @@
 				BC7B0F5229271B650044CF61 /* CourseWarePreviewView.xib in Resources */,
 				BC71D1EB2887FDD40010F14B /* img_1.png in Resources */,
 				BC71DF262A8A014F003F165E /* KSImageDisplayView.xib in Resources */,
+				BC106BB82A8F6EAB000759A9 /* ShareLiveCellContentView.xib in Resources */,
 				BC3673DB28A606A500059721 /* live_animation_1.png in Resources */,
 				BC71DEF92A89F470003F165E /* TxClassroomChatOtherCell.xib in Resources */,
 				BCC583FB28A9FA8100BAB4CF /* cloud_animation_27.png in Resources */,
@@ -7486,13 +7777,14 @@
 				BC7CFFCA2817F2FF00CAEB21 /* CashRecordListCell.xib in Resources */,
 				BCB9FA41286DA337005D766B /* GuideListView.xib in Resources */,
 				BC3ACDA12891261F00060E97 /* MyMusicNavView.xib in Resources */,
-				BCB908DD2850A71800F5FF69 /* ShareMusicCellContentView.xib in Resources */,
 				BC71D2062887FDD40010F14B /* img_23.png in Resources */,
 				BC513E7E28A4D874003F58C4 /* live_animation.json in Resources */,
+				BC106BA32A8F45AA000759A9 /* TXLiveRoomHeadView.xib in Resources */,
 				27D83F5927F4225D00062476 /* LivePreviewBodyView.xib in Resources */,
 				BC41104A2806706800800BD9 /* HomeworkListCell.xib in Resources */,
 				BCD457A72863196F0010B493 /* CourseTimeSegView.xib in Resources */,
 				BC9070A428C7159F00237958 /* MyStyleNavView.xib in Resources */,
+				BC106BB62A8F6E94000759A9 /* ShareMusicCellContentView.xib in Resources */,
 				2779362E27E33C360010E277 /* LoginBodyView.xib in Resources */,
 				BC8B6E6E285836B600866917 /* low_staff.png in Resources */,
 				BCB399BD27F9831D00AFF376 /* CourseForLiveCell.xib in Resources */,
@@ -7507,6 +7799,7 @@
 				BC7CFFBA2817E9FC00CAEB21 /* echarts.min.js in Resources */,
 				BC3673D528A606A500059721 /* live_animation_2.png in Resources */,
 				BC71D2012887FDD40010F14B /* img_18.png in Resources */,
+				BC106BA62A8F45AA000759A9 /* TXLiveDownSeatView.xib in Resources */,
 				BC1263A528FF98BB00509E90 /* HomeNewMusicView.xib in Resources */,
 				BCE6A08727F81B4D00C97704 /* MinePageSubmitView.xib in Resources */,
 				BC71DF0D2A89F470003F165E /* NewTXMetronomeAlertView.xib in Resources */,
@@ -7717,6 +8010,7 @@
 				BCDF82192A8A2BEF005F8B82 /* InputView.m in Sources */,
 				BCD6D15C281950E9009A773E /* WithdrawModel.m in Sources */,
 				BCE6A08527F81B4200C97704 /* MinePageSubmitView.m in Sources */,
+				BC106B822A8F4586000759A9 /* TXLiveMessageUserQuit.m in Sources */,
 				2779323227E30FC30010E277 /* ALCalendarManager.m in Sources */,
 				BC0A22A6284751F80065C1AB /* DownloadStatusCell.m in Sources */,
 				2779326F27E30FD80010E277 /* FSCalendarHeaderView.m in Sources */,
@@ -7724,9 +8018,11 @@
 				BC71DE922A89C937003F165E /* TXClassroomTextMsg.m in Sources */,
 				BC0238062865C4F6005560CA /* KSLiveChatroomMemberUp.m in Sources */,
 				277931E827E30FC20010E277 /* KSUtilities.m in Sources */,
+				BC106B332A8F4541000759A9 /* TXLiveMessageCenter.m in Sources */,
 				2779326327E30FD80010E277 /* FSCalendarCollectionView.m in Sources */,
 				BCA1135728A2439D007FAFB9 /* HomeBannerCell.m in Sources */,
 				BC2888522A80DB990064B773 /* AppDelegate+AppService.m in Sources */,
+				BC106B7A2A8F4586000759A9 /* TXLiveMessageLikeCount.m in Sources */,
 				BCED5CB128507E85009A42DE /* KSChatMusicMessage.m in Sources */,
 				BCA9CE3927FD93EB00D558C6 /* AccompanyStudentEvaCell.m in Sources */,
 				2779324027E30FC30010E277 /* VoNetworking+RequestManager.m in Sources */,
@@ -7750,10 +8046,13 @@
 				BCC0F6F32A8CF11700C4EFA4 /* TXClassRoomAlertView.m in Sources */,
 				BC56C97329238CBA00AF301F /* CoursewareAlertView.m in Sources */,
 				2779321F27E30FC30010E277 /* ShoppCatView.m in Sources */,
+				BC106BAB2A8F45AA000759A9 /* TXSeatContainerView.m in Sources */,
 				277931CD27E30FC20010E277 /* KSPremissionAlert.m in Sources */,
+				BC106B872A8F4586000759A9 /* TXConstMessage.m in Sources */,
 				2779323927E30FC30010E277 /* LLCollectionViewCell.m in Sources */,
 				2779326A27E30FD80010E277 /* FSCalendarWeekdayView.m in Sources */,
 				BC02BCF228B32771005CB483 /* KSRejectAllSeatMessage.m in Sources */,
+				BC106B302A8F4541000759A9 /* TXLiveRoomTimeManager.m in Sources */,
 				BCDB0931280583C100D0BDAD /* NSObject+KSDateFormatter.m in Sources */,
 				BC4BCE702823A02F00522C8B /* AddressBottomView.m in Sources */,
 				277931EB27E30FC20010E277 /* NSArray+zh_SafeAccess.m in Sources */,
@@ -7768,6 +8067,7 @@
 				BC5E4B1E291E5E26001BBCD2 /* SmallToolBodyView.m in Sources */,
 				BC4BCE6C28239EEB00522C8B /* MyAddressListCell.m in Sources */,
 				BCD6D16228195A17009A773E /* WithdrawApplyViewController.m in Sources */,
+				BC106B8C2A8F4586000759A9 /* TXLiveMessageSeatResponse.m in Sources */,
 				277932B627E30FFE0010E277 /* UIView+SDExtension.m in Sources */,
 				2779335C27E317CD0010E277 /* KSBaseModel.m in Sources */,
 				BC7CFFB72817E90700CAEB21 /* KSSegView.m in Sources */,
@@ -7775,6 +8075,7 @@
 				BC71DF112A89F470003F165E /* TXMetronomeAlertView.m in Sources */,
 				2779322227E30FC30010E277 /* KSImageButton.m in Sources */,
 				2723B68727F1642B00E0B90B /* HomeBodyView.m in Sources */,
+				BC106B252A8F44F8000759A9 /* TXLiveRoomViewController.m in Sources */,
 				2779320827E30FC30010E277 /* KSAudioRecordManager.m in Sources */,
 				27F9CAFB27EC1AF3003E0FE4 /* ContractListCell.m in Sources */,
 				BCDB093728058BBE00D0BDAD /* AccompanyLessonModel.m in Sources */,
@@ -7802,8 +8103,10 @@
 				BC5EB5B22804027500B4A3B0 /* MyStyleViewController.m in Sources */,
 				BCFE54182817BDFD00AD6786 /* IncomeHeaderView.m in Sources */,
 				BC8B641C28F3E8D800A08D16 /* KSAwardAlertView.m in Sources */,
+				BC106B7D2A8F4586000759A9 /* TXLiveMessageOpenLive.m in Sources */,
 				275B16FD27EB083C0081FDEF /* ChatAddressViewController.m in Sources */,
 				BC41104228066E5500800BD9 /* EvaluateCourseListViewController.m in Sources */,
+				BC106B8E2A8F4586000759A9 /* TXMicStatusSync.m in Sources */,
 				BC41103B28066D2E00800BD9 /* HomeworkBodyView.m in Sources */,
 				BC9070A228C7159800237958 /* MyStyleNavView.m in Sources */,
 				BC81F0E929232D01004106AF /* CoursewareListCell.m in Sources */,
@@ -7815,6 +8118,7 @@
 				BC5E4B2C291E5E26001BBCD2 /* WMGaugeViewStyleFlatThin.m in Sources */,
 				275E3DAD27F45BE90010EC30 /* KSChatroomMessageCenter.m in Sources */,
 				BC5E4B2D291E5E26001BBCD2 /* WMGaugeViewStyle3D.m in Sources */,
+				BC106BAD2A8F45AA000759A9 /* TXLiveRoomHeadView.m in Sources */,
 				BCA353CE2858A86200377661 /* MusicRoomCourseCell.m in Sources */,
 				BCA9CE4327FD947C00D558C6 /* AccompanyArrangeCell.m in Sources */,
 				2779322C27E30FC30010E277 /* ALCalendarHeader.m in Sources */,
@@ -7858,14 +8162,17 @@
 				2779322127E30FC30010E277 /* NSString+phone.m in Sources */,
 				BC5EB5BB2804083800B4A3B0 /* MyStyleIntroduceCell.m in Sources */,
 				277931D627E30FC20010E277 /* UIImage+Property.m in Sources */,
+				BC106BB02A8F46C0000759A9 /* LiveRoomConfirmAlert.m in Sources */,
 				2779326727E30FD80010E277 /* FSCalendarStickyHeader.m in Sources */,
 				BCB9FA592872C670005D766B /* LiveListBodyView.m in Sources */,
+				BC106B8B2A8F4586000759A9 /* TXLiveMessageMemberUp.m in Sources */,
 				BCD6D16A28195FBE009A773E /* CashRecordHeadView.m in Sources */,
 				277931F027E30FC20010E277 /* UIView+AddConstraints.m in Sources */,
 				277D432527E9A46A00107DB7 /* ModifyPhoneCheckController.m in Sources */,
 				BC5E4B1B291E5E26001BBCD2 /* Tuner.swift in Sources */,
 				BCC9F43327F69BD200647449 /* KSRemoteUserManager.m in Sources */,
 				BC450D352A86024600992740 /* UIButton+KSDelayAction.m in Sources */,
+				BC106B862A8F4586000759A9 /* TXLiveMessageKickOut.m in Sources */,
 				27F9CAF727EC1A16003E0FE4 /* UITableView+SCIndexView.m in Sources */,
 				275E3DC827F460720010EC30 /* KSLiveChatroomKickOut.m in Sources */,
 				2779361B27E32C3A0010E277 /* MineViewController.m in Sources */,
@@ -7877,10 +8184,12 @@
 				BCE6A07F27F7FACA00C97704 /* UIView+SubViewExtension.m in Sources */,
 				BCA9CE5027FD954800D558C6 /* AccompanyRemarkCell.m in Sources */,
 				BCDE359B289BC02200A9A560 /* HomeHotAlbumCell.m in Sources */,
+				BC106B712A8F4586000759A9 /* TXLiveUser.m in Sources */,
 				2779321B27E30FC30010E277 /* SearchView.m in Sources */,
 				BCFE540928168DFF00AD6786 /* KSButtonStatusView.m in Sources */,
 				BC5EB5A92803D85300B4A3B0 /* AccompanyAlertView.m in Sources */,
 				BC71DF1D2A89F470003F165E /* TXClassroomVideoListCell.m in Sources */,
+				BC106B812A8F4586000759A9 /* TXLiveMessageEnter.m in Sources */,
 				2708565227ED8B8C00EC8E72 /* GroupApplyChooseAllCell.m in Sources */,
 				277932BC27E30FFE0010E277 /* TAAbstractDotView.m in Sources */,
 				BCEA752328190D2900886A86 /* UnbindCardViewController.m in Sources */,
@@ -7916,6 +8225,7 @@
 				27F9030E27E875DD00C08A19 /* AudioPlayManager.m in Sources */,
 				BC000D9E2A84E68B006C5A89 /* KSTXGroupChatViewController.m in Sources */,
 				277935E227E327F00010E277 /* KSTabBarViewController.m in Sources */,
+				BC106B322A8F4541000759A9 /* TXLiveMessageModel.m in Sources */,
 				2779322727E30FC30010E277 /* KSInputView.m in Sources */,
 				BC71D293288811BF0010F14B /* AnimationHelper.m in Sources */,
 				BC60E3C0287D447F00B05441 /* DeleteAccountBodyView.m in Sources */,
@@ -7967,6 +8277,7 @@
 				BC7B0F5029271B5E0044CF61 /* CourseWarePreviewView.m in Sources */,
 				BC28886D2A8101310064B773 /* KSSearchResultListController.m in Sources */,
 				277931C027E30FC20010E277 /* ArchiveTools.m in Sources */,
+				BC106BA42A8F45AA000759A9 /* TXLiveChatListCell.m in Sources */,
 				BC1263A428FF98BB00509E90 /* HomeNewMusicView.m in Sources */,
 				BCDE359E289BC03E00A9A560 /* HomeAlbumModel.m in Sources */,
 				277931FA27E30FC20010E277 /* CALayer+Layout.m in Sources */,
@@ -7974,6 +8285,7 @@
 				BC0A22C528475E060065C1AB /* SongListViewController.m in Sources */,
 				BC71DF1B2A89F470003F165E /* IACircularSlider.m in Sources */,
 				BCE6A09A27F83E8E00C97704 /* MinePageVideoCell.m in Sources */,
+				BC106B752A8F4586000759A9 /* TXLiveMessageChatBan.m in Sources */,
 				BCA9CE2127FD642600D558C6 /* MyLiveCourseBodyView.m in Sources */,
 				BC71DF012A89F470003F165E /* TXMainEmtpyView.m in Sources */,
 				27F9030027E864AE00C08A19 /* NetworkBodyView.m in Sources */,
@@ -8004,6 +8316,8 @@
 				2779320127E30FC30010E277 /* KSStatusView.m in Sources */,
 				2779323027E30FC30010E277 /* ALCalendarPicker.m in Sources */,
 				BCB9FA13286C7C6C005D766B /* KSShareGroupViewController.m in Sources */,
+				BC106BA72A8F45AA000759A9 /* TXLiveSeatActionView.m in Sources */,
+				BC106B722A8F4586000759A9 /* TXLiveMessageShopRush.m in Sources */,
 				2779323E27E30FC30010E277 /* VoCacheManager.m in Sources */,
 				277931DE27E30FC20010E277 /* NSObject+AssociatedObject.m in Sources */,
 				27D83F4927F3EBC400062476 /* CreateLiveViewController.m in Sources */,
@@ -8015,6 +8329,7 @@
 				2779309927E30F480010E277 /* BaseViewController.m in Sources */,
 				BC71DF1E2A89F470003F165E /* TXClassroomVideoListView.m in Sources */,
 				BC5FF91728293C5600854D37 /* ReceiveListModel.m in Sources */,
+				BC106B8D2A8F4586000759A9 /* TXLiveMessageWelcome.m in Sources */,
 				BC245706286C434800D1F7C0 /* CoreAudioUtils.c in Sources */,
 				BC7CFFC92817F2FF00CAEB21 /* CashRecordListCell.m in Sources */,
 				BC7CFFBE2817F1D200CAEB21 /* MyBankCardViewController.m in Sources */,
@@ -8049,6 +8364,7 @@
 				275E8A6927E18F2300DD3F6E /* AppDelegate.m in Sources */,
 				2779361E27E3338E0010E277 /* KSUpdateManager.m in Sources */,
 				BCC9F42827F69BD200647449 /* WhiteUtils.m in Sources */,
+				BC106BB42A8F4BC9000759A9 /* LiveModuleService.m in Sources */,
 				BCB635BF27F7256B00ACFDCF /* KSDocument.m in Sources */,
 				BCDF822F2A8A3176005F8B82 /* KSValuePopView.m in Sources */,
 				2779322D27E30FC30010E277 /* ALCalendarDate.m in Sources */,
@@ -8076,8 +8392,10 @@
 				275B16EF27EAF9B20081FDEF /* ChatNavView.m in Sources */,
 				BCA353E92859A6FB00377661 /* MusicRoomHomeworkCell.m in Sources */,
 				BCEA752028190CEB00886A86 /* CardBandResultViewController.m in Sources */,
+				BC106BA92A8F45AA000759A9 /* TXLiveDownSeatView.m in Sources */,
 				BCB9FA4D28717BB2005D766B /* MyMusicSearchView.m in Sources */,
 				275B170527EB13420081FDEF /* KSChatListViewController.m in Sources */,
+				BC106B7C2A8F4586000759A9 /* TXLiveMessageSeatControl.m in Sources */,
 				277931C827E30FC20010E277 /* KSVideoEditor.m in Sources */,
 				BCA193B5282A80AA004A585D /* RecentCourseModel.m in Sources */,
 				2779326B27E30FD80010E277 /* FSCalendarSeparatorDecorationView.m in Sources */,
@@ -8089,6 +8407,7 @@
 				BCEA752B2819133E00886A86 /* CardBindResultBodyView.m in Sources */,
 				2779322827E30FC30010E277 /* KeyChainTools.m in Sources */,
 				BC4BCE682823991400522C8B /* AddressListViewController.m in Sources */,
+				BC106BA52A8F45AA000759A9 /* TXLiveMemberSeatCell.m in Sources */,
 				2779323827E30FC30010E277 /* LLPhoto.m in Sources */,
 				BC71DF2E2A8A2233003F165E /* KSNewWhiteBoard.m in Sources */,
 				BCDF82252A8A2F56005F8B82 /* KSCloseCourseView.m in Sources */,
@@ -8116,6 +8435,7 @@
 				BCC305F828FD4C0800C39762 /* KSChatUserDetailViewController.m in Sources */,
 				BC1365C4280D44EB00EB03E2 /* NotiferMessageViewController.m in Sources */,
 				27A54CF127E9BD3B007309A3 /* FeedbackViewController.m in Sources */,
+				BC106B7B2A8F4586000759A9 /* TXLiveMessageUnBlockUser.m in Sources */,
 				BC7705FD287676D3003EFA7F /* HomeActionView.m in Sources */,
 				275E3DE127F467410010EC30 /* KSChatInputView.m in Sources */,
 				BC5E4B30291E5E26001BBCD2 /* WidgetNavView.m in Sources */,
@@ -8189,6 +8509,8 @@
 				BCB635B927F722E800ACFDCF /* KSDocumentViewController.m in Sources */,
 				BC14A60D28A0AAE00086395C /* MineFunctionView.m in Sources */,
 				275E3DE727F4677F0010EC30 /* LiveRoomHeadView.m in Sources */,
+				BC106B882A8F4586000759A9 /* TXLiveMessageBlockUser.m in Sources */,
+				BC106B7E2A8F4586000759A9 /* TXLiveMessageDownSeatAll.m in Sources */,
 				2779320427E30FC30010E277 /* KSHoldButton.m in Sources */,
 				2779320627E30FC30010E277 /* UIView+ValueAdd.m in Sources */,
 				BCA9CE1527FD339400D558C6 /* AuthDisplayView.m in Sources */,
@@ -8214,9 +8536,12 @@
 				BC14A61228A0AC820086395C /* MineTeachToolView.m in Sources */,
 				BC02380F2865C6F9005560CA /* RCChatroomLikeCount.m in Sources */,
 				2779321727E30FC30010E277 /* UITextField_Toolbar.m in Sources */,
+				BC106B762A8F4586000759A9 /* TXLiveForceKickMsg.m in Sources */,
+				BC106BA82A8F45AA000759A9 /* TXLiveSeatBodyView.m in Sources */,
 				BC2456E3286BE85A00D1F7C0 /* MineStyleEmptyView.m in Sources */,
 				277D432F27E9A50800107DB7 /* PhoneChangeBodyView.m in Sources */,
 				BC71DE8F2A89C937003F165E /* TXRTCService.m in Sources */,
+				BC106B792A8F4586000759A9 /* TXLiveMessageRejectAllSeat.m in Sources */,
 				BC71DF212A89FABD003F165E /* TxRTCRoomConfig.m in Sources */,
 				277931EA27E30FC20010E277 /* UIAlertController+Extend.m in Sources */,
 				BCC0F7032A8CF13D00C4EFA4 /* TXDanBottomView.m in Sources */,
@@ -8225,6 +8550,7 @@
 				BC5E4B1D291E5E26001BBCD2 /* KSMetronomePlayer.m in Sources */,
 				BC2456EE286BEFC600D1F7C0 /* MineEmptyIntroduceCell.m in Sources */,
 				BCC0F7092A8CF13D00C4EFA4 /* TXDanMuView.m in Sources */,
+				BC106B732A8F4586000759A9 /* TXLiveTextMessage.m in Sources */,
 				2779326C27E30FD80010E277 /* FSCalendarExtensions.m in Sources */,
 				BCF61BEC28042D1A0000ACFE /* InstrumentMessageModel.m in Sources */,
 				BC58E7DD281B969B004B0893 /* MinePageTopView.m in Sources */,
@@ -8248,6 +8574,7 @@
 				BC14A61728A0B0440086395C /* MineBottomView.m in Sources */,
 				27F9CB1127EC60D0003E0FE4 /* GroupListModel.m in Sources */,
 				27FC2F5F27F1930400FCC239 /* KSStarView.m in Sources */,
+				BC106B802A8F4586000759A9 /* TXLiveCourseTimeChange.m in Sources */,
 				BC24570D286C436E00D1F7C0 /* KSCloudBeatView.m in Sources */,
 				BC81F0ED29233220004106AF /* CoursewareSearchView.m in Sources */,
 				2779320A27E30FC30010E277 /* HomeButton.m in Sources */,
@@ -8258,6 +8585,7 @@
 				27D83F4C27F3EC1500062476 /* CreateLiveBodyView.m in Sources */,
 				2779322027E30FC30010E277 /* GRScanManager.m in Sources */,
 				BC8C2C642824EB9000FBA5D5 /* NotiferHeadView.m in Sources */,
+				BC106B772A8F4586000759A9 /* TXLiveMessageDownSeat.m in Sources */,
 				27F902F427E863B600C08A19 /* NetworkingCheckController.m in Sources */,
 				BCD457A5286319660010B493 /* CourseTimeSegView.m in Sources */,
 				2779362327E334470010E277 /* KSUpdateAlert.m in Sources */,
@@ -8265,9 +8593,11 @@
 				BC8C2C7A28264CF400FBA5D5 /* ReceiveEvaluateListController.m in Sources */,
 				BC8B6DB8285327DD00866917 /* MusicShareDisplayView.m in Sources */,
 				BC71DE902A89C937003F165E /* TXClassroomDisplayMsg.m in Sources */,
+				BC106B312A8F4541000759A9 /* TXLiveURLUtils.m in Sources */,
 				277932BB27E30FFE0010E277 /* TAAnimatedDotView.m in Sources */,
 				BC542E3628406F7700633781 /* UserAuthBodyView.m in Sources */,
 				2779321827E30FC30010E277 /* SkipTextField.m in Sources */,
+				BC106B832A8F4586000759A9 /* TXLiveMessageLeave.m in Sources */,
 				BCA353ED2859B4EC00377661 /* MusicRoomHomeworkStudentController.m in Sources */,
 				BC6BEAA4288A4C2A00022109 /* KSHomeButton.m in Sources */,
 				27A2F63027E70E57009E2380 /* UserInfo.m in Sources */,
@@ -8278,6 +8608,7 @@
 				BC71DEF72A89F470003F165E /* TXChatAreaView.m in Sources */,
 				BCB9FA1F286D539A005D766B /* ScanNavView.m in Sources */,
 				2779330E27E3105F0010E277 /* DZNSegmentedControl.m in Sources */,
+				BC106B782A8F4586000759A9 /* TXLiveMessageSeatApply.m in Sources */,
 				BC28884A2A80DA200064B773 /* KSLoginManager.m in Sources */,
 				BC245707286C434800D1F7C0 /* CAudioUnit.m in Sources */,
 				277931D027E30FC20010E277 /* UILabel+QWTopLeftLabel.m in Sources */,
@@ -8306,6 +8637,7 @@
 				277931CF27E30FC20010E277 /* UIView+XIBView.m in Sources */,
 				27F9CB0427EC5446003E0FE4 /* GroupSettingViewController.m in Sources */,
 				2779320F27E30FC30010E277 /* shopview.m in Sources */,
+				BC106B892A8F4586000759A9 /* TXLiveMessageLike.m in Sources */,
 				BC7CFFD02817FF6700CAEB21 /* CardDisplayView.m in Sources */,
 				275E3DC527F460030010EC30 /* KSLiveChatroomClose.m in Sources */,
 				277932B527E30FFE0010E277 /* SDCycleScrollView.m in Sources */,
@@ -8316,6 +8648,7 @@
 				BC1365CF280D48B800EB03E2 /* HomeworkListModel.m in Sources */,
 				BC71DF0E2A89F470003F165E /* KSRateSliderView.m in Sources */,
 				2779326427E30FD80010E277 /* FSCalendarDelegationProxy.m in Sources */,
+				BC106B852A8F4586000759A9 /* TXLiveMessageCardMessage.m in Sources */,
 				277935DF27E326DA0010E277 /* KSNetTypeManager.m in Sources */,
 				2755C08527ED5770007D9070 /* GroupApplyMemberCell.m in Sources */,
 				27A54CEC27E9B96F007309A3 /* ModifyNameBodyView.m in Sources */,
@@ -8329,6 +8662,7 @@
 				BCE6A0A427F8517900C97704 /* MineVideoCell.m in Sources */,
 				BC0A22C0284752900065C1AB /* WhiteboardListCell.m in Sources */,
 				BCD457BE2865694B0010B493 /* KSRCPauseLiveMessage.m in Sources */,
+				BC106B842A8F4586000759A9 /* TXControlMemberMic.m in Sources */,
 				BC0A22C1284752900065C1AB /* WhiteboardListView.m in Sources */,
 				BC332DB3284866BE005AEF95 /* KSOrderManager.m in Sources */,
 				BCB908F72850C6EF00F5FF69 /* MusicChooseCell.m in Sources */,
@@ -8364,6 +8698,7 @@
 				BCC9F42C27F69BD200647449 /* InputTextField.m in Sources */,
 				2779320727E30FC30010E277 /* KSRecordStatusView.m in Sources */,
 				BC3ACD9F2891261800060E97 /* MyMusicNavView.m in Sources */,
+				BC106B8A2A8F4586000759A9 /* TXLiveMessageStatSync.m in Sources */,
 				2779329527E30FEB0010E277 /* MSSBrowseBaseViewController.m in Sources */,
 				BC41103828066C2F00800BD9 /* HomeworkListViewController.m in Sources */,
 				BC71DF172A89F470003F165E /* TXToolButtonView.m in Sources */,
@@ -8386,6 +8721,7 @@
 				277931EE27E30FC20010E277 /* UIView+Dealloc.m in Sources */,
 				2779320B27E30FC30010E277 /* KSFullDatePicker.m in Sources */,
 				BC12638028FEB5B900509E90 /* UserDetailNavView.m in Sources */,
+				BC106BAC2A8F45AA000759A9 /* TXUISeatMember.m in Sources */,
 				BCB9FA1C286D537E005D766B /* KSScanViewController.m in Sources */,
 				277931F427E30FC20010E277 /* NSDate+Extension.m in Sources */,
 				277931C127E30FC20010E277 /* NSDictionary+KSSafe.m in Sources */,
@@ -8403,6 +8739,7 @@
 				BC56C95D2923412800AF301F /* CoursewareViewModel.m in Sources */,
 				BC1191ED280E55CB00A716F7 /* EvaluateDetailModel.m in Sources */,
 				275E3DA927F45A8A0010EC30 /* KSLiveStreamVideo.m in Sources */,
+				BC106B7F2A8F4586000759A9 /* TXLiveMessagePauseLive.m in Sources */,
 				BC60E3BD287D294C00B05441 /* AccountDeleteViewController.m in Sources */,
 				BC56C95829233F1700AF301F /* CoursewareBottomView.m in Sources */,
 				BC6BEAAA288E3D7400022109 /* HomeNewHeadView.m in Sources */,
@@ -8416,6 +8753,7 @@
 				BC483231282A646A005F534C /* HomeRecentCourseView.m in Sources */,
 				277931C327E30FC20010E277 /* NSArray+KSSafe.m in Sources */,
 				BCB9FA42286DA337005D766B /* GuideListView.m in Sources */,
+				BC106B742A8F4586000759A9 /* TXLiveMessageClose.m in Sources */,
 				BCE6A09527F823DC00C97704 /* MinePageMusicCell.m in Sources */,
 				BC56C97829238D6300AF301F /* CoursewareListModel.m in Sources */,
 				27D83F3F27F3EA8A00062476 /* MinePageCourseView.m in Sources */,

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/AppDelegate.m

@@ -89,7 +89,7 @@
     }
     self.window = [[KSTouchCapturingWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
     
-    [[UITabBar appearance] setTranslucent:NO];
+//    [[UITabBar appearance] setTranslucent:NO];
     // 全局配置光标颜色
     [[UITextField appearance] setTintColor:THEMECOLOR];
     [[UITextView appearance] setTintColor:THEMECOLOR];

+ 7 - 13
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSBaseWKWebViewController.m

@@ -29,7 +29,8 @@
 #import "KSUMShareManager.h"
 #import "TZImageManager.h"
 #import "MusicRoomViewController.h"
-#import "LiveRoomViewController.h"
+#import "KSEnterLiveroomManager.h"
+
 
 #import "UserInfoManager.h"
 typedef NS_ENUM(NSInteger, CHOOSETYPE) {
@@ -205,12 +206,8 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
         WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
         config.selectionGranularity = WKSelectionGranularityDynamic;
         config.allowsInlineMediaPlayback = YES;
-        if (@available(iOS 10.0, *)) {
-            config.mediaTypesRequiringUserActionForPlayback = NO;
-        } else {
-            // Fallback on earlier versions
-            config.requiresUserActionForMediaPlayback = NO;
-        }
+        config.mediaTypesRequiringUserActionForPlayback = NO;
+
         config.processPool = [KSBaseWKWebViewController singleWkProcessPool];
         config.websiteDataStore = [WKWebsiteDataStore defaultDataStore];
         [self configUserAgent:config];
@@ -595,12 +592,9 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
 
 
 - (void)joinLiveRoomWithRoomId:(NSString *)roomId {
-    LiveRoomViewController *ctrl = [[LiveRoomViewController alloc] init];
-    ctrl.roomId = roomId;
-    ctrl.isTempRoom = NO;
-    CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:ctrl];
-    navCtrl.modalPresentationStyle = UIModalPresentationFullScreen;
-    [self.navigationController presentViewController:navCtrl animated:YES completion:nil];
+    [KSEnterLiveroomManager queryLiveStatusConfig:roomId isLiveCourse:YES liveContent:nil inController:(CustomNavViewController *)self.navigationController callback:^(ENTER_CALLTYPE type) {
+        
+    }];
 }
 
 - (void)savePicCallback:(NSString *)uuid isSuccess:(BOOL)isSuccess {

+ 2 - 2
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSDocumentViewController.m

@@ -17,7 +17,7 @@
 - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view.
-    [[UITabBar appearance] setTranslucent:YES];
+//    [[UITabBar appearance] setTranslucent:YES];
 }
 
 - (void)viewWillAppear:(BOOL)animated {
@@ -46,7 +46,7 @@
  
 -(void)dealloc
 {
-    [[UITabBar appearance] setTranslucent:NO];
+//    [[UITabBar appearance] setTranslucent:NO];
 }
 
 /*

+ 3 - 1
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.h

@@ -26,7 +26,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 #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
@@ -1326,5 +1327,6 @@ NS_ASSUME_NONNULL_BEGIN
 /// @param success 成功
 /// @param faliure 失败
 + (void)courseCoursewareRemoveRequest:(NSString *)post ids:(NSString *)ids success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
 @end
 NS_ASSUME_NONNULL_END

+ 8 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.m

@@ -288,6 +288,14 @@
     [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
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSTabBarViewController.m

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

+ 2 - 2
KulexiuForTeacher/KulexiuForTeacher/Common/Base/LoginManger/TXIMLinsenter.m

@@ -154,7 +154,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}];
@@ -164,7 +164,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}];
     }
 }
 

+ 7 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Extension/NSDictionary+Extension.h

@@ -27,6 +27,13 @@
 - (int)ks_intValueForKey:(id)key;
 
 /**
+ 从字典里取NSUInteger(内带判空)
+ 
+ @param key 字典Key值
+ @return NSUInteger
+ */
+- (NSUInteger)ks_unsignLongValueForKey:(id)key;
+/**
  从字典里取long long(内带判空)
  
  @param key 字典Key值

+ 10 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Extension/NSDictionary+Extension.m

@@ -20,6 +20,16 @@
     return value == nil ? 0 : [value intValue];
 }
 
+/**
+ 从字典里取NSUInteger(内带判空)
+ 
+ @param key 字典Key值
+ @return NSUInteger
+ */
+- (NSUInteger)ks_unsignLongValueForKey:(id)key {
+    id value = [self notNullValueForKey:key];
+    return value == nil ? 0 : [value unsignedLongValue];
+}
 
 - (long long)ks_longlongValueForKey:(id)key {
     id value = [self notNullValueForKey:key];

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

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

+ 6 - 13
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/CreateLiveViewController.m

@@ -8,9 +8,9 @@
 #import "CreateLiveViewController.h"
 #import "CreateLiveBodyView.h"
 #import "CustomNavViewController.h"
-#import "LiveRoomViewController.h"
 #import "KSChoosePicker.h"
 #import "KSMediaManager.h"
+#import "KSEnterLiveroomManager.h"
 
 @interface CreateLiveViewController ()
 
@@ -145,19 +145,12 @@
 }
 
 - (void)previewViewWithRoomId:(NSString *)roomId liveDesc:(NSString *)liveDesc {
-    LiveRoomViewController *ctrl = [[LiveRoomViewController alloc] init];
-    ctrl.roomId = roomId;
-    ctrl.isTempRoom = YES;
-    ctrl.liveContent = liveDesc;
-    MJWeakSelf;
-    [ctrl backRefreshCallback:^{
-        [weakSelf backAction];
-    }];
-    CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:ctrl];
-    navCtrl.modalPresentationStyle = UIModalPresentationFullScreen;
-    
     
-    [self.navigationController presentViewController:navCtrl animated:YES completion:nil];
+    [KSEnterLiveroomManager queryLiveStatusConfig:roomId isLiveCourse:NO liveContent:liveDesc inController:(CustomNavViewController *)self.navigationController callback:^(ENTER_CALLTYPE type) {
+        if (type == ENTER_CALLTYPE_BACK) {
+            [self backAction];
+        }
+    }];
 }
 
 #pragma mark - 懒加载

+ 4 - 7
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LiveRoomViewController.m

@@ -317,9 +317,6 @@ typedef NS_ENUM(NSInteger, LIVEPAGE) {
     KSShareChooseViewController *chooseCtrl = [[KSShareChooseViewController alloc] init];
     chooseCtrl.msgData = data;
     [self.navigationController pushViewController:chooseCtrl animated:YES];
-    
-    
-    
 }
 
 - (void)displayBeautyView {
@@ -1645,10 +1642,10 @@ typedef NS_ENUM(NSInteger, LIVEPAGE) {
             [self displaySeatView];
         }
             break;
-        case LIVEROOMACTION_QUIT: // 退出
-        {
-            [self showMoreView];
-        }
+//        case LIVEROOMACTION_QUIT: // 退出
+//        {
+//            [self showMoreView];
+//        }
             break;
         case LIVEROOMACTION_MICACTION:
         {

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

@@ -1,43 +0,0 @@
-//
-//  KSEnterLiveroomManager.m
-//  KulexiuForTeacher
-//
-//  Created by Kyle on 2022/3/30.
-//
-
-#import "KSEnterLiveroomManager.h"
-
-
-@implementation KSEnterLiveroomManager
-
-
-+ (void)queryLiveroomConfig:(NSString *)roomId callback:(RoomConfigCallback)callback {
-    [KSNetworkingManager speakerCheckRoomInfoRequest:KS_GET roomUid:roomId success:^(NSDictionary * _Nonnull dic) {
-        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
-            callback([dic ks_dictionaryValueForKey:@"data"]);
-        }
-        else {
-            [self MBShowInWindow:MESSAGEKEY];
-            callback(nil);
-        }
-    } faliure:^(NSError * _Nonnull error) {
-        callback(nil);
-    }];
-}
-
-+ (void)MBShowInWindow:(NSString *)str {
-    [MBProgressHUD hideHUD];
-    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:[UIApplication sharedApplication].keyWindow animated:YES];
-    hud.removeFromSuperViewOnHide =YES;
-    hud.mode = MBProgressHUDModeText;
-    hud.label.text = str;
-    hud.label.numberOfLines = 0;
-    hud.minSize = CGSizeMake(132.f, 60.0f);
-    hud.label.textColor = [UIColor whiteColor];
-    hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
-    hud.bezelView.backgroundColor = [UIColor colorWithHexString:@"#000000" alpha:0.8];
-    double hiddenTime = str.length > 15 ? 3.0f : 1.5f;
-    [hud hideAnimated:YES afterDelay:hiddenTime];
-}
-
-@end

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/LiveSeatMember.h

@@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
 
 @property (nonatomic, assign) BOOL isConnected; // 是否连上麦
 
-//@property (nonatomic, assign) BOOL quitTag;
+@property (nonatomic, assign) BOOL isMicMute;  // 是否mic静音
 
 @end
 

+ 11 - 55
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LivePreviewBodyView.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -24,17 +24,17 @@
                     <rect key="frame" x="81.5" y="608.5" width="251" height="76"/>
                     <subviews>
                         <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="utK-Cw-EDV">
-                            <rect key="frame" x="0.0" y="0.0" width="83.5" height="76"/>
+                            <rect key="frame" x="0.0" y="0.0" width="125.5" height="76"/>
                             <subviews>
                                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="live_switch" translatesAutoresizingMaskIntoConstraints="NO" id="lKf-On-Nhz">
-                                    <rect key="frame" x="24.5" y="10" width="35" height="35"/>
+                                    <rect key="frame" x="45.5" y="10" width="35" height="35"/>
                                     <constraints>
                                         <constraint firstAttribute="width" constant="35" id="ilG-Eb-HZf"/>
                                         <constraint firstAttribute="height" constant="35" id="rjF-Db-eZM"/>
                                     </constraints>
                                 </imageView>
                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="翻转" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6dP-na-Q0G">
-                                    <rect key="frame" x="30.5" y="48" width="23" height="16"/>
+                                    <rect key="frame" x="51.5" y="48" width="23" height="16"/>
                                     <constraints>
                                         <constraint firstAttribute="height" constant="16" id="mrk-u6-hK9"/>
                                     </constraints>
@@ -43,7 +43,7 @@
                                     <nil key="highlightedColor"/>
                                 </label>
                                 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Q0-gr-Dbs">
-                                    <rect key="frame" x="0.0" y="0.0" width="83.5" height="76"/>
+                                    <rect key="frame" x="0.0" y="0.0" width="125.5" height="76"/>
                                     <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                     <connections>
                                         <action selector="switchAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="luH-9V-uMZ"/>
@@ -62,57 +62,18 @@
                                 <constraint firstAttribute="trailing" secondItem="3Q0-gr-Dbs" secondAttribute="trailing" id="vOd-6V-d8M"/>
                             </constraints>
                         </view>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vhH-ad-pgs">
-                            <rect key="frame" x="83.5" y="0.0" width="84" height="76"/>
-                            <subviews>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="livePrew_beauty" translatesAutoresizingMaskIntoConstraints="NO" id="4dd-Kh-Kmk">
-                                    <rect key="frame" x="24.5" y="10" width="35" height="35"/>
-                                    <constraints>
-                                        <constraint firstAttribute="width" constant="35" id="Khe-GL-mWs"/>
-                                        <constraint firstAttribute="height" constant="35" id="qhs-hu-n1W"/>
-                                    </constraints>
-                                </imageView>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="美颜" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="j4U-EV-Gh0">
-                                    <rect key="frame" x="30.5" y="48" width="23" height="16"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="16" id="bTP-CQ-5pM"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="11"/>
-                                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TJq-DR-AeU">
-                                    <rect key="frame" x="0.0" y="0.0" width="84" height="76"/>
-                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                                    <connections>
-                                        <action selector="beautyAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="Hlz-7Z-w4w"/>
-                                    </connections>
-                                </button>
-                            </subviews>
-                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                            <constraints>
-                                <constraint firstItem="4dd-Kh-Kmk" firstAttribute="top" secondItem="vhH-ad-pgs" secondAttribute="top" constant="10" id="443-BX-uep"/>
-                                <constraint firstItem="4dd-Kh-Kmk" firstAttribute="centerX" secondItem="vhH-ad-pgs" secondAttribute="centerX" id="IEg-Yo-jVy"/>
-                                <constraint firstAttribute="bottom" secondItem="TJq-DR-AeU" secondAttribute="bottom" id="Jfb-mv-imx"/>
-                                <constraint firstItem="j4U-EV-Gh0" firstAttribute="centerX" secondItem="4dd-Kh-Kmk" secondAttribute="centerX" id="Twf-JO-ynW"/>
-                                <constraint firstItem="j4U-EV-Gh0" firstAttribute="top" secondItem="4dd-Kh-Kmk" secondAttribute="bottom" constant="3" id="VPq-i3-dPS"/>
-                                <constraint firstAttribute="trailing" secondItem="TJq-DR-AeU" secondAttribute="trailing" id="WbV-II-nTh"/>
-                                <constraint firstItem="TJq-DR-AeU" firstAttribute="top" secondItem="vhH-ad-pgs" secondAttribute="top" id="dsb-mk-oTi"/>
-                                <constraint firstItem="TJq-DR-AeU" firstAttribute="leading" secondItem="vhH-ad-pgs" secondAttribute="leading" id="fNS-Pp-8Lu"/>
-                            </constraints>
-                        </view>
                         <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jAT-dj-aq8">
-                            <rect key="frame" x="167.5" y="0.0" width="83.5" height="76"/>
+                            <rect key="frame" x="125.5" y="0.0" width="125.5" height="76"/>
                             <subviews>
                                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="live_share" translatesAutoresizingMaskIntoConstraints="NO" id="nc9-4x-kHq">
-                                    <rect key="frame" x="24" y="10" width="35" height="35"/>
+                                    <rect key="frame" x="45.5" y="10" width="35" height="35"/>
                                     <constraints>
                                         <constraint firstAttribute="height" constant="35" id="8nt-P7-avU"/>
                                         <constraint firstAttribute="width" constant="35" id="uSC-nv-5GY"/>
                                     </constraints>
                                 </imageView>
                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="分享" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Bpv-QR-PtI">
-                                    <rect key="frame" x="30" y="48" width="23" height="16"/>
+                                    <rect key="frame" x="51.5" y="48" width="23" height="16"/>
                                     <constraints>
                                         <constraint firstAttribute="height" constant="16" id="grB-Ze-frq"/>
                                     </constraints>
@@ -121,7 +82,7 @@
                                     <nil key="highlightedColor"/>
                                 </label>
                                 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cjc-mH-jHh">
-                                    <rect key="frame" x="0.0" y="0.0" width="83.5" height="76"/>
+                                    <rect key="frame" x="0.0" y="0.0" width="125.5" height="76"/>
                                     <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                     <connections>
                                         <action selector="shareAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="SF3-Tf-k7q"/>
@@ -144,19 +105,15 @@
                     <color key="backgroundColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="0.25" colorSpace="custom" customColorSpace="calibratedRGB"/>
                     <constraints>
                         <constraint firstItem="jAT-dj-aq8" firstAttribute="width" secondItem="utK-Cw-EDV" secondAttribute="width" id="0aS-HW-sVk"/>
-                        <constraint firstAttribute="bottom" secondItem="vhH-ad-pgs" secondAttribute="bottom" id="5VH-L7-Ddf"/>
-                        <constraint firstItem="vhH-ad-pgs" firstAttribute="leading" secondItem="utK-Cw-EDV" secondAttribute="trailing" id="LAZ-t9-jV1"/>
-                        <constraint firstItem="vhH-ad-pgs" firstAttribute="width" secondItem="utK-Cw-EDV" secondAttribute="width" id="UZ5-vx-Rdn"/>
                         <constraint firstAttribute="width" constant="251" id="Ubg-yr-iPK"/>
                         <constraint firstItem="jAT-dj-aq8" firstAttribute="top" secondItem="XeW-qC-lAf" secondAttribute="top" id="gsa-Ij-iNg"/>
-                        <constraint firstItem="vhH-ad-pgs" firstAttribute="top" secondItem="XeW-qC-lAf" secondAttribute="top" id="izP-7H-KLr"/>
                         <constraint firstAttribute="bottom" secondItem="utK-Cw-EDV" secondAttribute="bottom" id="j2i-p7-8nf"/>
                         <constraint firstItem="utK-Cw-EDV" firstAttribute="leading" secondItem="XeW-qC-lAf" secondAttribute="leading" id="kbp-n5-G0A"/>
-                        <constraint firstItem="jAT-dj-aq8" firstAttribute="leading" secondItem="vhH-ad-pgs" secondAttribute="trailing" id="l4J-RU-UfG"/>
                         <constraint firstAttribute="trailing" secondItem="jAT-dj-aq8" secondAttribute="trailing" id="p6Y-cm-oFt"/>
                         <constraint firstItem="utK-Cw-EDV" firstAttribute="top" secondItem="XeW-qC-lAf" secondAttribute="top" id="rTd-JI-zwO"/>
                         <constraint firstAttribute="height" constant="76" id="sty-yK-rcr"/>
                         <constraint firstAttribute="bottom" secondItem="jAT-dj-aq8" secondAttribute="bottom" id="wlL-vf-TFQ"/>
+                        <constraint firstItem="jAT-dj-aq8" firstAttribute="leading" secondItem="utK-Cw-EDV" secondAttribute="trailing" id="zJ7-Wd-ee5"/>
                     </constraints>
                     <userDefinedRuntimeAttributes>
                         <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
@@ -230,7 +187,6 @@
     </objects>
     <resources>
         <image name="livePreview_close" width="18" height="18"/>
-        <image name="livePrew_beauty" width="35" height="35"/>
         <image name="live_share" width="35" height="35"/>
         <image name="live_switch" width="35" height="35"/>
     </resources>

+ 5 - 3
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.h

@@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN
 typedef NS_ENUM(NSInteger, LIVEROOMACTION) {
     LIVEROOMACTION_CHAT,
     LIVEROOMACTION_SEAT,
-    LIVEROOMACTION_QUIT,
+    LIVEROOMACTION_MORE,
     LIVEROOMACTION_MICACTION,
 };
 
@@ -20,12 +20,14 @@ typedef void(^LiveBottomCallback)(LIVEROOMACTION action);
 
 @interface LiveRoomBottomView : UIView
 
+@property (weak, nonatomic) IBOutlet UIButton *micButton;
+
+@property (weak, nonatomic) IBOutlet UIButton *moreButton;
+
 @property (nonatomic, assign) BOOL isMicOn;
 
 + (instancetype)shareInstance;
 
-@property (weak, nonatomic) IBOutlet UIButton *micButton;
-
 - (void)bottomClickAction:(LiveBottomCallback)callback;
 
 @end

+ 10 - 8
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.m

@@ -26,14 +26,21 @@
     }
 }
 
+- (IBAction)micButtonAction:(id)sender {
+    if (self.callback) {
+        self.callback(LIVEROOMACTION_MICACTION);
+    }
+}
+
 - (IBAction)seatAction:(id)sender {
     if (self.callback) {
         self.callback(LIVEROOMACTION_SEAT);
     }
 }
-- (IBAction)quitAction:(id)sender {
+
+- (IBAction)moreAction:(id)sender {
     if (self.callback) {
-        self.callback(LIVEROOMACTION_QUIT);
+        self.callback(LIVEROOMACTION_MORE);
     }
 }
 
@@ -43,12 +50,6 @@
     }
 }
 
-- (IBAction)micButtonAction:(id)sender {
-    if (self.callback) {
-        self.callback(LIVEROOMACTION_MICACTION);
-    }
-}
-
 - (void)setIsMicOn:(BOOL)isMicOn {
     _isMicOn = isMicOn;
     NSString *imageName = @"";
@@ -61,6 +62,7 @@
     [self.micButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
 }
 
+
 /*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.

+ 35 - 51
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveRoomBottomView.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -14,16 +14,16 @@
             <autoresizingMask key="autoresizingMask"/>
             <subviews>
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jTy-ba-b13">
-                    <rect key="frame" x="12" y="24" width="238" height="38"/>
+                    <rect key="frame" x="12" y="24" width="250" height="38"/>
                     <subviews>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="和同学聊两句~" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kYE-Qz-HRk">
-                            <rect key="frame" x="14" y="10.5" width="100" height="17"/>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="快来互动吧!" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kYE-Qz-HRk">
+                            <rect key="frame" x="14" y="10.5" width="86" height="17"/>
                             <fontDescription key="fontDescription" type="system" pointSize="14"/>
                             <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                             <nil key="highlightedColor"/>
                         </label>
                         <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="liveroom_chat" translatesAutoresizingMaskIntoConstraints="NO" id="cPM-ak-zqh">
-                            <rect key="frame" x="201" y="6" width="26" height="26"/>
+                            <rect key="frame" x="213" y="6" width="26" height="26"/>
                         </imageView>
                     </subviews>
                     <color key="backgroundColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="0.25" colorSpace="calibratedRGB"/>
@@ -44,72 +44,61 @@
                         <outletCollection property="gestureRecognizers" destination="NfQ-Px-XVN" appends="YES" id="bAE-zd-lYr"/>
                     </connections>
                 </view>
-                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ggL-eh-YOa">
-                    <rect key="frame" x="260" y="21" width="44" height="44"/>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zan-87-t9F">
+                    <rect key="frame" x="314" y="21" width="44" height="44"/>
                     <constraints>
-                        <constraint firstAttribute="width" constant="44" id="e86-p7-Vye"/>
-                        <constraint firstAttribute="height" constant="44" id="geo-3u-phf"/>
+                        <constraint firstAttribute="height" constant="44" id="7Je-mB-8su"/>
+                        <constraint firstAttribute="width" constant="44" id="kog-Hz-mLS"/>
                     </constraints>
                     <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                    <state key="normal" image="seat_image"/>
+                    <state key="normal" image="live_micOn"/>
                     <connections>
-                        <action selector="seatAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="9mg-Nx-aBn"/>
+                        <action selector="micButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="AHw-pb-3bW"/>
                     </connections>
                 </button>
-                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="HuW-Iz-IGX">
-                    <rect key="frame" x="309" y="21" width="44" height="44"/>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="grR-xq-Urr">
+                    <rect key="frame" x="358" y="21" width="44" height="44"/>
                     <constraints>
-                        <constraint firstAttribute="width" constant="44" id="hgb-6c-iv7"/>
-                        <constraint firstAttribute="height" constant="44" id="oEM-kE-U0P"/>
+                        <constraint firstAttribute="width" constant="44" id="NEi-Tn-v9J"/>
+                        <constraint firstAttribute="height" constant="44" id="Xxe-yP-AOf"/>
                     </constraints>
                     <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                    <state key="normal" image="live_micOn"/>
+                    <state key="normal" image="liveroom_quit"/>
                     <connections>
-                        <action selector="micButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="7hE-vy-vbs"/>
+                        <action selector="moreAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="2t7-bB-r9J"/>
                     </connections>
                 </button>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0Pn-yj-7I8">
-                    <rect key="frame" x="358" y="21" width="44" height="44"/>
-                    <subviews>
-                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="liveroom_quit" translatesAutoresizingMaskIntoConstraints="NO" id="fke-RK-gH7">
-                            <rect key="frame" x="3" y="3" width="38" height="38"/>
-                            <gestureRecognizers/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="38" id="AzP-vU-Mwh"/>
-                                <constraint firstAttribute="height" constant="38" id="iMV-kR-ZFB"/>
-                            </constraints>
-                        </imageView>
-                    </subviews>
-                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                    <gestureRecognizers/>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ggL-eh-YOa">
+                    <rect key="frame" x="270" y="21" width="44" height="44"/>
                     <constraints>
-                        <constraint firstItem="fke-RK-gH7" firstAttribute="centerX" secondItem="0Pn-yj-7I8" secondAttribute="centerX" id="1zy-tP-WBf"/>
-                        <constraint firstAttribute="width" constant="44" id="79L-lk-6FE"/>
-                        <constraint firstItem="fke-RK-gH7" firstAttribute="centerY" secondItem="0Pn-yj-7I8" secondAttribute="centerY" id="cJW-kq-uui"/>
-                        <constraint firstAttribute="height" constant="44" id="jzU-J7-PHi"/>
+                        <constraint firstAttribute="width" constant="44" id="e86-p7-Vye"/>
+                        <constraint firstAttribute="height" constant="44" id="geo-3u-phf"/>
                     </constraints>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" image="seat_image"/>
                     <connections>
-                        <outletCollection property="gestureRecognizers" destination="eAc-nw-wLB" appends="YES" id="UtO-DF-lUC"/>
+                        <action selector="seatAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="DkM-24-YIW"/>
                     </connections>
-                </view>
+                </button>
             </subviews>
             <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
             <constraints>
-                <constraint firstItem="ggL-eh-YOa" firstAttribute="centerY" secondItem="jTy-ba-b13" secondAttribute="centerY" id="Fdf-Xi-1cU"/>
-                <constraint firstItem="0Pn-yj-7I8" firstAttribute="centerY" secondItem="jTy-ba-b13" secondAttribute="centerY" id="JME-zi-czB"/>
-                <constraint firstItem="ggL-eh-YOa" firstAttribute="leading" secondItem="jTy-ba-b13" secondAttribute="trailing" constant="10" id="KRm-Tz-ut5"/>
-                <constraint firstAttribute="trailing" secondItem="0Pn-yj-7I8" secondAttribute="trailing" constant="12" id="UVM-th-SZ5"/>
-                <constraint firstItem="HuW-Iz-IGX" firstAttribute="leading" secondItem="ggL-eh-YOa" secondAttribute="trailing" constant="5" id="Z8T-VD-M7b"/>
+                <constraint firstItem="zan-87-t9F" firstAttribute="leading" secondItem="ggL-eh-YOa" secondAttribute="trailing" id="AHt-Ef-zl6"/>
+                <constraint firstItem="grR-xq-Urr" firstAttribute="centerY" secondItem="ggL-eh-YOa" secondAttribute="centerY" id="AqT-FZ-xqo"/>
+                <constraint firstItem="zan-87-t9F" firstAttribute="centerY" secondItem="ggL-eh-YOa" secondAttribute="centerY" id="DQi-1D-wyM"/>
+                <constraint firstItem="grR-xq-Urr" firstAttribute="leading" secondItem="zan-87-t9F" secondAttribute="trailing" id="Qas-Yg-RVR"/>
+                <constraint firstAttribute="trailing" secondItem="grR-xq-Urr" secondAttribute="trailing" constant="12" id="SjC-r2-6oc"/>
+                <constraint firstItem="ggL-eh-YOa" firstAttribute="leading" secondItem="jTy-ba-b13" secondAttribute="trailing" constant="8" id="Ukd-Ji-6nH"/>
                 <constraint firstItem="jTy-ba-b13" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="12" id="dmB-Tj-Bau"/>
-                <constraint firstItem="0Pn-yj-7I8" firstAttribute="leading" secondItem="HuW-Iz-IGX" secondAttribute="trailing" constant="5" id="lbE-Kg-N5J"/>
+                <constraint firstItem="ggL-eh-YOa" firstAttribute="centerY" secondItem="jTy-ba-b13" secondAttribute="centerY" id="qDr-PR-QaJ"/>
                 <constraint firstItem="jTy-ba-b13" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="t8u-VX-RG5"/>
-                <constraint firstItem="HuW-Iz-IGX" firstAttribute="centerY" secondItem="ggL-eh-YOa" secondAttribute="centerY" id="tXZ-75-tTf"/>
             </constraints>
             <nil key="simulatedTopBarMetrics"/>
             <nil key="simulatedBottomBarMetrics"/>
             <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
             <connections>
-                <outlet property="micButton" destination="HuW-Iz-IGX" id="kI6-FK-8sJ"/>
+                <outlet property="micButton" destination="zan-87-t9F" id="anQ-pW-ttu"/>
+                <outlet property="moreButton" destination="grR-xq-Urr" id="h62-8I-ss3"/>
             </connections>
             <point key="canvasLocation" x="131.8840579710145" y="-12.723214285714285"/>
         </view>
@@ -118,11 +107,6 @@
                 <action selector="chatAction:" destination="iN0-l3-epB" id="1kD-cA-vvt"/>
             </connections>
         </tapGestureRecognizer>
-        <tapGestureRecognizer id="eAc-nw-wLB">
-            <connections>
-                <action selector="quitAction:" destination="iN0-l3-epB" id="QFD-cp-ZIx"/>
-            </connections>
-        </tapGestureRecognizer>
     </objects>
     <resources>
         <image name="live_micOn" width="38" height="38"/>

+ 5 - 8
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/LiveList/View/LiveListBodyView.m

@@ -9,7 +9,7 @@
 #import "UnderwayLiveCell.h"
 #import "FinishedLiveCell.h"
 #import "LiveListModel.h"
-#import "LiveRoomViewController.h"
+#import "KSEnterLiveroomManager.h"
 #import "CustomNavViewController.h"
 #import "LiveVideoListView.h"
 #import "LiveVideoModel.h"
@@ -192,13 +192,10 @@
 }
 
 - (void)toLiveRoomWithRoomMessaeg:(LiveListModel *)listModel {
-    LiveRoomViewController *ctrl = [[LiveRoomViewController alloc] init];
-    ctrl.roomId = listModel.roomUid;
-    ctrl.isTempRoom = YES;
-    ctrl.liveContent = listModel.liveRemark;
-    CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:ctrl];
-    navCtrl.modalPresentationStyle = UIModalPresentationFullScreen;
-    [self.naviController presentViewController:navCtrl animated:YES completion:nil];
+    
+    [KSEnterLiveroomManager queryLiveStatusConfig:listModel.roomUid isLiveCourse:NO liveContent:listModel.liveRemark inController:(CustomNavViewController *)self.naviController callback:^(ENTER_CALLTYPE type) {
+        
+    }];
 }
 
 - (void)toRecordView:(LiveListModel *)listModel {

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/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 - 2
KulexiuForTeacher/KulexiuForTeacher/Module/TXClassRoom/Controller/TXClassroomViewController.m

@@ -2086,8 +2086,7 @@
         [_coursewareView configUI];
         MJWeakSelf;
         [_coursewareView chooseCoursewareCallback:^(NSString * _Nonnull musicUrl, NSString * _Nonnull musicName, NSString * _Nonnull songId) {
-            
-            [weakSelf notiferStudentDownload:songId songUrl:musicUrl accompanyUrl:nil songName:musicName];
+            [weakSelf notiferStudentDownload:songId songUrl:nil accompanyUrl:musicUrl songName:musicName];
         }];
     }
     return _coursewareView;

+ 58 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Controller/TXLiveRoomViewController.h

@@ -0,0 +1,58 @@
+//
+//  TXLiveRoomViewController.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/3/6.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "BaseViewController.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef void(^TXLiveRoomBackAction)(void);
+
+@interface TXLiveRoomViewController : BaseViewController
+
+@property (nonatomic, strong) NSString *liveContent; // 直播介绍
+
+@property (nonatomic, strong) NSString *roomId; // 房间号
+
+@property (nonatomic, assign) BOOL isEnterBackground;
+
+// 直播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 isLiveCourse;
+
+@property (nonatomic, assign) NSInteger surplusTime;
+
+@property (nonatomic, assign) NSInteger autoCloseNetworkRoomTime;
+
+// 课程编号
+@property (nonatomic, strong) NSString *courseId;
+
+@property (nonatomic, strong) NSString *subjectId;
+
+// 3A 参数
+@property (nonatomic, assign) NSInteger ANS;
+
+@property (nonatomic, assign) NSInteger AEC;
+
+@property (nonatomic, assign) NSInteger AGC;
+
+- (void)backRefreshCallback:(TXLiveRoomBackAction)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 2474 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Controller/TXLiveRoomViewController.m

@@ -0,0 +1,2474 @@
+//
+//  TXLiveRoomViewController.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/3/6.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveRoomViewController.h"
+#import "LivePreviewBodyView.h"
+#import "KSEnterLiveroomManager.h"
+#import "UserInfoManager.h"
+#import "KSChatInputBarControl.h"
+#import "TXLiveRoomHeadView.h"
+#import "LiveRoomBottomView.h"
+#import "SeatTipsView.h"
+#import "TXLiveChatListCell.h"
+#import "LiveRoomAlertView.h"
+#import "LiveMoreDisplayView.h"
+#import "LiveAnimationView.h"
+#import "TXLiveSeatActionView.h"
+
+#import "TXLiteAVSDK_Professional/TXLiteAVSDK.h"
+#import <ImSDK_Plus/ImSDK_Plus.h>
+#import "TXIMLinsenter.h"
+
+#import "TXLiveMessageModel.h"
+#import "TXLiveURLUtils.h"
+#import "TXLiveMessageCenter.h"
+#import "TXSeatContainerView.h"
+#import "TXUISeatMember.h"
+#import "TXLiveRoomTimeManager.h"
+#import "LiveRoomConfirmAlert.h"
+#import "LiveModuleService.h"
+#import "KSShareChooseViewController.h"
+
+typedef NS_ENUM(NSInteger, LIVEPAGE) {
+    LIVEPAGE_PREVIEW,
+    LIVEPAGE_LIVE,
+};
+
+@interface TXLiveRoomViewController ()<KSChatInputBarControlDelegate,UITableViewDataSource,UITableViewDelegate,TRTCCloudDelegate,UIGestureRecognizerDelegate,TXLiveRoomTimeManagerDelegate>
+
+@property (nonatomic, assign) LIVEPAGE pageType;
+
+@property (nonatomic, assign) BOOL isPauseLive; // 是否暂停直播
+
+@property (nonatomic, assign) BOOL isOtherLogin;  // 是否被顶掉
+
+@property (nonatomic, strong) LivePreviewBodyView *previewPageView;
+
+@property (nonatomic, strong) UIView *preVideoView;
+
+// rtc
+@property (nonatomic, strong) TRTCCloud *trtcCloud;
+
+#pragma mark ------- 直播房间信息
+
+/// 主讲人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;
+/// 房间人数
+@property (nonatomic, assign) NSInteger totalCount;
+
+#pragma mark ---- Live page
+
+@property (nonatomic, strong) UIView *livePageView;
+
+@property (nonatomic, assign) BOOL isImConnected;
+
+@property (nonatomic, assign) BOOL hasJoinRoomSuccess;
+
+@property (nonatomic, strong) UIView *localVideoView;
+
+@property (nonatomic, strong) UIView *liveVideoView;
+
+@property (nonatomic, strong) TXLiveRoomHeadView *headView;
+
+@property (nonatomic, copy) LiveRoomBottomView *bottomView;
+
+/// 连麦的视图
+@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, strong) UIView *seatCtrlView;
+
+@property (nonatomic, strong) TXLiveSeatActionView *seatActionView; // 连麦控制view
+
+@property (nonatomic, strong) NSMutableArray *seatApplyArray;  // 申请连麦数组
+
+// 远端连麦用户
+@property (nonatomic, strong) NSMutableArray *remoteMemberArray;
+
+/// 连麦申请统计数据
+@property (nonatomic, strong) SeatTipsView *seatApplyTips;
+
+/// 提示窗
+@property (nonatomic, strong) LiveRoomAlertView *alertView;
+
+
+// SEI消息定时器
+@property (nonatomic, strong) dispatch_source_t SEITimer;
+
+@property (nonatomic, strong) LiveMoreDisplayView *moreView;
+
+@property (nonatomic, strong) LiveAnimationView *animationView;
+
+@property (nonatomic, strong)  UITapGestureRecognizer *gesture;
+
+@property (nonatomic, assign) BOOL needPublishStream;
+
+@property (nonatomic, assign) BOOL micEnable;
+
+@property (nonatomic, assign) BOOL needSendOpenMsg;
+
+@property (nonatomic, assign) BOOL muteRoomMic;
+
+@property (nonatomic, strong) TXLiveRoomTimeManager *timeManager;
+
+@property (nonatomic, assign) BOOL isQuitRoom; // 是否正在退出房间
+
+@property (nonatomic, strong) LiveRoomConfirmAlert *closeAlert;
+
+@property (nonatomic, assign) NSTimeInterval lastSendMsgTime;
+
+@property (nonatomic, copy) TXLiveRoomBackAction callback;
+
+@end
+
+@implementation TXLiveRoomViewController
+
+- (void)backRefreshCallback:(TXLiveRoomBackAction)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+- (instancetype)init {
+    self = [super init];
+    if (self) {
+        [self default3AConfig];
+    }
+    return self;
+}
+
+- (void)default3AConfig {
+    self.ANS = 0;
+    self.AEC = 100;
+    self.AGC = 0;
+}
+
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    self.ks_prefersNavigationBarHidden = YES;
+    self.isOtherLogin = NO;
+    [self registerOtherLoginNotice];
+    [self configUI];
+    [self configEngine];
+    self.pageType = LIVEPAGE_PREVIEW;
+}
+
+- (void)registerOtherLoginNotice {
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(liveroomLogOut) name:@"liveroomLogout" object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(liveroomQuit) name:@"liveroomQuit" object:nil];
+}
+
+- (void)viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+    [UIApplication sharedApplication].idleTimerDisabled = YES;
+    [IQKeyboardManager sharedManager].enableAutoToolbar = NO;
+    [IQKeyboardManager sharedManager].enable = NO;
+    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
+}
+
+- (void)viewWillDisappear:(BOOL)animated {
+    [super viewWillDisappear:animated];
+    [UIApplication sharedApplication].idleTimerDisabled = 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;
+    }
+    if (_timeManager) {
+        [self.timeManager stopDurationTimer];
+    }
+}
+
+- (void)configUI {
+    self.previewPageView = [LivePreviewBodyView shareInstance];
+    [self.view addSubview:self.previewPageView];
+    [self.previewPageView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.bottom.top.mas_equalTo(self.view);
+    }];
+    MJWeakSelf;
+    [self.previewPageView previewOperationCallback:^(PREVIEWLIVEACTION action) {
+        [weakSelf previewOperationAction:action];
+    }];
+}
+
+- (void)configEngine {
+    if (!self.preVideoView) {
+        self.preVideoView = [[UIView alloc] init];
+        [self.previewPageView.videoView addSubview:self.preVideoView];
+        [self.preVideoView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.top.bottom.right.mas_equalTo(self.previewPageView.videoView);
+        }];
+    }
+    [self.trtcCloud startLocalPreview:YES view:self.preVideoView];
+}
+
+- (void)previewOperationAction:(PREVIEWLIVEACTION)action {
+    switch (action) {
+        case PREVIEWLIVEACTION_BACK: // 返回
+        {
+            if (self.isPauseLive) { // 退出RTC房间
+                [self quitRoomBackPreView:NO];
+            }
+            else {
+                [self.trtcCloud stopLocalPreview];
+                self.preVideoView = nil;
+                [self.trtcCloud stopPublishing];
+                [self.trtcCloud exitRoom];
+                [self.navigationController dismissViewControllerAnimated:YES completion:nil];
+            }
+        }
+            break;
+        case PREVIEWLIVEACTION_SWITCH: // 切换
+        {
+            [self switchCamera];
+        }
+            break;
+        case PREVIEWLIVEACTION_BEAUTY: // 美颜
+        {
+            
+        }
+            break;
+        case PREVIEWLIVEACTION_OPEN: // 进入直播间
+        {
+            [self showLiveView];
+        }
+            break;
+        case PREVIEWLIVEACTION_SHARE:
+        {
+            [self shareLiveRoomMessage];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)shareLiveRoomMessage {
+    // 选择群组分享
+    
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:@"TC_CHATSHARE_LIVE" forKey:@"businessID"];
+    [parm setValue:@"TXLiveShareCell" forKey:@"TMessageCell_Name"];
+    [parm setValue:@"TXLiveShareMessage" forKey:@"TMessageCell_Name"];
+    
+    NSString *teacherName = UserDefaultObjectForKey(NicknameKey);
+    if ([NSString isEmptyString:teacherName]) {
+        teacherName = [NSString stringWithFormat:@"游客%@",UserDefaultObjectForKey(UIDKey)];
+    }
+    [parm setValue:self.roomId forKey:@"roomUID"];
+    [parm setValue:teacherName forKey:@"teacherName"];
+    [parm setValue:UserDefaultObjectForKey(AvatarUrlKey) forKey:@"teacherAvatar"];
+    [parm setValue:self.liveContent forKey:@"liveDescMessage"];
+    
+    NSData *data = [NSJSONSerialization dataWithJSONObject:parm options:0 error:nil];
+    
+    
+    KSShareChooseViewController *chooseCtrl = [[KSShareChooseViewController alloc] init];
+    chooseCtrl.msgData = data;
+    [self.navigationController pushViewController:chooseCtrl animated:YES];
+}
+
+- (void)showLiveView {
+    if (self.isPauseLive) { // 直接切换页面
+        self.pageType = LIVEPAGE_LIVE;
+        [self.view addSubview:self.livePageView];
+        [self.livePageView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.bottom.mas_equalTo(self.view);
+        }];
+        // 开启推流
+        [self startPublishStream];
+    }
+    else {
+        [self showhud];
+        MJWeakSelf;
+        [KSEnterLiveroomManager queryLiveroomConfig:self.roomId callback:^(NSDictionary * _Nullable parm) {
+            [weakSelf removehub];
+            if (parm != nil) {
+                [weakSelf setupLiveroomConfig:parm];
+                [weakSelf createLivePageViewDisplay];
+            }
+            else {
+                [weakSelf previewBackAction];
+            }
+        }];
+    }
+}
+
+- (void)startPublishStream {
+    self.pageType = LIVEPAGE_LIVE;
+    self.isPauseLive = NO;
+    [self publishLocalStream];
+    [self countMemberCount];
+    [self.timeManager requestCousreTimeConfig];
+}
+
+- (void)publishLocalStream {
+    
+    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.trtcCloud startLocalPreview:YES view:self.liveVideoView];
+    [self.trtcCloud enterRoom:parms appScene:TRTCAppSceneLIVE];
+    [self.trtcCloud muteLocalAudio:!self.micEnable];
+    [self configVideoAndAudioSetting];
+    NSString *streamId = [NSString stringWithFormat:@"%@_%@", self.roomId, UserDefault(IM_USERID)];
+    [self.trtcCloud startPublishing:streamId type:TRTCVideoStreamTypeBig];
+    [self sendOpenLiveMessage];
+}
+
+
+- (void)extracted:(TXLiveMessageOpenLive *)openLiveMsg {
+    [self sendCustomMessage:openLiveMsg priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+        
+    }];
+}
+
+- (void)sendOpenLiveMessage {
+    if (TXIM_LINSENTER.loginIMSuccess) {
+        // 发送开播消息
+        TXLiveMessageOpenLive *openLiveMsg = [[TXLiveMessageOpenLive alloc] init];
+        openLiveMsg.userInfo = [self getCurrentUser];
+        [self extracted:openLiveMsg];
+        
+        [self syncLiveStatus:YES];
+        
+    }
+    else {
+        self.needSendOpenMsg = YES;
+    }
+}
+
+- (void)configVideoAndAudioSetting {
+    [self.trtcCloud startLocalAudio:TRTCAudioQualityMusic];
+    
+    TRTCVideoEncParam *videoEncParam = [[TRTCVideoEncParam alloc] init];
+    videoEncParam.videoFps = 15;
+    videoEncParam.resMode = TRTCVideoResolutionModePortrait;
+    videoEncParam.videoResolution = TRTCVideoResolution_960_540;
+    [self.trtcCloud setVideoEncoderParam:videoEncParam];
+}
+
+// 配置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];
+}
+
+
+- (void)setupLiveroomConfig:(NSDictionary *)source {
+    self.createrId = [source ks_stringValueForKey:@"speakerId"];
+    self.createrName = [source ks_stringValueForKey:@"speakerName"];
+    self.createrAvatal = [source ks_stringValueForKey:@"speakerPic"];
+//    self.likeCount = [source ks_integerValueForKey:@"likeNum"]; // 点赞数
+    NSInteger lookCount = [source ks_integerValueForKey:@"lookNum"];
+    self.totalCount = lookCount; // 观看人数
+    NSString *roomConfig = [source ks_stringValueForKey:@"roomConfig"];
+    NSData *jsonData = [roomConfig dataUsingEncoding:NSUTF8StringEncoding];
+    NSError *err;
+    NSDictionary *configDic = [NSJSONSerialization JSONObjectWithData:jsonData
+                                                              options:NSJSONReadingMutableContainers
+                                                                error:&err];
+    if (configDic) {
+        self.enableChat = ![configDic ks_boolValueForKey:@"whether_chat"];
+        self.enableSeat = ![configDic ks_boolValueForKey:@"whether_mic"];
+        self.enableLike = ![configDic ks_boolValueForKey:@"whether_like"];
+    }
+    self.userSig = [source ks_stringValueForKey:@"userSig"];
+    
+    NSDictionary *liveRoomConfig = [source ks_dictionaryValueForKey:@"liveRoomConfig"];
+    if (liveRoomConfig) {
+        self.pushDomain = [liveRoomConfig ks_stringValueForKey:@"pushUrl"];
+        self.pushUrlKey = [liveRoomConfig ks_stringValueForKey:@"pushSecret"];
+        self.playDomain = [liveRoomConfig ks_stringValueForKey:@"playUrl"];
+        self.liveUrlKey = [liveRoomConfig ks_stringValueForKey:@"playSecret"];
+    }
+}
+
+- (void)createLivePageViewDisplay {
+    self.micEnable = YES;
+    self.pageType = LIVEPAGE_LIVE;
+    self.isImConnected = TXIM_LINSENTER.isIMConnected;
+    [self registerNotification];
+    [self setupUI];
+    [self connectionService];
+    // 开启SEL消息定时器
+    [self startSEITimer];
+}
+
+#pragma mark ------- Live page
+
+- (void)startSEITimer {
+    if (self.SEITimer) {
+        dispatch_resume(self.SEITimer);
+    }
+}
+
+- (void)StopSEITimer {
+    if (self.SEITimer) {
+        dispatch_suspend(self.SEITimer);
+    }
+}
+- (void)registerNotification {
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMessageNotification:) name:OnReceiveTXLiveMessageNotification object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(IMConnetedCallback) name:@"TXIMConnected" object:nil];
+
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appEnterBackground) name:@"appEnterBackground" object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appBecomeActive) name:@"appBecomeActive" 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 {
+    if (self.isOtherLogin) {
+        return;
+    }
+    dispatch_main_async_safe(^{
+        if (self.hasJoinRoomSuccess) { // 如果已发送进入消息
+            // 查询是否直播间开启
+            [LiveModuleService queryRoomMessage:KS_GET roomUid:self.roomId success:^(NSDictionary * _Nonnull dic) {
+                if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+                    // 回调信息
+                    MJWeakSelf;
+                    [self notiferJoinSuccessToServiceCallback:^{
+                        [weakSelf joinChatRoomAndLiveRoom];
+                    }];
+                }
+                else {
+                    [self MBPShow:MESSAGEKEY];
+                    [self quitRoomBackPreView:NO];
+                }
+            } faliure:^(NSError * _Nonnull error) {
+                
+            }];
+        }
+        if (self.needPublishStream) {
+            [self startPublishStream];
+        }
+    });
+}
+
+- (void)joinChatRoomAndLiveRoom {
+    [[V2TIMManager sharedInstance] joinGroup:self.roomId msg:nil succ:^{
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [self delyJoinRTCRoom];
+            [self getGroupInfo];
+        });
+        
+    } fail:^(int code, NSString *desc) {
+        NSLog(@"");
+    }];
+}
+
+- (void)delyJoinRTCRoom {
+    [self resetSeatContainer];
+    [self.trtcCloud exitRoom];
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        [self publishLocalStream];
+    });
+}
+
+#pragma mark ------ enter back ground
+- (void)appEnterBackground {
+    self.isEnterBackground = YES;
+    if (self.isPauseLive == NO) { // 暂停推流
+        [self pauseLiveActionBack:NO];
+    }
+}
+
+- (void)appBecomeActive {
+    if (self.isEnterBackground && self.pageType == LIVEPAGE_LIVE && self.isOtherLogin == NO) {
+        if (TXIM_LINSENTER.isIMConnected) {
+            // 开启推流
+            [self startPublishStream];
+        }
+        else {
+            self.needPublishStream = YES;
+        }
+    }
+    self.isEnterBackground = NO;
+}
+
+- (void)setupUI {
+    CGSize size = self.view.bounds.size;
+    [self.view addSubview:self.livePageView];
+    [self.livePageView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.view);
+    }];
+    
+    [self.livePageView addSubview:self.liveVideoView];
+    [self.liveVideoView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.top.bottom.right.mas_equalTo(self.livePageView);
+    }];
+    
+    [self.livePageView addSubview:self.headView];
+    
+    CGFloat headHeight = [TXLiveRoomHeadView getViewHeight];
+    [self.headView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.mas_equalTo(self.livePageView);
+        make.height.mas_equalTo(headHeight);
+        if (@available(iOS 11.0, *)) {
+            make.top.mas_equalTo(self.livePageView.mas_safeAreaLayoutGuideTop).offset(10);
+        } else {
+            // Fallback on earlier versions
+            make.top.mas_equalTo(self.livePageView.mas_top).offset(10);
+        }
+    }];
+    [self.livePageView addSubview:self.messageContentView];
+    [self.livePageView addSubview:self.bottomView];
+    
+    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.livePageView addSubview:self.messageContentView];
+    [self.livePageView addSubview:self.bottomView];
+    
+    [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.mas_equalTo(self.livePageView);
+        if (@available(iOS 11.0, *)) {
+            make.bottom.mas_equalTo(self.livePageView.mas_safeAreaLayoutGuideBottom).offset(-5);
+        } else {
+            // Fallback on earlier versions
+            make.bottom.mas_equalTo(self.livePageView.mas_bottom).offset(-5);
+        }
+        make.height.mas_equalTo(44);
+    }];
+    
+    [self.messageContentView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(self.livePageView.mas_left);
+        make.right.mas_equalTo(self.livePageView.mas_right);
+        make.bottom.mas_equalTo(self.bottomView.mas_top).offset(-5);
+        make.height.mas_equalTo(180);
+    }];
+    [self.livePageView addSubview:self.inputBar];
+    [_inputBar setBackgroundColor: [UIColor whiteColor]];
+    
+    [_inputBar setFrame:CGRectMake(0, kScreenHeight, size.width , 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);
+    }];
+    
+    [self.livePageView addSubview:self.seatApplyTips];
+    [self.seatApplyTips hideView];
+    [self.seatApplyTips mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.bottom.mas_equalTo(self.bottomView.mas_top).offset(2);
+        make.height.mas_equalTo(20);
+        make.left.mas_equalTo(self.bottomView.mas_right).offset(-116);
+    }];
+    
+    UITapGestureRecognizer *resetBottomTapGesture =[[UITapGestureRecognizer alloc]
+                                                    initWithTarget:self
+                                                    action:@selector(resetBottomGesture:)];
+    resetBottomTapGesture.delegate = self;
+    [self.livePageView addGestureRecognizer:resetBottomTapGesture];
+}
+
+- (void)joinChatRoom {
+    if (TXIM_LINSENTER.loginIMSuccess == NO) {
+        [TXIM_LINSENTER TXIMLoginWithUserId:UserDefault(IM_USERID) sig:self.userSig callback:^(BOOL isSuccess, NSString * _Nullable msg) {
+            [self liveConversationJoin];
+            if (self.needSendOpenMsg) {
+                self.needSendOpenMsg = NO;
+                [self sendOpenLiveMessage];
+            }
+        }];
+    }
+    else {
+        [self liveConversationJoin];
+    }
+}
+
+- (void)liveConversationJoin {
+    [[V2TIMManager sharedInstance] joinGroup:self.roomId msg:nil succ:^{
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [self addConstMessage];
+            self.hasJoinRoomSuccess = YES;
+            [self getGroupInfo];
+        });
+        
+    } fail:^(int code, NSString *desc) {
+        NSLog(@"");
+    }];
+}
+
+- (void)getGroupInfo {
+    [self getGroupAttrInfo];
+    [self getGroupCount];
+}
+
+- (void)getGroupAttrInfo {
+    [[V2TIMManager sharedInstance] getGroupAttributes:self.roomId keys:nil succ:^(NSMutableDictionary<NSString *,NSString *> *groupAttributeList) {
+        [self evaluateGroupInfo:groupAttributeList];
+    } fail:^(int code, NSString *desc) {
+        
+    }];
+}
+
+- (void)getGroupCount {
+    [[V2TIMManager sharedInstance] getGroupCounters:self.roomId keys:nil succ:^(NSDictionary<NSString *,NSNumber *> *groupCounters) {
+        [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];
+    [self sendCustomMessage:welcomeMessage priority:V2TIM_PRIORITY_DEFAULT displayMessage:NO callback:^(BOOL success) {
+    }];
+}
+
+
+- (void)joinLiveRoom {
+    [self notiferJoinSuccessToServiceCallback:^{
+            
+    }];
+    [self startPublishStream];
+}
+
+
+- (void)liveroomLogOut {
+    if (self.isOtherLogin == NO) {
+        self.isOtherLogin = YES;
+        [self MBPShow:@"该账号在其他设备上登录"];
+        [self quitRoomBackPreView:NO];
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+            [[NSNotificationCenter defaultCenter] postNotificationName:@"backLoginView" object:nil];
+        });
+    }
+}
+
+- (void)liveroomQuit {
+    if (self.isOtherLogin == NO) {
+        self.isOtherLogin = YES;
+        [self quitRoomBackPreView:NO];
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+            [[NSNotificationCenter defaultCenter] postNotificationName:@"backLoginView" object:nil];
+        });
+    }
+}
+ 
+- (void)connectionService {
+    [self configLiveVideo];
+    [self joinChatRoom];
+}
+
+- (void)configLiveVideo {
+    [self.trtcCloud setAudioRoute:TRTCAudioModeSpeakerphone];
+    [self setupLocalVideoView];
+    [self joinLiveRoom];
+}
+
+
+- (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;
+}
+
+// 刷新seatView
+- (void)renderSeatView {
+    NSMutableArray *seatArray = [NSMutableArray array];
+    NSArray *remoteUserArray = [self.remoteMemberArray mutableCopy];
+    for (TXUISeatMember *member in remoteUserArray) {
+        [seatArray addObject:member];
+    }
+    if (seatArray.count) {
+        if (![self.livePageView.subviews containsObject:self.seatContainer]) {
+            [self.livePageView addSubview:self.seatContainer];
+        }
+
+        [self.seatContainer mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.livePageView);
+            make.top.mas_equalTo(self.headView.mas_bottom).offset(10);
+            make.height.mas_equalTo(80);
+        }];
+
+        [self.seatContainer refreshSeatUIWithMember:[NSMutableArray arrayWithArray:seatArray]];
+    }
+    else {
+        [self removeSeatContainer];
+    }
+}
+
+- (void)removeSeatContainer {
+    if ([self.livePageView.subviews containsObject:self.seatContainer]) {
+        [self.seatContainer removeFromSuperview];
+    }
+}
+
+// 添加本地采集预览页面
+- (void)setupLocalVideoView {
+    
+    [self.trtcCloud startLocalPreview:YES view:self.liveVideoView];
+}
+
+
+#pragma mark --- publish
+
+- (void)onStopPublishing:(int)err errMsg:(NSString *)errMsg {
+    
+}
+
+- (void)onStartPublishing:(int)err errMsg:(NSString *)errMsg {
+    
+}
+
+
+#pragma mark ----- trtc delegate
+
+- (void)sendSEIMessage {
+    if (self.isOtherLogin || self.isPauseLive) {
+        return;
+    }
+    NSMutableArray *memberArray = [self.remoteMemberArray mutableCopy];
+    NSMutableArray *seatUser = [NSMutableArray array];
+    for (TXUISeatMember *member in memberArray) {
+        NSMutableDictionary *memberDic = [NSMutableDictionary dictionary];
+        [memberDic setValue:member.userId forKey:@"userId"];
+        [memberDic setValue:@(member.muteMic) forKey:@"micStatus"];
+        [seatUser addObject:memberDic];
+    }
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:seatUser forKey:@"seatUser"];
+    [parm setValue:@"sync" forKey:@"api"];
+    BOOL isSuccess =  [self.trtcCloud sendSEIMsg:[parm mj_JSONData] repeatCount:1];
+    NSLog(@"%d",isSuccess);
+}
+
+
+// 远端主播加入房间
+- (void)onRemoteUserEnterRoom:(NSString *)userId {
+    if (![self judgeContainerRemoteUser:userId]) { // 如果不包含当前用户 添加 和刷新连麦
+        TXUISeatMember *member = [[TXUISeatMember alloc] init];
+        member.userId = userId;
+        member.muteMic = NO;
+        [self.remoteMemberArray addObject:member];
+    }
+    [self renderSeatView];
+    // 刷新连麦成员状态数据
+    if ([self judgeContainMember:userId]) {
+        // 更新状态
+        [self updateMemberStatusConnecting:userId];
+        [self refreshSeatApplyView];
+    }
+    [self mixRemoteStream];
+}
+
+// 混流操作
+- (void)mixRemoteStream {
+    TRTCTranscodingConfig *config = [[TRTCTranscodingConfig alloc] init];
+    // 设置分辨率为720 × 1280, 码率为1500kbps,帧率为20FPS
+    config.videoWidth      = 540;
+    config.videoHeight     = 960;
+    config.videoBitrate    = 1500;
+    config.videoFramerate  = 20;
+    config.videoGOP        = 2;
+    config.audioSampleRate = 48000;
+    config.audioBitrate    = 64;
+    config.audioChannels   = 2;
+    // 采用全手动模式
+    config.mode = TRTCTranscodingConfigMode_Manual;
+
+    NSMutableArray *mixUsers = [NSMutableArray new];
+    // 主播摄像头的画面位置
+    TRTCMixUser* local = [TRTCMixUser new];
+    local.userId = UserDefault(IM_USERID);
+    local.zOrder = 0;   // zOrder 为0代表主播画面位于最底层
+    local.rect   = CGRectMake(0, 0, 540, 960);
+    local.roomID = nil; // 本地用户不用填写 roomID,远程需要
+    [mixUsers addObject:local];
+    if (self.remoteMemberArray.count) {
+        NSMutableArray *userArray = [self.remoteMemberArray mutableCopy];
+        
+        for (int index = 0; index < userArray.count; index++) {
+            TXUISeatMember *member = userArray[index];
+            // 连麦者的画面位置
+            TRTCMixUser* remoteUser = [TRTCMixUser new];
+            remoteUser.userId = member.userId;
+            remoteUser.zOrder = index+1;
+            remoteUser.inputType = TRTCMixInputTypePureAudio;
+            remoteUser.rect   = CGRectMake(0, 0, 0, 0); //仅供参考
+            remoteUser.roomID = self.roomId; // 本地用户不用填写 roomID,远程需要
+            [mixUsers addObject:remoteUser];
+        }
+        config.mixUsers = mixUsers;
+        [self.trtcCloud setMixTranscodingConfig:config];
+    }
+    else {
+        [self.trtcCloud setMixTranscodingConfig:nil];
+    }
+}
+
+
+// 远端主播离开
+- (void)onRemoteUserLeaveRoom:(NSString *)userId reason:(NSInteger)reason {
+    if ([self judgeContainerRemoteUser:userId]) { // 如果包含当前用户 移除当前用和刷新连麦
+        [self removeMemberUserId:userId];
+    }
+    [self renderSeatView];
+    
+    // 刷新连麦成员数据
+    if ([self judgeContainMember:userId]) {
+        [self removeMember:userId];
+        [self refreshSeatApplyView];
+    }
+    [self mixRemoteStream];
+}
+
+
+- (void)onUserAudioAvailable:(NSString *)userId available:(BOOL)available {
+    
+    [self changeSeatMemberStatus:userId muteMic:!available];
+}
+
+- (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)onStatistics:(TRTCStatistics *)statistics {
+    BOOL isConnectedFailed = NO;
+    
+    if (statistics.upLoss == 1.0) {
+        isConnectedFailed = YES;
+    }
+    [self showNetStatus:statistics.rtt networkLost:isConnectedFailed];
+}
+
+- (void)showNetStatus:(NSInteger)rttValue networkLost:(BOOL)isFailed {
+    dispatch_main_async_safe((^{
+        if (isFailed) {
+            [self.headView.rttImage setImage:[UIImage imageNamed:@"live_networking_bad"]];
+            self.headView.msLabel.text = @"网络已断开";
+        }
+        else {
+            self.headView.msLabel.text = [NSString stringWithFormat:@"%zdms",rttValue];
+            if (rttValue < 100) {
+                [self.headView.rttImage setImage:[UIImage imageNamed:@"live_networking_good"]];
+            }
+            else if (rttValue < 200) {
+                [self.headView.rttImage setImage:[UIImage imageNamed:@"live_networking_nomal"]];
+            }
+            else {
+                [self.headView.rttImage setImage:[UIImage imageNamed:@"live_networking_bad"]];
+            }
+        }
+    }));
+}
+
+#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 {
+    NSDate *date = [NSDate date];
+    NSTimeInterval currentInterval = [date timeIntervalSince1970];
+    if (currentInterval - self.lastSendMsgTime < 1) {
+        return;
+    }
+    if (self.lastSendMsgTime == 0) {
+        self.lastSendMsgTime = currentInterval;
+    }
+    [self touristSendMessage:text];
+}
+
+- (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)syncLiveStatus:(BOOL)isOnLive {
+    
+    [LiveModuleService updateRoomStatusRequest:KS_POST pushStatus:isOnLive roomId:self.roomId success:^(NSDictionary * _Nonnull dic) {
+        
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+
+}
+
+
+- (void)exitRoomCallback:(void(^)(BOOL success))callback {
+    [self.trtcCloud stopPublishing];
+    [self.trtcCloud stopLocalPreview];
+    [self.trtcCloud exitRoom];
+    [self sendLeaveMessageCallback:^(BOOL success) {
+        callback(success);
+    }];
+}
+
+// 销毁房间
+- (void)distoryRoomCallback:(void(^)(BOOL success))callback {
+    [self.trtcCloud stopLocalPreview];
+    [self.trtcCloud exitRoom];
+    [self sendLeaveMessageCallback:^(BOOL success) {
+        callback(success);
+    }];
+}
+
+#pragma mark -- 加入直播间和退出直播间回到服务
+- (void)notiferJoinSuccessToServiceCallback:(void(^)(void))callback {
+    [LiveModuleService speakerJoinRoomRequest:KS_GET roomUid:self.roomId success:^(NSDictionary * _Nonnull dic) {
+        callback();
+    } faliure:^(NSError * _Nonnull error) {
+        callback();
+    }];
+}
+
+
+#pragma mark -- 退出直播间回掉服务
+- (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) {
+        
+    }];
+}
+
+- (void)closeRoomNotiferService {
+    [LiveModuleService roomDestroyRequest:KS_GET roomUid:self.roomId success:^(NSDictionary * _Nonnull dic) {
+        if ([dic ks_integerValueForKey:@"errCode"] == 0) {
+            NSLog(@"success");
+        }
+        else {
+            NSLog(@"----- error %@", [dic ks_stringValueForKey:@"errMsg"]);
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+}
+
+- (void)sendLeaveMessageCallback:(void(^)(BOOL success))callback {
+    TXLiveMessageLeave *leaveMessage = [[TXLiveMessageLeave alloc] init];
+    leaveMessage.userInfo = [self getCurrentUser];
+    [self sendCustomMessage:leaveMessage priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+        callback(success);
+    }];
+    
+}
+
+- (void)quitChatRoom {
+    [[V2TIMManager sharedInstance] quitGroup:self.roomId succ:^{
+        
+    } fail:^(int code, NSString *desc) {
+        
+    }];
+}
+
+
+#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_main_async_safe((^{
+            if ([message isMemberOfClass:[TXLiveMessageLike class]]) {
+                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;
+                }
+                
+                NSString *userName = [welcomeMessage.userInfo.sendUserName stringByAppendingString:@""];
+                NSString *contentMsg = [NSString stringWithFormat:@"%@ 进入直播间",userName];
+                [__blockSelf showAnimationView:YES showMessag:contentMsg];
+                
+                if ([__blockSelf judgeContainMember:welcomeMessage.userInfo.sendUserId]) {
+                    [__blockSelf removeMember:welcomeMessage.userInfo.sendUserId];
+                    [__blockSelf refreshSeatApplyView];
+                    [__blockSelf renderSeatView];
+                }
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageMemberUp class]]) {
+                TXLiveMessageMemberUp *member = (TXLiveMessageMemberUp *)message;
+                __blockSelf.totalCount = member.count;
+                [__blockSelf countMemberCount];
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageStatSync class]]) { // 数据同步 不取点赞数
+                // 暂不使用
+//                TXLiveMessageStatSync *syncStatMsg = (TXLiveMessageStatSync *)message;
+//                __blockSelf.totalCount = syncStatMsg.onlineUsers;
+//                __blockSelf.likeCount = syncStatMsg.likes;
+//                [__blockSelf countMemberCount];
+            }
+            // 用户退出消息
+            else if ([message isMemberOfClass:[TXLiveMessageLeave class]]) {
+                TXLiveMessageLeave *memberLeaveMsg = (TXLiveMessageLeave *)message;
+                if ([__blockSelf judgeContainMember:memberLeaveMsg.userInfo.sendUserId]) {
+                    [__blockSelf removeMember:memberLeaveMsg.userInfo.sendUserId];
+                    [__blockSelf refreshSeatApplyView];
+                }
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageUserQuit class]]) {
+                TXLiveMessageUserQuit *quitMsg = (TXLiveMessageUserQuit *)message;
+                if ([__blockSelf judgeContainMember:quitMsg.targetId]) {
+                    [__blockSelf removeMember:quitMsg.targetId];
+                    [__blockSelf refreshSeatApplyView];
+                }
+                return;
+            }
+            
+            // 连麦申请消息
+            else if ([message isMemberOfClass:[TXLiveMessageSeatApply class]]) {
+                
+                TXLiveMessageSeatApply *seatApplyMessage = (TXLiveMessageSeatApply *)message;
+                
+                if (seatApplyMessage.type == SEATHANDLE_APPLY) { // 观众申请 加入申请中
+                    LiveSeatMember *member = [[LiveSeatMember alloc] init];
+                    member.avatar = seatApplyMessage.audienceAvatar;
+                    member.name = seatApplyMessage.audienceName;
+                    member.userId = seatApplyMessage.audienceId;
+                    member.isConnected = NO;
+                    if (![__blockSelf judgeContainMember:member.userId]) {
+                        [__blockSelf.seatApplyArray addObject:member];
+                        [__blockSelf refreshSeatApplyView];
+                    }
+                    
+                }
+                else if (seatApplyMessage.type == SEATHANDLE_CANCELAPPLY) { // 观众取消申请 从申请中剔除
+                    if ([__blockSelf judgeContainMember:seatApplyMessage.audienceId]) {
+                        // 如果在申请中的状态
+                        BOOL connectedStatus = [__blockSelf getUserConnectStatus:seatApplyMessage.audienceId];
+                        if (connectedStatus == NO) {
+                            [__blockSelf removeMember:seatApplyMessage.audienceId];
+                            [__blockSelf refreshSeatApplyView];
+                        }
+                    }
+                }
+                return;
+                
+            }
+            // 连麦回复消息(暂不处理)
+            else if ([message isMemberOfClass:[TXLiveMessageSeatResponse class]]) {
+                
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageDownSeat class]]) { // 观众下麦,从列表中移除
+                
+                TXLiveMessageDownSeat *downSeatMessage = (TXLiveMessageDownSeat *)message;
+                if ([__blockSelf judgeContainMember:downSeatMessage.audienceId]) {
+                    [__blockSelf removeMember:downSeatMessage.audienceId];
+                    [__blockSelf refreshSeatApplyView];
+                }
+                return;
+                
+            }
+            // 禁言控制
+            else if ([message isMemberOfClass:[TXLiveMessageChatBan class]]) {
+
+            }
+            else if ([message isMemberOfClass:[TXLiveMessageBlockUser class]]) { // 禁言用户操作 (用户无法发生下麦消息)
+                TXLiveMessageBlockUser *blockMessage = (TXLiveMessageBlockUser *)message;
+                if ([__blockSelf judgeContainMember:blockMessage.userId]) {
+                    [__blockSelf removeMember:blockMessage.userId];
+                    [__blockSelf refreshSeatApplyView];
+                }
+            }
+            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:[TXLiveTextMessage class]]) {
+                TXLiveTextMessage *rushMsg = (TXLiveTextMessage *)message;
+                [__blockSelf insertMessage:rushMsg];
+            }
+            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 quitRoomBackPreView:NO];
+                });
+                return;
+            }
+            else if ([message isMemberOfClass:[TXLiveForceKickMsg class]]) { // 踢出信息
+                TXLiveForceKickMsg *changeMsg = (TXLiveForceKickMsg *)message;
+                if (changeMsg.targetIds.count == 0 || changeMsg.targetIds == nil) {
+                    [__blockSelf courseChangeTips:changeMsg];
+                }
+            }
+            else if ([message isMemberOfClass:[TXLiveCourseTimeChange class]]) {
+                [__blockSelf.timeManager requestCousreTimeConfig];
+            }
+            else if ([message isMemberOfClass:[TXMicStatusSync class]]) {
+//                TXMicStatusSync *syncMsg = (TXMicStatusSync *)message;
+//                [__blockSelf changeSeatMemberStatus:syncMsg.userId muteMic:syncMsg.muteMic];
+            }
+        }));
+    }
+}
+
+- (void)courseChangeTips:(TXLiveForceKickMsg *)msg {
+    MJWeakSelf;
+    [self exitRoomCallback:^(BOOL success) {
+        // quit 接口
+        [weakSelf quitNotiferService];
+        [weakSelf quitChatRoom];
+        [weakSelf.moreView hideView];
+    }];
+    // 退出房间
+    NSString *tipsMsg = [NSString isEmptyString:msg.reason] ? @"当前课程已调整,请退出直播间" : msg.reason;
+    self.closeAlert = [LiveRoomConfirmAlert liveroomAlertWithTitle:tipsMsg sureTitle:@"确定" inView:self.view confirm:^{
+        [weakSelf.navigationController dismissViewControllerAnimated:YES completion:nil];
+    }];
+}
+
+// 修改mic状态
+- (void)changeSeatMemberStatus:(NSString *)userId muteMic:(BOOL)muteMic {
+    // 刷新连麦成员状态数据
+    if ([self judgeContainMember:userId]) {
+        // 更新状态
+        [self updateMemberMicStatus:userId isMicMute:muteMic];
+        [self refreshSeatApplyView];
+    }
+    // 修改seat container
+    if ([self judgeContainerRemoteUser:userId]) {
+        [self updateSeatMember:userId isMute:muteMic];
+        [self renderSeatView];
+    }
+}
+
+- (void)updateSeatMember:(NSString *)userId isMute:(BOOL)isMute {
+    NSMutableArray *applyArray = [self.remoteMemberArray mutableCopy];
+    for (TXUISeatMember *obj in applyArray) {
+        if ([obj.userId isEqualToString:userId]) {
+            obj.muteMic = isMute;
+            return;
+        }
+    }
+}
+
+- (void)insertMessage:(TXLiveMessageModel *)liveMessage {
+    [self appendAndDisplayMessage:liveMessage];
+}
+
+
+- (BOOL)judgeContainMember:(NSString *)userId {
+    NSMutableArray *applyArray = [self.seatApplyArray mutableCopy];
+    for (LiveSeatMember *obj in applyArray) {
+        if ([obj.userId isEqualToString:userId]) {
+            return YES;
+        }
+    }
+    return NO;
+}
+
+- (BOOL)getUserConnectStatus:(NSString *)userId {
+    BOOL isConnected = NO;
+    NSMutableArray *applyArray = [self.seatApplyArray mutableCopy];
+    for (LiveSeatMember *member in applyArray) {
+        if ([member.userId isEqualToString:userId]) {
+            return member.isConnected;
+        }
+    }
+    return isConnected;
+}
+
+- (NSInteger)queryConnectingCount {
+    NSInteger count = 0;
+    NSMutableArray *applyArray = [self.seatApplyArray mutableCopy];
+    for (LiveSeatMember *member in applyArray) {
+        if (member.isConnected) {
+            count++;
+        }
+    }
+    return count;
+}
+
+
+- (void)removeMember:(NSString *)memberId {
+    NSMutableArray *applyArray = [self.seatApplyArray mutableCopy];
+    for (LiveSeatMember *member in applyArray) {
+        if ([member.userId isEqualToString:memberId]) {
+            [self.seatApplyArray removeObject:member];
+            return;
+        }
+    }
+}
+
+- (void)updateMemberStatusWaiting:(NSString *)userId {
+    NSMutableArray *applyArray = [self.seatApplyArray mutableCopy];
+    for (LiveSeatMember *obj in applyArray) {
+        if ([obj.userId isEqualToString:userId]) {
+            obj.isConnected = NO;
+            return;
+        }
+    }
+}
+
+- (void)updateMemberStatusConnecting:(NSString *)userId {
+    NSMutableArray *applyArray = [self.seatApplyArray mutableCopy];
+    for (LiveSeatMember *obj in applyArray) {
+        if ([obj.userId isEqualToString:userId]) {
+            obj.isConnected = YES;
+            return;
+        }
+    }
+}
+
+- (void)updateMemberMicStatus:(NSString *)userId isMicMute:(BOOL)muteMic {
+    NSMutableArray *applyArray = [self.seatApplyArray mutableCopy];
+    for (LiveSeatMember *obj in applyArray) {
+        if ([obj.userId isEqualToString:userId]) {
+            obj.isMicMute = muteMic;
+            return;
+        }
+    }
+}
+
+
+- (void)refreshSeatApplyView {
+    NSMutableArray *applyArray = [self.seatApplyArray mutableCopy];
+    if (applyArray.count) {
+        NSInteger count = 0;
+        for (LiveSeatMember *obj in applyArray) {
+            if (obj.isConnected == NO) {
+                count++;
+            }
+        }
+        if (count > 0) {
+            [self showSeatTips:count];
+        }
+        else {
+            [self hideSeatTips];
+        }
+    }
+    else {
+        [self hideSeatTips];
+    }
+    [self.seatActionView refreshSeatApplyTable:applyArray];
+}
+
+- (void)showSeatTips:(NSInteger)count {
+    NSString *countDesc = count >= 100 ? @"99+" : [NSString stringWithFormat:@"%zd",count];
+    [self.seatApplyTips configCountMessage:countDesc];
+    [self.seatApplyTips showTipsView];
+}
+
+- (void)hideSeatTips {
+    [self.seatApplyTips hideView];
+}
+
+
+#pragma mark ----- 群计数器
+// 群属性变更信息
+- (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];
+    }
+}
+
+#pragma mark ------ 群属性
+- (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 allKeys] containsObject:@"MEMBER_ONLINE"]) {
+        self.totalCount = [groupInfo ks_integerValueForKey:@"MEMBER_ONLINE"];
+        [self countMemberCount];
+    }
+    // 主播全员闭麦状态
+    if ([[groupInfo allKeys] containsObject:@"ANCHOR_MIC"]) {
+        if ([[groupInfo ks_stringValueForKey:@"ANCHOR_MIC"] isEqualToString:@"ON"]) { // 禁麦
+            self.muteRoomMic = YES;
+        }
+        else {
+            self.muteRoomMic = NO;
+        }
+    }
+    else {
+        self.muteRoomMic = NO;
+    }
+    if (self.seatActionView) {
+        self.seatActionView.isMuteMic = self.muteRoomMic;
+    }
+}
+
+#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 ----- 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 ----- live page lazying
+
+- (UIView *)livePageView {
+    if (!_livePageView) {
+        _livePageView = [[UIView alloc] init];
+        _livePageView.backgroundColor = HexRGB(0x25292e);
+    }
+    return _livePageView;
+}
+
+- (UIView *)liveVideoView {
+    if (!_liveVideoView) {
+        _liveVideoView = [[UIView alloc] init];
+        _liveVideoView.backgroundColor = [UIColor clearColor];
+    }
+    return _liveVideoView;
+}
+
+- (TXLiveRoomHeadView *)headView {
+    if (!_headView) {
+        _headView = [TXLiveRoomHeadView shareInstance];
+        MJWeakSelf;
+        [_headView liveHeaderAction:^{
+            [weakSelf switchCamera];
+        }];
+    }
+    return _headView;
+}
+
+- (void)switchCamera {
+    // 获取当前摄像头状态
+    BOOL isFrontCamera = [[self.trtcCloud getDeviceManager] isFrontCamera];
+    [[self.trtcCloud getDeviceManager] switchCamera:!isFrontCamera];
+}
+
+- (LiveRoomBottomView *)bottomView {
+    if (!_bottomView) {
+        _bottomView = [LiveRoomBottomView shareInstance];
+        if (self.isLiveCourse) {
+            [_bottomView.moreButton setImage:[UIImage imageNamed:@"liveroom_pause"] forState:UIControlStateNormal];
+        }
+        else {
+            [_bottomView.moreButton setImage:[UIImage imageNamed:@"liveroom_quit"] forState:UIControlStateNormal];
+        }
+        MJWeakSelf;
+        [_bottomView bottomClickAction:^(LIVEROOMACTION action) {
+            [weakSelf bottomViewAction:action];
+        }];
+    }
+    return _bottomView;
+}
+
+- (void)bottomViewAction:(LIVEROOMACTION)action {
+    switch (action) {
+        case LIVEROOMACTION_CHAT: // 聊天
+        {
+            [_inputBar setHidden:NO];
+            [_inputBar setInputBarStatus:KSBottomBarStatusKeyboard];
+        }
+            break;
+        case LIVEROOMACTION_SEAT: // 呼出连麦页面
+        {
+            [self displaySeatView];
+        }
+            break;
+        case LIVEROOMACTION_MORE: // 更多
+        {
+            if (self.isLiveCourse) {
+                [self pauseAction];
+            }
+            else {
+                [self showMoreView];
+            }
+        }
+            break;
+        case LIVEROOMACTION_MICACTION:
+        {
+            self.micEnable = !self.micEnable;
+            [self.trtcCloud muteLocalAudio:!self.micEnable];
+            NSString *desc = @"";
+            if (self.micEnable) {
+                desc = @"你已开启麦克风";
+            }
+            else {
+                desc = @"你已关闭麦克风";
+            }
+            [self MBPShow:desc];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)setMicEnable:(BOOL)micEnable {
+    _micEnable = micEnable;
+    self.bottomView.isMicOn = micEnable;
+}
+
+- (void)showMoreView {
+    [self.view addSubview:self.moreView];
+}
+
+- (SeatTipsView *)seatApplyTips {
+    if (!_seatApplyTips) {
+        _seatApplyTips = [[SeatTipsView alloc] init];
+    }
+    return _seatApplyTips;
+}
+
+- (void)displaySeatView {
+    [self.view addSubview:self.seatCtrlView];
+    [self refreshSeatApplyView];
+}
+
+- (void)closeRoomAction {
+    MJWeakSelf;
+    self.alertView = [LiveRoomAlertView liveroomAlertWithTitle:@"结束直播后,不可再次开启" leftButtonTitle:@"取消" rightTitle:@"结束直播" inView:self.view cancel:^{
+        
+    } confirm:^{
+        [weakSelf distoryRoomAction];
+    }];
+}
+
+
+- (void)pauseAction {
+    MJWeakSelf;
+    self.alertView = [LiveRoomAlertView liveroomAlertWithTitle:@"暂停后观众将无法看到视频画面" leftButtonTitle:@"取消" rightTitle:@"暂停直播" inView:self.view cancel:^{
+        
+    } confirm:^{
+        [weakSelf quitRoomBackPreView:YES];
+    }];
+}
+
+- (void)distoryRoomAction {
+    MJWeakSelf;
+    [self distoryRoomCallback:^(BOOL success) {
+        [weakSelf closeRoomNotiferService];
+        [weakSelf quitChatRoom];
+        [weakSelf.navigationController dismissViewControllerAnimated:YES completion:nil];
+    }];
+    
+}
+
+- (void)pauseLiveActionBack:(BOOL)backPreView {
+    self.needPublishStream = NO;
+    [self resetSeatContainer];
+    TXLiveMessagePauseLive *pauserMsg = [[TXLiveMessagePauseLive alloc] init];
+    pauserMsg.userInfo = [self getCurrentUser];
+    MJWeakSelf;
+    [self sendCustomMessage:pauserMsg priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+        if (backPreView) {
+            [weakSelf pauseLiveReset];
+        }
+        else {
+            [weakSelf pauseLive];
+        }
+    }];
+    [self syncLiveStatus:NO];
+}
+
+- (void)pauseLive {
+    [self.trtcCloud stopPublishing];
+    [self.trtcCloud exitRoom];
+}
+
+- (void)pauseLiveReset {
+    [self.moreView hideView];
+    self.isPauseLive = YES;
+    self.pageType = LIVEPAGE_PREVIEW;
+    [self.livePageView removeFromSuperview];
+    [self.trtcCloud stopPublishing];
+    [self.trtcCloud exitRoom];
+    [self configEngine];
+}
+
+- (void)resetSeatContainer {
+    self.remoteMemberArray = [NSMutableArray array];
+    [self removeSeatContainer];
+    self.seatApplyArray = [NSMutableArray array];
+    [self refreshSeatApplyView];
+}
+
+- (void)quitRoomBackPreView:(BOOL)backPreView {
+    if (backPreView) { // 暂停
+        [self pauseLiveActionBack:YES];
+    }
+    else {
+        // 未连接IM直接退出
+        if (self.pageType == LIVEPAGE_PREVIEW && self.isPauseLive == NO) {
+            [self previewBackAction];
+        }
+        else { // 如果连接了IM
+            MJWeakSelf;
+            [self exitRoomCallback:^(BOOL success) {
+                // quit 接口
+                [weakSelf quitNotiferService];
+                [weakSelf quitChatRoom];
+                [weakSelf.moreView hideView];
+                if (weakSelf.callback) {
+                    weakSelf.callback();
+                }
+                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+                    [weakSelf.navigationController dismissViewControllerAnimated:YES completion:nil];
+                });
+            }];
+        }
+    }
+}
+
+- (void)previewBackAction {
+    self.preVideoView = nil;
+    [self.trtcCloud stopLocalPreview];
+    if (self.callback) {
+        self.callback();
+    }
+    [self.navigationController dismissViewControllerAnimated:YES completion:nil];
+}
+
+- (NSMutableArray *)remoteMemberArray {
+    if (!_remoteMemberArray) {
+        _remoteMemberArray = [NSMutableArray array];
+    }
+    return _remoteMemberArray;
+}
+
+- (UIView *)messageContentView {
+    if (!_messageContentView) {
+        _messageContentView = [[UIView alloc] init];
+        [_messageContentView setBackgroundColor: [UIColor clearColor]];
+    }
+    return _messageContentView;
+}
+
+- (NSMutableArray<TXLiveMessageModel *> *)conversationDataRepository {
+    if (!_conversationDataRepository) {
+        _conversationDataRepository = [NSMutableArray array];
+    }
+    return _conversationDataRepository;
+}
+
+- (KSChatInputBarControl *)inputBar {
+    if (!_inputBar) {
+        _inputBar = [[KSChatInputBarControl alloc] initWithStatus:KSBottomBarStatusDefault];
+        [_inputBar setDelegate:self];
+    }
+    return _inputBar;
+}
+
+- (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;
+}
+
+- (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 {
+    TXControlMemberMic *ctrlMsg = [[TXControlMemberMic alloc] init];
+    ctrlMsg.userInfo = [self getCurrentUser];
+    ctrlMsg.userId = userId;
+    ctrlMsg.muteMic = muteMic;
+    [self sendCustomMessage:ctrlMsg priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+        
+    }];
+}
+
+
+- (UIView *)seatCtrlView {
+    if (!_seatCtrlView) {
+        _seatCtrlView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KPortraitWidth, KPortraitHeight)];
+        _seatCtrlView.backgroundColor = [UIColor clearColor];
+        self.gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideSeatCtrlView)];
+        self.gesture.delegate = self;
+        [_seatCtrlView addGestureRecognizer:self.gesture];
+        [_seatCtrlView addSubview:self.seatActionView];
+        UIView *headView = [[UIView alloc] initWithFrame:CGRectMake(0, KPortraitHeight - 300 - iPhoneXSafeBottomMargin - 16, KPortraitWidth, 16)];
+        headView.backgroundColor = [UIColor whiteColor];
+        [_seatCtrlView addSubview:headView];
+        if (@available(iOS 11.0, *)) {
+            headView.layer.cornerRadius = 8;
+            headView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner; // 左上圆角
+        }
+        else {
+            UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:headView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(8, 8)];
+            CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
+            maskLayer.frame = headView.bounds;
+            maskLayer.path = path.CGPath;
+            headView.layer.mask = maskLayer;
+        }
+        
+    }
+    return _seatCtrlView;
+}
+
+- (void)hideSeatCtrlView {
+    if (_seatCtrlView) {
+        [_seatCtrlView removeFromSuperview];
+    }
+}
+
+- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
+    if (gestureRecognizer == self.gesture) {
+        if ([touch.view isDescendantOfView:self.seatActionView]) {
+            return NO;
+        }
+    }
+    
+    return YES;
+}
+
+- (TXLiveSeatActionView *)seatActionView {
+    if (!_seatActionView) {
+        _seatActionView = [[TXLiveSeatActionView alloc] initWithFrame:CGRectMake(0, kScreenHeight - 300 - iPhoneXSafeBottomMargin, kScreenWidth, 300 + iPhoneXSafeBottomMargin)];
+        MJWeakSelf;
+        [_seatActionView opreationCallback:^(TXLIVESECONTROL action, LiveSeatMember * _Nonnull member) {
+            [weakSelf operationSeatApplyAction:action member:member];
+        }];
+        _seatActionView.isForbiddenApply = !self.enableSeat;
+        _seatActionView.isMuteMic = self.muteRoomMic;
+    }
+    return _seatActionView;
+}
+
+- (void)operationSeatApplyAction:(TXLIVESECONTROL)control member:(LiveSeatMember *)member {
+    switch (control) {
+        case TXLIVESECONTROL_ALLOW: // 允许连麦
+        {
+            [self sendMicStatusRequest:0];
+        }
+            break;
+        case TXLIVESECONTROL_FORBIDDEN: // 禁止连麦
+        {
+            [self sendMicStatusRequest:1];
+        }
+            break;
+        case TXLIVESECONTROL_APPROVE: // 上麦
+        {
+            if (member) {
+                // 判断连麦人数超过4人 无法点击
+                NSInteger count = [self queryConnectingCount];
+                if (count >= 4) {
+                    [self MBPShow:@"最多可连麦4人"];
+                    return;
+                }
+                TXLiveMessageSeatResponse *responseMessage = [[TXLiveMessageSeatResponse alloc] init];
+                responseMessage.type = SEATRESPONSE_TEACHERAPPROVE;
+                responseMessage.teacherId = self.createrId;
+                responseMessage.teacherName = self.createrName;
+                responseMessage.audienceId = member.userId;
+                responseMessage.audienceName = member.name;
+                responseMessage.userInfo = [self getCurrentUser];
+                MJWeakSelf;
+                [self sendCustomMessage:responseMessage priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+                    [weakSelf refreshSeatArrayRemoveMember:NO member:member];
+                }];
+                
+            }
+        }
+            break;
+        case TXLIVESECONTROL_DOWNSEAT: // 下麦
+        {
+            if (member) {
+                TXLiveMessageSeatApply *kickSeatMessage = [[TXLiveMessageSeatApply alloc] init];
+                kickSeatMessage.userInfo = [self getCurrentUser];
+                kickSeatMessage.type = SEATHANDLE_KICKSEAT;
+                kickSeatMessage.teacherId = self.createrId;
+                kickSeatMessage.teacherName = self.createrName;
+                kickSeatMessage.audienceId = member.userId;
+                kickSeatMessage.audienceName = member.name;
+                MJWeakSelf;
+                [self sendCustomMessage:kickSeatMessage priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+                    [weakSelf refreshSeatArrayRemoveMember:YES member:member];
+                }];
+            }
+        }
+            break;
+        case TXLIVESECONTROL_DOWNSEATALL: // 下麦
+        {
+            MJWeakSelf;
+            self.alertView = [LiveRoomAlertView liveroomAlertWithTitle:@"确认后所有连麦中学员都将下麦" leftButtonTitle:@"取消" rightTitle:@"确认" inView:self.view cancel:^{
+                
+            } confirm:^{
+                [weakSelf downSeatAll];
+            }];
+        }
+            break;
+        case TXLIVESECONTROL_REFUSEALL:
+        {
+            MJWeakSelf;
+            self.alertView = [LiveRoomAlertView liveroomAlertWithTitle:@"确认将正在申请连麦的学员清空?" leftButtonTitle:@"取消" rightTitle:@"确认" inView:self.view cancel:^{
+                
+            } confirm:^{
+                [weakSelf refuseAllSeatApply];
+            }];
+        }
+            break;
+        case TXLIVESECONTROL_MUTEALL:  // 全员闭麦
+        {
+            [self changeMuteMicStatus:YES];
+        }
+            break;
+        case TXLIVESECONTROL_OPNEALL:  // 全员开麦
+        {
+            [self changeMuteMicStatus:NO];
+        }
+            break;
+        case TXLIVESECONTROL_MUTESINGLE:  // 闭麦
+        {
+            TXControlMemberMic *ctrlMsg = [[TXControlMemberMic alloc] init];
+            ctrlMsg.userInfo = [self getCurrentUser];
+            ctrlMsg.userId = member.userId;
+            ctrlMsg.muteMic = YES;
+            [self sendCustomMessage:ctrlMsg priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+                
+            }];
+        }
+            break;
+        case TXLIVESECONTROL_OPENSINGLE:  // 开启
+        {
+            TXControlMemberMic *ctrlMsg = [[TXControlMemberMic alloc] init];
+            ctrlMsg.userInfo = [self getCurrentUser];
+            ctrlMsg.userId = member.userId;
+            ctrlMsg.muteMic = NO;
+            [self sendCustomMessage:ctrlMsg priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+                
+            }];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+
+
+
+
+// 全体连麦人麦克风状态
+- (void)changeMuteMicStatus:(BOOL)isMute {
+    [LiveModuleService updateRoomMicStatusRequest:KS_POST isMuteMic:isMute roomId:self.roomId success:^(NSDictionary * _Nonnull dic) {
+        
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+}
+
+// 是否允许连麦 0:是 1否
+- (void)sendMicStatusRequest:(NSInteger)whetherMic {
+    [self showhud];
+    [KSNetworkingManager liveRoomSetMicApplyEnable:KS_GET roomUid:self.roomId whetherMic:whetherMic success:^(NSDictionary * _Nonnull dic) {
+        [self removehub];
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            if (whetherMic == 0) {
+                self.seatActionView.isForbiddenApply = NO;
+                [self enableSeatAction];
+            }
+            else {
+                self.seatActionView.isForbiddenApply = YES;
+                [self forceSeatAction];
+            }
+        }
+        else {
+            [self MBPShow:MESSAGEKEY];
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        [self removehub];
+    }];
+}
+
+
+- (void)enableSeatAction {
+    
+    TXLiveMessageSeatControl *message = [[TXLiveMessageSeatControl alloc] init];
+    message.userInfo = [self getCurrentUser];
+    message.seatBan = NO;
+    [self sendCustomMessage:message priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+    }];
+}
+
+// 禁止连麦
+- (void)forceSeatAction {
+    TXLiveMessageSeatControl *message = [[TXLiveMessageSeatControl alloc] init];
+    message.userInfo = [self getCurrentUser];
+    message.seatBan = YES;
+    MJWeakSelf;
+    [self sendCustomMessage:message priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+        [weakSelf removeSeatMember:YES];
+    }];
+
+}
+
+// 全员下麦
+- (void)downSeatAll {
+    TXLiveMessageDownSeatAll *message = [[TXLiveMessageDownSeatAll alloc] init];
+    message.userInfo = [self getCurrentUser];
+    MJWeakSelf;
+    [self sendCustomMessage:message priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+        [weakSelf removeSeatMember:NO];
+    }];
+}
+
+- (void)refuseAllSeatApply {
+    TXLiveMessageRejectAllSeat *message = [[TXLiveMessageRejectAllSeat alloc] init];
+    message.userInfo = [self getCurrentUser];
+    MJWeakSelf;
+    [self sendCustomMessage:message priority:V2TIM_PRIORITY_HIGH displayMessage:NO callback:^(BOOL success) {
+        [weakSelf removeSeatMember:YES];
+    }];
+}
+
+
+- (void)removeSeatMember:(BOOL)isApply {
+    NSMutableArray *seatArray = [self.seatApplyArray mutableCopy];
+
+    if (isApply) {
+        NSMutableArray *array = [NSMutableArray array];
+        for (LiveSeatMember *member in seatArray) {
+            if (member.isConnected == YES) {
+                [array addObject:member];
+            }
+        }
+        self.seatApplyArray = [NSMutableArray arrayWithArray:array];
+    }
+    else {
+        NSMutableArray *array = [NSMutableArray array];
+        for (LiveSeatMember *member in seatArray) {
+            if (member.isConnected == NO) {
+                [array addObject:member];
+            }
+        }
+        self.seatApplyArray = [NSMutableArray arrayWithArray:array];
+    }
+    [self refreshSeatApplyView];
+}
+
+- (void)refreshSeatArrayRemoveMember:(BOOL)isRemove member:(LiveSeatMember *)member {
+    if (isRemove) {
+        [self.seatApplyArray removeObject:member];
+    }
+    else {
+        member.isConnected = YES;
+        if (![self judgeContainMember:member.userId]) {
+            [self.seatApplyArray addObject:member];
+            NSLog(@"hah--------");
+        }
+    }
+    [self refreshSeatApplyView];
+}
+
+
+- (NSMutableArray *)seatApplyArray {
+    if (!_seatApplyArray) {
+        _seatApplyArray = [NSMutableArray array];
+    }
+    return _seatApplyArray;
+}
+
+- (LiveMoreDisplayView *)moreView {
+    if (!_moreView) {
+        _moreView = [LiveMoreDisplayView shareInstance];
+        _moreView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight);
+        MJWeakSelf;
+        [_moreView operationQuitAction:^(BOOL isCloseRoom) {
+            [weakSelf leaveRoom:isCloseRoom];
+        }];
+    }
+    return _moreView;
+}
+
+- (void)leaveRoom:(BOOL)closeRoom {
+    if (closeRoom) {
+        [self closeRoomAction];
+    }
+    else {
+        [self pauseAction];
+    }
+}
+
+- (void)dealloc {
+    NSLog(@"---- live room dealloc");
+
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+    if (_SEITimer) {
+        dispatch_source_cancel(_SEITimer);
+        _SEITimer = nil;
+    }
+    if (_trtcCloud) {
+        [self.trtcCloud stopLocalAudio];
+        [self.trtcCloud stopLocalPreview];
+        [self.trtcCloud stopPublishing];
+        [self.trtcCloud exitRoom];
+        _trtcCloud = nil;
+        [TRTCCloud destroySharedIntance];
+    }
+}
+
+
+- (dispatch_source_t)SEITimer {
+    if (!_SEITimer) {
+        _SEITimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
+        uint64_t interval = (uint64_t)(2 * NSEC_PER_SEC);
+        dispatch_source_set_timer(_SEITimer, DISPATCH_TIME_NOW, interval, 0);
+//        @weakify(self);
+        dispatch_source_set_event_handler(_SEITimer, ^{
+            dispatch_async(dispatch_get_main_queue(), ^{
+//                @strongify(self);
+                [self sendSEIMessage];
+            });
+        });
+    }
+    return _SEITimer;
+}
+
+
+
+
+#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;
+}
+
+
+/**
+ *  判断消息是否在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];
+}
+
+
+- (void)showAnimationView:(BOOL)isJoinRoom showMessag:(NSString *)message {
+    if (self.animationView && self.animationView.isShow) {
+        return;
+    }
+    else {
+        if (self.pageType == LIVEPAGE_PREVIEW) {
+            return;
+        }
+        ANIMATIONTYPE type = isJoinRoom ? ANIMATIONTYPE_JOIN : ANIMATIONTYPE_RUSH;
+        self.animationView = [[LiveAnimationView alloc] initWithTitle:message animationType:type];
+        [self.view addSubview:self.animationView];
+        [self.animationView 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.animationView];
+        NSLog(@"------- start animation ");
+        MJWeakSelf;
+        [self.animationView startAnimationEndCallback:^{
+            NSLog(@"----- hide ");
+            weakSelf.animationView.isShow = YES;
+            weakSelf.animationView = nil;
+        }];
+    }
+}
+
+- (TRTCCloud *)trtcCloud {
+    if (!_trtcCloud) {
+        _trtcCloud = [TRTCCloud sharedInstance];
+        _trtcCloud.delegate = self;
+    }
+    return _trtcCloud;
+}
+
+#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;
+    }
+}
+
+- (TXLiveRoomTimeManager *)timeManager {
+    if (!_timeManager) {
+        _timeManager = [[TXLiveRoomTimeManager alloc] initWithDelegate:self];
+        _timeManager.roomId = self.roomId;
+        _timeManager.duration = self.surplusTime;
+        _timeManager.autoCloseNetworkRoomTime = self.autoCloseNetworkRoomTime;
+    }
+    return _timeManager;
+}
+
+#pragma mark ---- time manager
+- (void)formatTime:(NSString *)timeString timeType:(LIVETIMETYPE)type {
+    self.headView.timeLabel.text = timeString;
+    switch (type) {
+        case LIVETIMETYPE_NOTSTART:
+        {
+            self.headView.timeView.hidden = YES;
+        }
+            break;
+        case LIVETIMETYPE_COURSE:
+        {
+            self.headView.timeView.hidden = NO;
+            self.headView.tipsLabel.text = @"课程时长: ";
+            self.headView.timeLabel.textColor = HexRGB(0x00FFF0);
+        }
+            break;
+        case LIVETIMETYPE_REST:
+        {
+            self.headView.timeView.hidden = NO;
+            self.headView.tipsLabel.text = @"课间时间: ";
+            self.headView.timeLabel.textColor = HexRGB(0x00FFF0);
+        }
+            break;
+        case LIVETIMETYPE_CLOSECOUNT:
+        {
+            self.headView.timeView.hidden = NO;
+            self.headView.tipsLabel.text = @"直播即将关闭: ";
+            self.headView.timeLabel.textColor = HexRGB(0xFF605E);
+        }
+            break;
+        case LIVETIMETYPE_CLOSE:
+        {
+            self.headView.timeView.hidden = NO;
+            self.headView.tipsLabel.text = @"直播即将关闭:";
+            self.headView.timeLabel.textColor = HexRGB(0xFF605E);
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)timeLabelAddAnimation:(CABasicAnimation *)animation {
+    [self.headView.timeLabel.layer addAnimation:animation forKey:nil];
+}
+
+- (void)quitClassroomNotifer {
+    if (self.isLiveCourse) {
+        [self.timeManager stopDurationTimer];
+        [self MBPShow:@"直播已结束"];
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+            // 退出直播间
+            [self quitRoomBackPreView:NO];
+        });
+    }
+}
+
+
+- (void)setIsLiveCourse:(BOOL)isLiveCourse {
+    _isLiveCourse = isLiveCourse;
+    if (isLiveCourse) {
+        self.headView.timeView.hidden = NO;
+        [self configCountTimer];
+    }
+    else {
+        self.headView.timeView.hidden = YES;
+    }
+}
+
+- (void)configCountTimer {
+    self.timeManager.duration = self.surplusTime;
+}
+/*
+#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

+ 19 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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

+ 17 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveCourseTimeChange.h

@@ -0,0 +1,17 @@
+//
+//  TXLiveCourseTimeChange.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/6/14.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveCourseTimeChange : TXLiveMessageModel
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 38 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveCourseTimeChange.m

@@ -0,0 +1,38 @@
+//
+//  TXLiveCourseTimeChange.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/6/14.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveCourseTimeChange.h"
+
+@implementation TXLiveCourseTimeChange
+
+- (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:Chatroom:LiveCourseTimeChange";
+}
+
+- (NSString *)objectName {
+  return @"RC:Chatroom:LiveCourseTimeChange";
+}
+
+@end

+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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

+ 45 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageBlockUser.m

@@ -0,0 +1,45 @@
+//
+//  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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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:@"content"];
+    [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:@"content"];
+}
+
++ (NSString *)getObjectName {
+    return @"DY:LIVE_GOODS_CHANGE";
+}
+- (NSString *)objectName {
+    return @"DY:LIVE_GOODS_CHANGE";
+}
+@end

+ 33 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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

+ 37 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageClose.m

@@ -0,0 +1,37 @@
+//
+//  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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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 观众取消申请 5 主讲人断开连麦人连麦
+ */
+@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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/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

+ 50 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageStatSync.m

@@ -0,0 +1,50 @@
+//
+//  TXLiveMessageStatSync.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/3/9.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageStatSync.h"
+
+@implementation TXLiveMessageStatSync
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setObject:@(self.onlineUsers) forKey:@"onlineUsers"];
+    [content setObject:@(self.viewers) forKey:@"viewers"];
+    [content setObject:@(self.likes) forKey:@"likes"];
+    [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.onlineUsers = [content ks_integerValueForKey:@"onlineUsers"];
+    self.viewers = [content ks_integerValueForKey:@"viewers"];
+    self.likes = [content ks_integerValueForKey:@"likes"];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:StatSync";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:StatSync";
+}
+@end

+ 20 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageUnBlockUser.h

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

+ 46 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageUnBlockUser.m

@@ -0,0 +1,46 @@
+//
+//  TXLiveMessageUnBlockUser.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageUnBlockUser.h"
+
+@implementation TXLiveMessageUnBlockUser
+- (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:UNBLOCK_BLACK_USER";
+}
+
+- (NSString *)objectName {
+    return @"RC:UNBLOCK_BLACK_USER";
+}
+@end

+ 19 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageUserQuit.h

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

+ 45 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageUserQuit.m

@@ -0,0 +1,45 @@
+//
+//  TXLiveMessageUserQuit.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageUserQuit.h"
+
+@implementation TXLiveMessageUserQuit
+
+- (NSData *)encodeMessage {
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    NSMutableDictionary *content = [NSMutableDictionary dictionary];
+    [content setValue:[self.userInfo getUserInfoDic] forKey:@"sendUserInfo"];
+    [content setValue:self.targetId forKey:@"targetId"];
+    [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.targetId = [content ks_stringValueForKey:@"targetId"];
+    self.userInfo = [TXLiveUser evaluateUserInfo:[content ks_dictionaryValueForKey:@"sendUserInfo"]];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:LookerLoginOut";
+}
+
+- (NSString *)objectName {
+    return @"RC:LookerLoginOut";
+}
+
+@end

+ 17 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageWelcome.h

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

+ 42 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveMessageWelcome.m

@@ -0,0 +1,42 @@
+//
+//  TXLiveMessageWelcome.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveMessageWelcome.h"
+
+@implementation TXLiveMessageWelcome
+
+- (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:Welcome";
+}
+- (NSString *)objectName {
+    return @"RC:Chatroom:Welcome";
+}
+@end

+ 20 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveTextMessage.h

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

+ 45 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveTextMessage.m

@@ -0,0 +1,45 @@
+//
+//  TXLiveTextMessage.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/22.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveTextMessage.h"
+
+@implementation TXLiveTextMessage
+
+- (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:Text";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:Text";
+}
+@end

+ 28 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveUser.h

@@ -0,0 +1,28 @@
+//
+//  TXLiveUser.h
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveUser : NSObject
+
+/// 发送id
+@property (nonatomic, strong) NSString *sendUserId;
+// 发送者名称
+@property (nonatomic, strong) NSString *sendUserName;
+// 头像
+@property (nonatomic, strong) NSString *avatarUrl;
+
+- (NSMutableDictionary *)getUserInfoDic;
+
++ (TXLiveUser *)evaluateUserInfo:(NSDictionary *)userInfoDic;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 31 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXLiveUser.m

@@ -0,0 +1,31 @@
+//
+//  TXLiveUser.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/2/28.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveUser.h"
+
+@implementation TXLiveUser
+
++ (TXLiveUser *)evaluateUserInfo:(NSDictionary *)userInfoDic {
+    TXLiveUser *user = [[TXLiveUser alloc] init];
+    user.sendUserId = [userInfoDic ks_stringValueForKey:@"sendUserId"];
+    user.sendUserName = [userInfoDic ks_stringValueForKey:@"sendUserName"];
+    user.avatarUrl = [userInfoDic ks_stringValueForKey:@"avatarUrl"];
+    return user;
+}
+
+- (NSMutableDictionary *)getUserInfoDic {
+    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
+    [dic setValue:self.sendUserId forKey:@"sendUserId"];
+    [dic setValue:self.sendUserName forKey:@"sendUserName"];
+    [dic setValue:self.avatarUrl forKey:@"avatarUrl"];
+    return dic;
+}
+
+
+
+@end

+ 21 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXMicStatusSync.h

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

+ 49 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Message/TXMicStatusSync.m

@@ -0,0 +1,49 @@
+//
+//  TXMicStatusSync.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/4/4.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXMicStatusSync.h"
+
+@implementation TXMicStatusSync
+
+- (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:MicSync";
+}
+
+- (NSString *)objectName {
+    return @"RC:Chatroom:MicSync";
+}
+
+@end

+ 62 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveMessageCenter.h

@@ -0,0 +1,62 @@
+//
+//  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"
+#import "TXLiveCourseTimeChange.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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/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

+ 132 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveMessageModel.m

@@ -0,0 +1,132 @@
+//
+//  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:ForcedKick"]) {
+        return @"TXLiveForceKickMsg";
+    }
+    else if (([objectName isEqualToString:@"RC:Chatroom:LiveCourseTimeChange"])) {
+        return @"TXLiveCourseTimeChange";
+    }
+    else {
+        return @"TX_MESSAGE";
+    }
+}
+@end
+

+ 50 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveRoomTimeManager.h

@@ -0,0 +1,50 @@
+//
+//  TXLiveRoomTimeManager.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/6/6.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+typedef NS_ENUM(NSInteger, LIVETIMETYPE) {
+    LIVETIMETYPE_NOTSTART,    // 第一节课未开始
+    LIVETIMETYPE_COURSE,      // 当前时间
+    LIVETIMETYPE_REST,        // 休息时间
+    LIVETIMETYPE_CLOSECOUNT,  // 结束倒计时
+    LIVETIMETYPE_CLOSE,       // 关闭时间
+};
+
+@protocol TXLiveRoomTimeManagerDelegate <NSObject>
+
+- (void)formatTime:(NSString *_Nonnull)timeString timeType:(LIVETIMETYPE)type;
+
+- (void)timeLabelAddAnimation:(CABasicAnimation *_Nonnull)animation;
+
+- (void)quitClassroomNotifer;
+
+@end
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TXLiveRoomTimeManager : NSObject
+
+@property (nonatomic, strong) NSString *roomId;
+
+@property (nonatomic, assign) NSInteger duration;
+
+@property (nonatomic, assign) NSInteger autoCloseNetworkRoomTime;
+
+@property (nonatomic, assign) BOOL showCloseTips;
+
+- (instancetype)initWithDelegate:(id <TXLiveRoomTimeManagerDelegate>)delegate;
+
+- (void)stopDurationTimer;
+
+// 获取直播间时间信息
+- (void)requestCousreTimeConfig;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 291 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Model/TXLiveRoomTimeManager.m

@@ -0,0 +1,291 @@
+//
+//  TXLiveRoomTimeManager.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/6/6.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "TXLiveRoomTimeManager.h"
+#import "LiveModuleService.h"
+
+@interface CourseTimeModel : NSObject
+
+// 开始时间
+@property (nonatomic, assign) NSUInteger startTime;
+// 结束时间
+@property (nonatomic, assign) NSUInteger endTime;
+
+@end
+
+@implementation CourseTimeModel
+
+
+@end
+
+
+
+@interface TXLiveRoomTimeManager ()
+
+@property (nonatomic, strong) NSTimer *timeTimer;
+
+@property (nonatomic, assign) BOOL isCountDown;
+
+@property (nonatomic, weak) id <TXLiveRoomTimeManagerDelegate>delegate;
+
+@property (nonatomic, assign) BOOL autoCloseFlag;
+
+@property (nonatomic, strong) NSMutableArray *courseTimesArray;
+
+// 当前时间戳
+@property (nonatomic, assign) NSUInteger timestamp;
+
+// 当前课程时间
+@property (nonatomic, assign) NSInteger currentCourseIndex;
+
+// 计时时间类型
+@property (nonatomic, assign) LIVETIMETYPE type;
+
+@end
+
+@implementation TXLiveRoomTimeManager
+
+
+- (instancetype)initWithDelegate:(id<TXLiveRoomTimeManagerDelegate>)delegate {
+    self = [super init];
+    if (self) {
+        self.isCountDown = NO;
+        self.showCloseTips = NO;
+        self.delegate = delegate;
+    }
+    return self;
+}
+
+- (void)resetTimer {
+    [self stopDurationTimer];
+    self.currentCourseIndex = -1;
+    self.type = LIVETIMETYPE_NOTSTART;
+    self.courseTimesArray = [NSMutableArray array];
+}
+
+- (void)requestCousreTimeConfig {
+    [self resetTimer];
+    [LiveModuleService liveCourseScheduleTimeRequest:KS_GET roomUid:self.roomId success:^(NSDictionary * _Nonnull dic) {
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            NSDictionary *result = [dic ks_dictionaryValueForKey:@"data"];
+            self.autoCloseFlag = [result ks_boolValueForKey:@"autoCloseFlag"];
+            self.autoCloseNetworkRoomTime = [result ks_integerValueForKey:@"autoCloseNetworkRoomTime"];
+            self.timestamp = [result ks_longlongValueForKey:@"timestamp"];
+            NSArray *listArray = [result ks_arrayValueForKey:@"courseScheduleTimes"];
+            for (NSDictionary *parm in listArray) {
+                CourseTimeModel *model = [[CourseTimeModel alloc] init];
+                model.startTime = [parm ks_longlongValueForKey:@"startTime"];
+                model.endTime = [parm ks_longlongValueForKey:@"endTime"];
+                [self.courseTimesArray addObject:model];
+            }
+        }
+        else {
+            
+        }
+        [self startTimer];
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+}
+
+
+- (void)countTime {
+    for (NSInteger index = 0 ; index < self.courseTimesArray.count; index++) {
+        CourseTimeModel *model = self.courseTimesArray[index];
+        // 如果在课程时间中间 (倒计时)
+        if (model.startTime <= self.timestamp && model.endTime > self.timestamp) {
+            self.type = LIVETIMETYPE_COURSE;
+            self.currentCourseIndex = index;
+            self.duration = (model.endTime - self.timestamp) / 1000;
+            break;
+        }
+        // 延迟关闭时间
+        else if (index == self.courseTimesArray.count - 1 && self.timestamp > model.endTime) {
+            if (self.timestamp > model.endTime + self.autoCloseNetworkRoomTime * 60 * 1000) {
+                self.currentCourseIndex = index;
+                self.duration = 0;
+                self.type = LIVETIMETYPE_CLOSE;
+            }
+            else {
+                self.currentCourseIndex = index;
+                self.duration = ((model.endTime + self.autoCloseNetworkRoomTime * 60 * 1000) - self.timestamp) / 1000;
+                self.type = LIVETIMETYPE_CLOSECOUNT;
+            }
+            
+            break;
+        }
+        else if (index == 0 && self.timestamp < model.startTime) {
+            self.currentCourseIndex = -1;
+            self.duration = (model.startTime - self.timestamp) / 1000;
+            self.type = LIVETIMETYPE_NOTSTART;
+            break;
+        }
+        else if (index < self.courseTimesArray.count - 1) {
+            CourseTimeModel *nextModel = self.courseTimesArray[index+1];
+            if (model.endTime < self.timestamp && nextModel.startTime > self.timestamp) {
+                self.currentCourseIndex = index;
+                self.duration = (nextModel.startTime - self.timestamp) / 1000;
+                self.type = LIVETIMETYPE_REST;
+                break;
+            }
+        }
+    }
+}
+
+
+- (void)startTimer {
+    [self countTime];
+    [self.timeTimer setFireDate:[NSDate distantPast]];
+}
+
+- (void)setDuration:(NSInteger)duration {
+    _duration = duration;
+//    if (_duration < 300 && self.type == LIVETIMETYPE_CLOSECOUNT) {
+//        if (self.delegate && [self.delegate respondsToSelector:@selector(timeLabelAddAnimation:)]) {
+//            [self.delegate timeLabelAddAnimation:[self opacityForeverAnimation:0.5f]];
+//        }
+//    }
+}
+
+- (void)timeFunction:(NSTimer *)timer {
+    if (self.delegate && [self.delegate respondsToSelector:@selector(formatTime:timeType:)]) {
+        [self.delegate formatTime:[self formatLiveTime] timeType:self.type];
+    }
+}
+
+- (void)stopDurationTimer {
+    if (_timeTimer) {
+        [self.timeTimer setFireDate:[NSDate distantFuture]];
+        if (self.timeTimer.valid) {
+            [_timeTimer invalidate];
+            _timeTimer = nil;
+        }
+    }
+}
+
+- (void)findNextCourseCount {
+    NSInteger index = self.currentCourseIndex+1;
+    if (index < self.courseTimesArray.count) {
+        CourseTimeModel *nextModel = self.courseTimesArray[index];
+        if (self.currentCourseIndex >= 0) {
+            if (nextModel.startTime > self.timestamp) {
+                self.duration = (nextModel.startTime - self.timestamp) / 1000;
+                self.type = LIVETIMETYPE_REST;
+            }
+            else {
+                self.currentCourseIndex = index;
+                self.duration = (nextModel.endTime - self.timestamp) / 1000;
+                self.type = LIVETIMETYPE_COURSE;
+            }
+            
+        }
+        else { // 第一节课
+            self.currentCourseIndex = index;
+            self.duration = (nextModel.endTime - self.timestamp) / 1000;
+            self.type = LIVETIMETYPE_COURSE;
+        }
+    }
+    else {
+        CourseTimeModel *model = self.courseTimesArray[self.currentCourseIndex];
+        if (model.endTime + self.autoCloseNetworkRoomTime * 60 * 1000 > self.timestamp) {
+            self.duration = ((model.endTime + self.autoCloseNetworkRoomTime * 60 * 1000) - self.timestamp) / 1000;
+            self.type = LIVETIMETYPE_CLOSECOUNT;
+        }
+        else {
+            self.type = LIVETIMETYPE_CLOSE;
+        }
+    }
+    [self.timeTimer setFireDate:[NSDate distantPast]];
+}
+
+- (NSString *)formatLiveTime {
+    if (self.duration < 0 && self.type == LIVETIMETYPE_CLOSE) {
+        if (self.delegate && [self.delegate respondsToSelector:@selector(quitClassroomNotifer)]) {
+            [self.delegate quitClassroomNotifer];
+        }
+        return @"00:00";
+    }
+    else if (self.duration < 0) {
+        [self.timeTimer setFireDate:[NSDate distantFuture]];
+        [self findNextCourseCount];
+        return @"00:00";
+    }
+    self.timestamp += 1000;
+    NSInteger durationInteger = self.duration--;
+    NSInteger durationS = durationInteger % 60;
+    NSInteger durationM = ((durationInteger - durationS) / 60);
+    NSMutableArray * durationArr = [NSMutableArray new];
+    [durationArr addObject:[NSString stringWithFormat:@"%02ld", (long)durationM]];
+    [durationArr addObject:[NSString stringWithFormat:@"%02ld", (long)durationS]];
+    
+    return [durationArr componentsJoinedByString:@":"];
+}
+
+- (NSString *)formatJoinTime {
+    if (self.duration <= 0 && self.showCloseTips == NO) {
+        self.duration = self.autoCloseNetworkRoomTime * 60;
+        self.showCloseTips = YES;
+        return @"00:00:00";
+    }
+    else if (self.duration <= 0 && self.showCloseTips) {
+        if (self.delegate && [self.delegate respondsToSelector:@selector(quitClassroomNotifer)]) {
+            [self.delegate quitClassroomNotifer];
+        }
+        return @"00:00:00";
+    }
+    NSInteger durationInteger = self.duration--;
+    NSInteger durationS = durationInteger % 60;
+    NSInteger durationM = ((durationInteger - durationS) / 60) % 60;
+    NSInteger durationH = (durationInteger - durationS - 60 * durationM) / 3600;
+    NSMutableArray * durationArr = [NSMutableArray new];
+    [durationArr addObject:[NSString stringWithFormat:@"%02ld", (long)durationH]];
+    [durationArr addObject:[NSString stringWithFormat:@"%02ld", (long)durationM]];
+    [durationArr addObject:[NSString stringWithFormat:@"%02ld", (long)durationS]];
+    if (self.showCloseTips) {
+        return [NSString stringWithFormat:@"%@",[durationArr componentsJoinedByString:@":"]];
+    }
+    else {
+        return [durationArr componentsJoinedByString:@":"];
+    }
+}
+
+#pragma mark === 永久闪烁的动画 ======
+- (CABasicAnimation *)opacityForeverAnimation:(CGFloat)time {
+    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
+    animation.fromValue = [NSNumber numberWithFloat:1.0f];
+    animation.toValue = [NSNumber numberWithFloat:0.0f];//这是透明度。
+    animation.autoreverses = YES;
+    animation.duration = time;
+    animation.repeatCount = MAXFLOAT;
+    animation.removedOnCompletion = NO;
+    animation.fillMode = kCAFillModeForwards;
+    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
+    return animation;
+}
+
+- (NSTimer *)timeTimer {
+    if (_timeTimer == nil) {
+        
+        _timeTimer = [NSTimer scheduledTimerWithTimeInterval:1
+                                                      target:self
+                                                    selector:@selector(timeFunction:)
+                                                    userInfo:nil
+                                                     repeats:YES];
+        [[NSRunLoop currentRunLoop] addTimer:_timeTimer forMode:NSRunLoopCommonModes];
+    }
+    
+    return _timeTimer;
+}
+
+- (NSMutableArray *)courseTimesArray {
+    if (!_courseTimesArray) {
+        _courseTimesArray = [NSMutableArray array];
+    }
+    return _courseTimesArray;
+}
+@end

+ 59 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/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
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/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 streamId;
+    }
+    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

+ 9 - 2
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Model/KSEnterLiveroomManager.h → KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Service/KSEnterLiveroomManager.h

@@ -7,8 +7,12 @@
 
 #import <Foundation/Foundation.h>
 #import "CustomNavViewController.h"
-
-typedef void(^EnterCallback)(void);
+typedef NS_ENUM(NSInteger, ENTER_CALLTYPE) {
+    ENTER_CALLTYPE_SUCCESS,
+    ENTER_CALLTYPE_FAILER,
+    ENTER_CALLTYPE_BACK,
+};
+typedef void(^EnterCallback)(ENTER_CALLTYPE type);
 
 typedef void(^RoomConfigCallback)(NSDictionary * _Nullable parm);
 
@@ -19,6 +23,9 @@ NS_ASSUME_NONNULL_BEGIN
 
 + (void)queryLiveroomConfig:(NSString *)roomId callback:(RoomConfigCallback)callback;
 
++ (void)queryLiveStatusConfig:(NSString *)roomID isLiveCourse:(BOOL)isLiveCourse liveContent:(NSString * _Nullable)liveContent inController:(CustomNavViewController *)navCtrl callback:(EnterCallback)callback;
+
++ (void)refreshClickStatus;
 
 @end
 

+ 102 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Service/KSEnterLiveroomManager.m

@@ -0,0 +1,102 @@
+//
+//  KSEnterLiveroomManager.m
+//  KulexiuForTeacher
+//
+//  Created by Kyle on 2022/3/30.
+//
+
+#import "KSEnterLiveroomManager.h"
+#import "TXLiveRoomViewController.h"
+#import "LiveModuleService.h"
+
+// 用于记录防止重复点击的进入多个直播
+static BOOL isRequestRoomMsg  = NO;
+
+@implementation KSEnterLiveroomManager
+
+
++ (void)queryLiveroomConfig:(NSString *)roomId callback:(RoomConfigCallback)callback {
+    [LiveModuleService queryRoomMessage:KS_GET roomUid:roomId success:^(NSDictionary * _Nonnull dic) {
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            callback([dic ks_dictionaryValueForKey:@"data"]);
+        }
+        else {
+            [self MBShowInWindow:MESSAGEKEY];
+            callback(nil);
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        callback(nil);
+        
+    }];
+}
+
++ (void)queryLiveStatusConfig:(NSString *)roomID isLiveCourse:(BOOL)isLiveCourse liveContent:(NSString *)liveContent inController:(CustomNavViewController *)navCtrl callback:(EnterCallback)callback {
+    if (isRequestRoomMsg == YES) {
+        return;
+    }
+    isRequestRoomMsg = YES;
+    [LiveModuleService queryRoomMessage:KS_GET roomUid:roomID success:^(NSDictionary * _Nonnull dic) {
+        isRequestRoomMsg = NO;
+        
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            NSDictionary *source = [dic ks_dictionaryValueForKey:@"data"];
+            [self enterLiveRoom:roomID liveSource:source isLiveCourse:isLiveCourse liveContent:liveContent inController:navCtrl callback:callback];
+            if (callback) {
+                callback(ENTER_CALLTYPE_SUCCESS);
+            }
+        }
+        else {
+            [self MBShowInWindow:MESSAGEKEY];
+            if (callback) {
+                callback(ENTER_CALLTYPE_FAILER);
+            }
+        }
+        
+    } faliure:^(NSError * _Nonnull error) {
+        isRequestRoomMsg = NO;
+        if (callback) {
+            callback(ENTER_CALLTYPE_FAILER);
+        }
+    }];
+    
+}
+
++ (void)enterLiveRoom:(NSString *)roomId liveSource:(NSDictionary *)source isLiveCourse:(BOOL)isLiveCourse liveContent:(NSString *)liveContent inController:(CustomNavViewController *)navCtrl callback:(EnterCallback)callback {
+    BOOL isMobileLive = [[source ks_stringValueForKey:@"os"] isEqualToString:@"mobile"] ? YES : NO;
+    
+    if (isMobileLive == NO) {
+        [self MBShowInWindow:@"当前直播非移动端直播!"];
+        return;
+    }
+    TXLiveRoomViewController *ctrl = [[TXLiveRoomViewController alloc] init];
+    ctrl.roomId = roomId;
+    ctrl.liveContent = liveContent;
+    ctrl.isLiveCourse = isLiveCourse;
+    [ctrl backRefreshCallback:^{
+        callback(ENTER_CALLTYPE_BACK);
+    }];
+    CustomNavViewController *liveNav = [[CustomNavViewController alloc] initWithRootViewController:ctrl];
+    liveNav.modalPresentationStyle = UIModalPresentationFullScreen;
+    [navCtrl presentViewController:liveNav animated:YES completion:nil];
+}
+
++ (void)MBShowInWindow:(NSString *)str {
+    [MBProgressHUD hideHUD];
+    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:[UIApplication sharedApplication].keyWindow animated:YES];
+    hud.removeFromSuperViewOnHide =YES;
+    hud.mode = MBProgressHUDModeText;
+    hud.label.text = str;
+    hud.label.numberOfLines = 0;
+    hud.minSize = CGSizeMake(132.f, 60.0f);
+    hud.label.textColor = [UIColor whiteColor];
+    hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
+    hud.bezelView.backgroundColor = [UIColor colorWithHexString:@"#000000" alpha:0.8];
+    double hiddenTime = str.length > 15 ? 3.0f : 1.5f;
+    [hud hideAnimated:YES afterDelay:hiddenTime];
+}
+
+
++ (void)refreshClickStatus {
+    isRequestRoomMsg = NO;
+}
+@end

+ 81 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Service/LiveModuleService.h

@@ -0,0 +1,81 @@
+//
+//  LiveModuleService.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2023/8/18.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveModuleService : NSObject
+
+// /api-teacher/imLiveBroadcastRoom/queryRoom
+
+/// 查询房间信息
+/// @param get get
+/// @param roomUid 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)queryRoomMessage:(NSString *)get roomUid:(NSString *)roomUid success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// 是否在直播数据同步
+// imLiveBroadcastRoom/updateRoomStatus
+
+/// 同步房间直播状态
+/// @param post post
+/// @param isOnLive 是否在直播
+/// @param roomId 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)updateRoomStatusRequest:(NSString *)post pushStatus:(BOOL)isOnLive roomId:(NSString *)roomId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+// imLiveBroadcastRoom/updateRoomStatus
+
+/// 同步房间闭麦状态
+/// @param post post
+/// @param isMuteMic 是否闭麦
+/// @param roomId 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)updateRoomMicStatusRequest:(NSString *)post isMuteMic:(BOOL)isMuteMic roomId:(NSString *)roomId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// /api-teacher/imLiveBroadcastRoom/speakerJoinRoom
+
+/// 主讲人进入直播间
+/// @param get get
+/// @param roomUid 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)speakerJoinRoomRequest:(NSString *)get roomUid:(NSString *)roomUid success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+
+// /api-teacher/imLiveBroadcastRoom/roomDestroy/{id}
+
+/// 关闭直播间
+/// @param get get
+/// @param roomUid 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)roomDestroyRequest:(NSString *)get roomUid:(NSString *)roomUid success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// 退出直播间通知
+// /api-im/user/statusImUser
+
+/// 退出直播间
+/// @param post post json
+/// @param success 成功
+/// @param faliure 失败
++ (void)LiveroomQuit:(NSString *)post success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// courseSchedule/liveCourseScheduleTime
+
+/// 查询直播课时间
+/// @param get get
+/// @param roomUid 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)liveCourseScheduleTimeRequest:(NSString *)get roomUid:(NSString *)roomUid success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+@end
+
+NS_ASSUME_NONNULL_END

+ 117 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/Service/LiveModuleService.m

@@ -0,0 +1,117 @@
+//
+//  LiveModuleService.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2023/8/18.
+//
+
+#import "LiveModuleService.h"
+
+@implementation LiveModuleService
+
+// /api-teacher/imLiveBroadcastRoom/queryRoom
+
+/// 查询房间信息
+/// @param get get
+/// @param roomUid 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)queryRoomMessage:(NSString *)get roomUid:(NSString *)roomUid success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-teacher/imLiveBroadcastRoom/queryRoom"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:roomUid forKey:@"roomUid"];
+    [parm setValue:UserDefault(UIDKey) forKey:@"userId"];
+    [KSNetworkingManager LiveRoomRequest:get url:url parms:parm success:success faliure:faliure];
+}
+
+// 是否在直播数据同步
+// imLiveBroadcastRoom/updateRoomStatus
+
+/// 同步房间直播状态
+/// @param post post
+/// @param isOnLive 是否在直播
+/// @param roomId 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)updateRoomStatusRequest:(NSString *)post pushStatus:(BOOL)isOnLive roomId:(NSString *)roomId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-teacher/imLiveBroadcastRoom/updateRoomStatus"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:@(isOnLive) forKey:@"pushStatus"];
+    [parm setValue:roomId forKey:@"roomUid"];
+    [parm setValue:@(1) forKey:@"cameraStatus"];
+    [KSNetworkingManager LiveRoomRequest:post url:url parms:parm success:success faliure:faliure];
+}
+
+// imLiveBroadcastRoom/updateRoomStatus
+
+/// 同步房间闭麦状态
+/// @param post post
+/// @param isMuteMic 是否闭麦
+/// @param roomId 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)updateRoomMicStatusRequest:(NSString *)post isMuteMic:(BOOL)isMuteMic roomId:(NSString *)roomId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-teacher/imLiveBroadcastRoom/updateRoomStatus"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:roomId forKey:@"roomUid"];
+    [parm setValue:@(isMuteMic) forKey:@"micStatus"];
+    [KSNetworkingManager LiveRoomRequest:post url:url parms:parm success:success faliure:faliure];
+}
+
+// /api-teacher/imLiveBroadcastRoom/speakerJoinRoom
+
+/// 主讲人进入直播间
+/// @param get get
+/// @param roomUid 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)speakerJoinRoomRequest:(NSString *)get roomUid:(NSString *)roomUid success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@", hostURL,@"/api-teacher/imLiveBroadcastRoom/speakerJoinRoom"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:roomUid forKey:@"roomUid"];
+    [KSNetworkingManager LiveRoomRequest:get url:url parms:parm success:success faliure:faliure];
+}
+
+// /api-teacher/imLiveBroadcastRoom/roomDestroy/{id}
+
+/// 关闭直播间
+/// @param get get
+/// @param roomUid 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)roomDestroyRequest:(NSString *)get roomUid:(NSString *)roomUid success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-teacher/imLiveBroadcastRoom/roomDestroy/"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:roomUid forKey:@"roomUid"];
+    [KSNetworkingManager LiveRoomRequest:get url:url parms:parm success:success faliure:faliure];
+}
+
+// 退出直播间通知
+// /api-im/user/statusImUser
+
+/// 退出直播间
+/// @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:@"%@%@", hostURL, @"/api-teacher/liveRoom/syncUserStatus"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:@"iOS" forKey:@"os"];
+    [parm setValue:@"3" forKey:@"status"];
+    [parm setValue:UserDefault(UIDKey) forKey:@"userid"];
+    [KSNetworkingManager LiveRoomRequest:post url:url parms:parm success:success faliure:faliure];
+}
+
+// courseSchedule/liveCourseScheduleTime
+
+/// 查询直播课时间
+/// @param get get
+/// @param roomUid 房间号
+/// @param success 成功
+/// @param faliure 失败
++ (void)liveCourseScheduleTimeRequest:(NSString *)get roomUid:(NSString *)roomUid success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@%@", hostURL, @"/api-teacher/courseSchedule/liveCourseScheduleTime?roomUid=", roomUid];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [KSNetworkingManager LiveRoomRequest:get url:url parms:parm success:success faliure:faliure];
+}
+@end

+ 0 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveMoreDisplayView.h → KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/View/LiveMoreDisplayView.h


+ 0 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveMoreDisplayView.m → KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/View/LiveMoreDisplayView.m


+ 0 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/LiveMoreDisplayView.xib → KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/View/LiveMoreDisplayView.xib


+ 25 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/TXLiveModule/View/LiveRoomConfirmAlert.h

@@ -0,0 +1,25 @@
+//
+//  LiveRoomConfirmAlert.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2023/6/6.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^LiveConfirmAlertCallback)(void);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveRoomConfirmAlert : UIView
+
+@property (nonatomic, assign) BOOL isShow;
+
++ (LiveRoomConfirmAlert *)liveroomAlertWithTitle:(NSString *)title sureTitle:(NSString *)sureTitle inView:(UIView *)displayView confirm:(LiveConfirmAlertCallback)confirm;
+
+- (void)dismissAlertView;
+
+@end
+
+NS_ASSUME_NONNULL_END

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels