rtmpmockrtcmanager.dart 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import 'package:fis_jsonrpc/rpc.dart';
  2. import 'package:fis_lib_media_rt/config.dart';
  3. import 'package:fis_lib_media_rt/implementations/nt_rtmp/models.dart';
  4. import 'package:fis_lib_media_rt/implementations/nt_rtmp/rtc_adapter.dart';
  5. import 'package:flyinsonolite/managers/basemanager.dart';
  6. import 'package:flyinsonolite/managers/interfaces/irtmpmockrtcmanager.dart';
  7. import 'package:flyinsonolite/infrastructure/storage.dart';
  8. import 'package:get/get.dart';
  9. class RtmpMockRtcManager extends BaseManager implements IRtmpMockRtcManager {
  10. List<LiveConsultationMember>? _originMembers;
  11. bool get isRtmpMode =>
  12. FRTMediaConfig.serviceType == FRealTimeMediaServiceType.ntRtmp;
  13. @override
  14. void handleRemoteAccept(LiveConsultatioAccepterInfo accepter) {
  15. if (!isRtmpMode) return;
  16. final member = _originMembers?.firstWhereOrNull((e) => e.id == accepter.id);
  17. RtmpLiveInfo? liveInfo;
  18. if (member != null) {
  19. final liveData = member.liveData!;
  20. liveInfo = RtmpLiveInfo(
  21. flvUrl: liveData.httpPullUrl!,
  22. rtmpUrl: liveData.rtmpPullUrl!,
  23. height: liveData.height,
  24. width: liveData.width,
  25. );
  26. }
  27. final data = RtmpMemberInfo(
  28. id: accepter.id!,
  29. liveInfo: liveInfo,
  30. deviceInfoList: null,
  31. );
  32. NTRtmp2RtcAdapter.adapter.remoteMemberJoineEvent.emit(this, data);
  33. }
  34. @override
  35. void handleRemoteJoinIn(LiveConsultationJoinerInfo joiner) {
  36. if (isRtmpMode) {
  37. final liveData = joiner.liveData!;
  38. final data = RtmpMemberInfo(
  39. id: joiner.id!,
  40. liveInfo: RtmpLiveInfo(
  41. flvUrl: liveData.httpPullUrl!,
  42. rtmpUrl: liveData.rtmpPullUrl!,
  43. height: liveData.height,
  44. width: liveData.width,
  45. ),
  46. deviceInfoList: null,
  47. );
  48. _emitMemberJoin(data);
  49. }
  50. }
  51. @override
  52. void handleRemoteLeave(LiveConsultationLeaverInfo joiner) {
  53. if (isRtmpMode) {
  54. final id = joiner.id!;
  55. NTRtmp2RtcAdapter.adapter.remoteMemberLeaveEvent.emit(this, id);
  56. }
  57. }
  58. @override
  59. void storeOriginData(List<LiveConsultationMember>? members) {
  60. if (!isRtmpMode) return;
  61. if (members == null || members.isEmpty) return;
  62. _originMembers = List.from(members);
  63. final localIndex =
  64. _originMembers!.indexWhere((e) => e.id == Storage.user.userCode);
  65. if (localIndex < 0) return;
  66. // 本地成员
  67. final member = _originMembers![localIndex];
  68. _originMembers!.removeAt(localIndex);
  69. final liveData = member.liveData!;
  70. NTRtmp2RtcAdapter.adapter.localMemberInfo = RtmpMemberInfo(
  71. id: member.id!,
  72. liveInfo: RtmpLiveInfo(
  73. pushUrl: liveData.rtmpPushUrl,
  74. flvUrl: '',
  75. rtmpUrl: '',
  76. height: 0,
  77. width: 0,
  78. ),
  79. );
  80. }
  81. @override
  82. void updateDevice(LiveConsultationMember device) {
  83. if (!isRtmpMode) return;
  84. _handleDeviceLeave();
  85. /// 将设备更新为新设备
  86. final deviceIndex = _originMembers!
  87. .indexWhere((e) => e.memberType == LiveMemberEnum.Device);
  88. if (deviceIndex >= 0) {
  89. _originMembers![deviceIndex] = device;
  90. }
  91. _handleDeviceJoin(device);
  92. }
  93. @override
  94. void handleEnterRoom() {
  95. if (!isRtmpMode) return;
  96. final members = _originMembers;
  97. if (members == null || members.isEmpty) return;
  98. final userMembers =
  99. members.where((e) => e.memberType == LiveMemberEnum.User);
  100. for (final member in userMembers) {
  101. _emitExistRemoteJoin(member);
  102. }
  103. // 设备成员
  104. final deviceMember =
  105. members.firstWhereOrNull((e) => e.memberType == LiveMemberEnum.Device);
  106. if (deviceMember != null) {
  107. _handleDeviceJoin(deviceMember);
  108. }
  109. }
  110. @override
  111. void handleRemoteMuteVideo(String id, bool isMute) {
  112. NTRtmp2RtcAdapter.adapter.mmberMuteVideoEvent.emit(
  113. this,
  114. RtmpSetMuteEventArgs(userId: id, isMute: isMute),
  115. );
  116. }
  117. @override
  118. void handleRemoteMuteAudio(String id, bool isMute) {
  119. NTRtmp2RtcAdapter.adapter.mmberMuteAudioEvent.emit(
  120. this,
  121. RtmpSetMuteEventArgs(userId: id, isMute: isMute),
  122. );
  123. }
  124. void _emitExistRemoteJoin(LiveConsultationMember member) {
  125. final liveData = member.liveData!;
  126. final data = RtmpMemberInfo(
  127. id: member.id!,
  128. liveInfo: RtmpLiveInfo(
  129. rtmpUrl: liveData.rtmpPullUrl!,
  130. flvUrl: liveData.httpPullUrl!,
  131. height: liveData.height,
  132. width: liveData.width,
  133. ),
  134. deviceInfoList: null,
  135. );
  136. _emitMemberJoin(data);
  137. }
  138. void _handleDeviceJoin(LiveConsultationMember member) {
  139. if (member.videoDeviceInfos == null || member.videoDeviceInfos!.isEmpty) {
  140. return;
  141. }
  142. // 如果只有一个设备
  143. if (member.videoDeviceInfos!.length == 1) {
  144. final device = member.videoDeviceInfos!.first;
  145. final data = RtmpMemberInfo(
  146. id: device.videoDeviceId!, // 进入WebRTC时的用户名
  147. deviceInfoList: [_convertDeviceLiveInfo(member, device)],
  148. );
  149. _emitMemberJoin(data);
  150. } else {
  151. // 如果有多个设备,先找出主画面,再过滤出摄像头数组
  152. final mainview = member.videoDeviceInfos!.first;
  153. final subViewList = member.videoDeviceInfos!
  154. .where((e) =>
  155. e.videoDeviceSourceType == VideoDeviceSourceTypeEnum.Camera)
  156. .toList();
  157. final mainViewData = RtmpMemberInfo(
  158. id: mainview.videoDeviceId!, // 进入WebRTC时的用户名
  159. deviceInfoList:
  160. _convertDeviceLiveInfoList(member, member.videoDeviceInfos!),
  161. );
  162. _emitMemberJoin(mainViewData);
  163. for (var device in subViewList) {
  164. // 一个设备一个成员,设备成员↔设备Channel一对一
  165. final data = RtmpMemberInfo(
  166. id: device.videoDeviceId!, // 进入WebRTC时的用户名
  167. deviceInfoList: [_convertDeviceLiveInfo(member, device)],
  168. );
  169. _emitMemberJoin(data);
  170. }
  171. }
  172. }
  173. void _handleDeviceLeave() {
  174. /// 将当前存在的设备都退出房间
  175. final deviceIndex = _originMembers!
  176. .indexWhere((e) => e.memberType == LiveMemberEnum.Device);
  177. if (deviceIndex < 0) return;
  178. final member = _originMembers![deviceIndex];
  179. for (VideoDeviceOutputInfo device in member.videoDeviceInfos!) {
  180. NTRtmp2RtcAdapter.adapter.remoteMemberLeaveEvent
  181. .emit(this, device.videoDeviceId!);
  182. }
  183. }
  184. void _emitMemberJoin(RtmpMemberInfo member) {
  185. NTRtmp2RtcAdapter.adapter.remoteMemberJoineEvent.emit(this, member);
  186. Future.delayed(const Duration(milliseconds: 100), () {
  187. handleRemoteMuteVideo(member.id, true);
  188. handleRemoteMuteAudio(member.id, true);
  189. });
  190. }
  191. DeviceRtmpLiveInfo _convertDeviceLiveInfo(
  192. LiveConsultationMember member,
  193. VideoDeviceOutputInfo device,
  194. ) {
  195. return DeviceRtmpLiveInfo(
  196. type: DeviceTypeEnum.values[device.videoDeviceSourceType.index],
  197. rtmpUrl: device.liveData!.rtmpPullUrl!,
  198. flvUrl: device.liveData!.httpPullUrl!,
  199. height: device.outputHeight,
  200. width: device.outputWidth,
  201. isMerge: member.mergedChannel,
  202. isOldPlatform: member.isOldPlatform,
  203. mergeWidth: member.mergedVideoOutputWidth,
  204. mergeHeight: member.mergedVideoOutputHeight,
  205. );
  206. }
  207. List<DeviceRtmpLiveInfo> _convertDeviceLiveInfoList(
  208. LiveConsultationMember member,
  209. List<VideoDeviceOutputInfo> devices,
  210. ) {
  211. return devices.map((e) => _convertDeviceLiveInfo(member, e)).toList();
  212. }
  213. }