TRTCChatRoom.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. using Android.Content;
  2. using Android.OS;
  3. using Com.Tencent.Trtc;
  4. using Newtonsoft.Json;
  5. using Newtonsoft.Json.Linq;
  6. using System;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. using Vinno.FIS.TRTCClient.Common.Log;
  10. using Vinno.FIS.TRTCClient.Common.Models;
  11. using static Com.Tencent.Trtc.TRTCCloudDef;
  12. namespace Vinno.FIS.TRTCClient.Android
  13. {
  14. internal class TRTCChatRoom : TRTCCloudListener
  15. {
  16. private const int JoinAndLeaveRoomTimeout = 8000;
  17. private readonly AutoResetEvent _joinRoomWiator = new AutoResetEvent(false);
  18. private readonly AutoResetEvent _leafRoomWiator = new AutoResetEvent(false);
  19. private TRTCCloud _trtcCloud;
  20. private uint _roomId;
  21. private bool _enterRoomSuccess = false;
  22. private bool _isOldServerMode;
  23. private RemoteVideoRenderListener _remoteRenderListener;
  24. private TRTCVideoFrame _videoFrame;
  25. private uint _connectRoomId;
  26. private string _connectUserId;
  27. private int _reconnectTryCount;
  28. private int _videoResolution;
  29. private string _terminalId;
  30. private string _cameraId;
  31. public event EventHandler<TRTCRemoteUserLeaveRoomMessage> RemoteUserLeaveRoomArrived;
  32. public event EventHandler TryToReconnect;
  33. /// <summary>
  34. /// Remote device video frame arrived
  35. /// </summary>
  36. public event EventHandler<TRTCVideoFrameData> RemoteVideoFrameArrived;
  37. public event EventHandler OnTRTCEnterRoomError;
  38. public TRTCChatRoom(string logPath, Context context)
  39. {
  40. TRTCCloud.SetLogCompressEnabled(false);
  41. TRTCCloud.SetLogDirPath(logPath);
  42. TRTCCloud.SetLogLevel(TrtcLogLevelError);
  43. _trtcCloud = TRTCCloud.SharedInstance(context);
  44. _remoteRenderListener = new RemoteVideoRenderListener(OnRemoteVideoFrameArrived);
  45. }
  46. /// <summary>
  47. /// enter room
  48. /// </summary>
  49. /// <param name="accountId"></param>
  50. /// <param name="isChat"></param>
  51. /// <param name="integerRoomId"></param>
  52. /// <param name="mode"></param>
  53. /// <param name="userSign"></param>
  54. public void Enter(TRTCRoomInfo roomInfo, int videoResolution)
  55. {
  56. Logger.WriteLineInfo($"RtcChatRoom {roomInfo.RoomId} Enter begin");
  57. _videoResolution = videoResolution;
  58. _terminalId = roomInfo.TerminalId;
  59. _cameraId = roomInfo.CameraId;
  60. _isOldServerMode = roomInfo.IsOldServerMode;
  61. _roomId = roomInfo.RoomId;
  62. _trtcCloud.StartLocalAudio(TrtcAudioQualityMusic);
  63. _trtcCloud.EnableCustomVideoCapture(TrtcVideoStreamTypeBig, true);
  64. _trtcCloud.EnableCustomAudioCapture(false);
  65. InitVideoParam(15, 1000, 600);
  66. var renderParams = new TRTCRenderParams
  67. {
  68. FillMode = TrtcVideoRenderModeFit,
  69. MirrorType = TrtcVideoMirrorTypeDisable
  70. };
  71. _trtcCloud.SetLocalRenderParams(renderParams);
  72. TRTCParams trtcParams = new TRTCParams
  73. {
  74. SdkAppId = (int)roomInfo.AppId,
  75. RoomId = (int)roomInfo.RoomId,
  76. UserId = roomInfo.UserId,
  77. UserSig = roomInfo.UserSig,
  78. PrivateMapKey = "",
  79. BusinessInfo = ""
  80. };
  81. _trtcCloud.SetListener(this);
  82. _trtcCloud.EnterRoom(trtcParams, TrtcAppSceneVideocall);
  83. Logger.WriteLineInfo($"RtcChatRoom JoinRoom exectuted");
  84. if (!_joinRoomWiator.WaitOne(JoinAndLeaveRoomTimeout))
  85. {
  86. Logger.WriteLineWarn("RtcChatRoom Joint Room timeout");
  87. }
  88. }
  89. internal void UpdateCameraId(string cameraId)
  90. {
  91. _cameraId = cameraId;
  92. }
  93. /// <summary>
  94. /// 发送要推流的数据
  95. /// </summary>
  96. /// <param name="width"></param>
  97. /// <param name="height"></param>
  98. /// <param name="frameBuffer"></param>
  99. public void SendData(int width, int height, byte[] frameBuffer)
  100. {
  101. var len = width * height * 3 / 2;
  102. if (_videoFrame == null)
  103. {
  104. _videoFrame = new TRTCVideoFrame
  105. {
  106. PixelFormat = TrtcVideoPixelFormatI420,
  107. BufferType = TrtcVideoBufferTypeByteArray,
  108. Width = width,
  109. Height = height,
  110. Timestamp = 0,
  111. };
  112. }
  113. _videoFrame.Data = frameBuffer;
  114. _trtcCloud?.SendCustomVideoData(TrtcVideoStreamTypeBig, _videoFrame);
  115. }
  116. private void InitVideoParam(int videoFps, int videoBitrate, int minVideoBitrate)
  117. {
  118. TRTCVideoEncParam videoEncParams = new TRTCVideoEncParam
  119. {
  120. VideoBitrate = videoBitrate,
  121. MinVideoBitrate = minVideoBitrate,
  122. VideoFps = videoFps,
  123. VideoResolution = _videoResolution,
  124. VideoResolutionMode = TrtcVideoResolutionModeLandscape,
  125. EnableAdjustRes = false
  126. };
  127. _trtcCloud.SetVideoEncoderParam(videoEncParams);
  128. var qosParams = new TRTCNetworkQosParam
  129. {
  130. Preference = TrtcVideoQosPreferenceClear,
  131. ControlMode = VideoQosControlServer,
  132. };
  133. _trtcCloud.SetNetworkQosParam(qosParams);
  134. }
  135. /// <summary>
  136. /// Exit Room
  137. /// </summary>
  138. public void Exit()
  139. {
  140. if (_trtcCloud == null)
  141. {
  142. return;
  143. }
  144. Logger.WriteLineInfo($"RtcChatRoom {_roomId} Exit begin");
  145. _trtcCloud.StopAllRemoteView();
  146. _trtcCloud.StopLocalPreview();
  147. _trtcCloud.StopLocalAudio();
  148. _trtcCloud.MuteLocalAudio(true);
  149. _trtcCloud.MuteLocalVideo(0, true);
  150. _roomId = 0;
  151. _connectRoomId = 0;
  152. _connectUserId = string.Empty;
  153. _trtcCloud.ExitRoom();
  154. if (_enterRoomSuccess && !_leafRoomWiator.WaitOne(JoinAndLeaveRoomTimeout))
  155. {
  156. Logger.WriteLineWarn("RtcChatRoom exit Room timeout");
  157. }
  158. _enterRoomSuccess = false;
  159. _trtcCloud.SetListener(null);
  160. _trtcCloud = null;
  161. TRTCCloud.DestroySharedInstance();
  162. Logger.WriteLineInfo($"RtcChatRoom {_roomId} Exit end ");
  163. }
  164. private void OnRemoteVideoFrameArrived(TRTCVideoFrameData data)
  165. {
  166. if (_isOldServerMode || (_terminalId != data.UserId && _cameraId != data.UserId))//超声机画面过滤,只拉取远端用户画面
  167. {
  168. RemoteVideoFrameArrived?.Invoke(this, data);
  169. }
  170. }
  171. public override void OnError(int errCode, string errMsg, Bundle extInfo)
  172. {
  173. Logger.WriteLineError($"{errCode},{errMsg},{extInfo}");
  174. }
  175. public override void OnWarning(int warningCode, string warningMsg, Bundle extInfo)
  176. {
  177. Logger.WriteLineWarn($"{warningCode},{warningMsg},{extInfo}");
  178. }
  179. public override void OnEnterRoom(long result)
  180. {
  181. Logger.WriteLineInfo($"onEnterRoom result: {result}");
  182. _joinRoomWiator.Set();
  183. if (result >= 0)
  184. {
  185. _enterRoomSuccess = true;
  186. }
  187. else
  188. {
  189. OnTRTCEnterRoomError?.Invoke(this, EventArgs.Empty);
  190. }
  191. }
  192. public override void OnExitRoom(int reason)
  193. {
  194. Logger.WriteLineInfo($"onExitRoom reason: {reason}");
  195. _leafRoomWiator.Set();
  196. }
  197. public override void OnConnectOtherRoom(string userId, int errCode, string errMsg)
  198. {
  199. Logger.WriteLineInfo($"onConnectOtherRoom userId :{userId}, errCode: {errCode}, errMsg: {errMsg}");
  200. if (errCode != 0 && _reconnectTryCount <= 3)
  201. {
  202. ReconnectOtherRoom("onConnectOtherRoom failed");
  203. }
  204. }
  205. public override void OnRemoteUserLeaveRoom(string userId, int reason)
  206. {
  207. Logger.WriteLineInfo($"Remote User Leave Room,userId:{userId},reason:{reason}");
  208. RemoteUserLeaveRoomArrived?.Invoke(this, new TRTCRemoteUserLeaveRoomMessage(userId, reason));
  209. }
  210. public override void OnUserVideoAvailable(string userId, bool available)
  211. {
  212. if (available)
  213. {
  214. //远程用户可用
  215. _trtcCloud.SetRemoteVideoRenderListener(userId, TrtcVideoPixelFormatRgba, TrtcVideoBufferTypeByteBuffer, _remoteRenderListener);
  216. _trtcCloud.StartRemoteView(userId, 0, null);
  217. _trtcCloud.SetRemoteRenderParams(userId, 0, new TRTCRenderParams
  218. {
  219. FillMode = TrtcVideoRenderModeFit,
  220. MirrorType = TrtcVideoMirrorTypeDisable,
  221. Rotation = TrtcVideoRotation0,
  222. });
  223. }
  224. else
  225. {
  226. //远程用户离开
  227. _trtcCloud.StopRemoteView(userId, 0);
  228. if (!string.IsNullOrEmpty(_connectUserId) && _connectUserId == userId && _reconnectTryCount <= 3)
  229. {
  230. Task.Run(() =>
  231. {
  232. ReconnectOtherRoom("onUserVideoAvailable false");
  233. });
  234. }
  235. }
  236. Logger.WriteLineInfo($"onUserVideoAvailable userId: {userId}, available: {available}");
  237. }
  238. private async void ReconnectOtherRoom(string reason)
  239. {
  240. await Task.Delay(1000);
  241. if (_enterRoomSuccess)
  242. {
  243. Logger.WriteLineInfo($"Reason:{reason},OnReconnect Other Room userId: {_connectUserId}, roomId {_connectRoomId}");
  244. ConnectRoom(_connectRoomId, _connectUserId);
  245. _reconnectTryCount++;
  246. }
  247. }
  248. public void ConnectRoom(uint roomId, string terminalId)
  249. {
  250. var jsonObj = new JObject();
  251. jsonObj["roomId"] = roomId;
  252. jsonObj["userId"] = terminalId;
  253. _connectRoomId = roomId;
  254. _connectUserId = terminalId;
  255. _reconnectTryCount = 0;
  256. var jsonData = JsonConvert.SerializeObject(jsonObj);
  257. Logger.WriteLineInfo($"TRTC ConnectRoom Room id {roomId} - terminal id: {terminalId}");
  258. _trtcCloud.ConnectOtherRoom(jsonData);
  259. }
  260. public void SwitchCamera()
  261. {
  262. }
  263. public void Mute(bool isMute)
  264. {
  265. _trtcCloud.MuteLocalAudio(isMute);
  266. }
  267. /// <summary>
  268. /// 开始渲染本地或远程用户的首帧画面
  269. /// </summary>
  270. /// <param name="userId"></param>
  271. /// <param name="streamType"></param>d
  272. /// <param name="width"></param>
  273. /// <param name="height"></param>
  274. public override void OnFirstVideoFrame(string userId, int streamType, int width, int height)
  275. {
  276. Logger.WriteLineInfo($"OnFirstVideoFrame userId: {userId},{streamType},{width},{height}");
  277. }
  278. public override void OnConnectionLost()
  279. {
  280. Logger.WriteLineInfo($"onConnectionLost");
  281. }
  282. public override void OnTryToReconnect()
  283. {
  284. Logger.WriteLineInfo($"onTryToReconnect");
  285. TryToReconnect?.Invoke(this, EventArgs.Empty);
  286. }
  287. public override void OnConnectionRecovery()
  288. {
  289. Logger.WriteLineInfo($"onConnectionRecovery");
  290. }
  291. public override void OnStartPublishing(int errCode, string errMsg)
  292. {
  293. Logger.WriteLineInfo($"onStartPublishing errCode: {errCode}, errMsg: {errMsg}");
  294. }
  295. public override void OnStopPublishing(int errCode, string errMsg)
  296. {
  297. Logger.WriteLineInfo($"onStopPublishing errCode: {errCode}, errMsg: {errMsg}");
  298. }
  299. public override void OnSwitchRoom(int errCode, string errMsg)
  300. {
  301. Logger.WriteLineInfo($"onSwitchRoom: {errCode}, errMsg: {errMsg}");
  302. }
  303. }
  304. }