TRTCLivePusher.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. using Android.Content;
  2. using Android.OS;
  3. using Com.Tencent.Trtc;
  4. using System;
  5. using System.Runtime.InteropServices;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using Vinno.FIS.TRTCClient.Common.Log;
  9. using static Com.Tencent.Trtc.TRTCCloudDef;
  10. namespace Vinno.vCloud.FIS.CrossPlatform.Android.LiveVideo.RTC
  11. {
  12. public class TRTCLivePusher : TRTCCloudListener, IDisposable
  13. {
  14. private readonly ManualResetEvent _exitResetEvent = new ManualResetEvent(false);
  15. private TRTCCloud _tRtcCloud;
  16. private TRTCVideoFrame _videoFrame;
  17. private byte[] _tempData;
  18. private int _videoResolution;
  19. public event EventHandler FirstFrameSend;
  20. public TRTCLivePusher(string logPath, Context context)
  21. {
  22. TRTCCloud.SetLogCompressEnabled(false);
  23. TRTCCloud.SetLogDirPath(logPath);
  24. TRTCCloud.SetLogLevel(TrtcLogLevelError);
  25. _tRtcCloud = TRTCCloud.SharedInstance(context);
  26. }
  27. /// <summary>
  28. /// 进入房间
  29. /// </summary>
  30. /// <param name="userId"></param>
  31. /// <param name="roomId"></param>
  32. /// <param name="userSign"></param>
  33. /// <param name="appid"></param>
  34. /// <param name="width"></param>
  35. /// <param name="height"></param>
  36. /// <param name="fps"></param>
  37. public void EnterRoom(string userId, int roomId, string userSign, int appid, int videoResolution, int videoFps, int videoBitrate, int minVideoBitrate, bool isMute, string micId)
  38. {
  39. Logger.WriteLineInfo($"Enter Room,UserId:{userId},RoomId:{roomId}");
  40. _videoResolution = videoResolution;
  41. _tRtcCloud.MuteAllRemoteVideoStreams(true);
  42. _tRtcCloud.SetDefaultStreamRecvMode(false, false);
  43. _tRtcCloud.MuteAllRemoteAudio(true);
  44. _tRtcCloud.StartLocalAudio(TrtcAudioQualityMusic);//开启本地音频的采集和上行
  45. _tRtcCloud.EnableCustomVideoCapture(TrtcVideoStreamTypeBig, true);
  46. _tRtcCloud.EnableCustomAudioCapture(false);
  47. _tRtcCloud.SetVideoEncoderMirror(false);
  48. InitVideoParam(videoFps, videoBitrate, minVideoBitrate);
  49. var renderParams = new TRTCRenderParams
  50. {
  51. FillMode = TrtcVideoRenderModeFit,
  52. MirrorType = TrtcVideoMirrorTypeDisable
  53. };
  54. _tRtcCloud.SetLocalRenderParams(renderParams);
  55. TRTCParams trtcParams = new TRTCParams
  56. {
  57. SdkAppId = appid,
  58. RoomId = roomId,
  59. UserId = userId,
  60. UserSig = userSign,
  61. Role = TRTCRoleAnchor
  62. };
  63. _tRtcCloud.SetListener(this);
  64. _tRtcCloud.MuteLocalAudio(isMute);
  65. _tRtcCloud.EnterRoom(trtcParams, TrtcAppSceneLive);
  66. }
  67. public void SetMute(bool isMute)
  68. {
  69. if (_tRtcCloud != null)
  70. {
  71. _tRtcCloud.MuteLocalAudio(isMute);
  72. }
  73. }
  74. public void SwitchMic(string micId)
  75. {
  76. }
  77. /// <summary>
  78. /// 离开房间
  79. /// </summary>
  80. public void ExitRoom()
  81. {
  82. if (_tRtcCloud != null)
  83. {
  84. Logger.WriteLineInfo($"Exit room");
  85. _tRtcCloud.StopAllRemoteView();
  86. _tRtcCloud.StopLocalPreview();
  87. _tRtcCloud.StopLocalAudio();
  88. _tRtcCloud.MuteLocalAudio(true);
  89. _tRtcCloud.MuteLocalVideo(0, true);
  90. _exitResetEvent.Reset();
  91. _tRtcCloud.ExitRoom();
  92. _exitResetEvent.WaitOne(5000);
  93. _tRtcCloud.SetListener(null);
  94. _tRtcCloud = null;
  95. }
  96. }
  97. /// <summary>
  98. /// 发送要推流的数据
  99. /// </summary>
  100. /// <param name="width"></param>
  101. /// <param name="height"></param>
  102. /// <param name="frameBuffer"></param>
  103. public void SendData(int width, int height, IntPtr frameBuffer)
  104. {
  105. var len = width * height * 3 / 2;
  106. if (_videoFrame == null)
  107. {
  108. _videoFrame = new TRTCVideoFrame
  109. {
  110. PixelFormat = TrtcVideoPixelFormatI420,
  111. BufferType = TrtcVideoBufferTypeByteArray,
  112. Width = width,
  113. Height = height,
  114. Timestamp = 0
  115. };
  116. }
  117. if (_tempData == null)
  118. {
  119. _tempData = new byte[len];
  120. }
  121. else if (_tempData.Length != len)
  122. {
  123. Array.Resize(ref _tempData, len);
  124. }
  125. Marshal.Copy(frameBuffer, _tempData, 0, len);
  126. _videoFrame.Data = _tempData;
  127. _tRtcCloud?.SendCustomVideoData(TrtcVideoStreamTypeBig, _videoFrame);
  128. }
  129. /// <summary>
  130. /// 发送要推流的数据
  131. /// </summary>
  132. /// <param name="width"></param>
  133. /// <param name="height"></param>
  134. /// <param name="frameBuffer"></param>
  135. public void SendData(int width, int height, byte[] frameBuffer)
  136. {
  137. var len = width * height * 3 / 2;
  138. if (_videoFrame == null)
  139. {
  140. _videoFrame = new TRTCVideoFrame
  141. {
  142. PixelFormat = TrtcVideoPixelFormatI420,
  143. BufferType = TrtcVideoBufferTypeByteArray,
  144. Width = width,
  145. Height = height,
  146. Timestamp = 0,
  147. };
  148. }
  149. _videoFrame.Data = frameBuffer;
  150. _tRtcCloud?.SendCustomVideoData(TrtcVideoStreamTypeBig, _videoFrame);
  151. }
  152. private void InitVideoParam(int videoFps, int videoBitrate, int minVideoBitrate)
  153. {
  154. TRTCVideoEncParam videoEncParams = new TRTCVideoEncParam
  155. {
  156. VideoBitrate = videoBitrate,
  157. MinVideoBitrate = minVideoBitrate,
  158. VideoFps = videoFps,
  159. VideoResolution = _videoResolution,
  160. VideoResolutionMode = TrtcVideoResolutionModeLandscape,
  161. EnableAdjustRes = false
  162. };
  163. _tRtcCloud.SetVideoEncoderParam(videoEncParams);
  164. var qosParams = new TRTCNetworkQosParam
  165. {
  166. Preference = TrtcVideoQosPreferenceClear,
  167. ControlMode = VideoQosControlServer,
  168. };
  169. _tRtcCloud.SetNetworkQosParam(qosParams);
  170. }
  171. #region 回调
  172. public override void OnError(int errCode, string errMsg, Bundle extInfo)
  173. {
  174. Logger.WriteLineError(string.Format("RtcPusher: Tecent errCode : {0}, errMsg : {1}, ExtInfo = {2}", errCode, errMsg, extInfo));
  175. }
  176. public override void OnWarning(int warningCode, string warningMsg, Bundle extInfo)
  177. {
  178. if (warningCode == 1208)
  179. {
  180. return;
  181. }
  182. Logger.WriteLineWarn(string.Format("RtcPusher: Tecent warningCode : {0}, warningMsg : {1}, ExtInfo = {2}", warningCode, warningMsg, extInfo));
  183. }
  184. public override void OnSendFirstLocalVideoFrame(int p0)
  185. {
  186. Logger.WriteLineInfo($"onSendFirstLocalVideoFrame successed{p0}");
  187. Task.Run(() =>//Felix:如果不用Task,容易Crash,会SIGSEGV Error
  188. {
  189. FirstFrameSend?.Invoke(null, EventArgs.Empty);
  190. });
  191. }
  192. public override void OnEnterRoom(long result)
  193. {
  194. if (result > 0)
  195. {
  196. Logger.WriteLineInfo($"Enter Room Success!:{result}");
  197. }
  198. else
  199. {
  200. Logger.WriteLineInfo($"Enter Room Fail!:{result}");
  201. }
  202. }
  203. public override void OnExitRoom(int reason)
  204. {
  205. Logger.WriteLineInfo($"Exit Room Success,{reason}");
  206. _exitResetEvent.Set();
  207. }
  208. public override void OnConnectionLost()
  209. {
  210. Logger.WriteLineWarn("RtcPusher Tx connection lost");
  211. }
  212. public override void OnTryToReconnect()
  213. {
  214. Logger.WriteLineWarn("RtcPusher Tx try to reconnect");
  215. }
  216. public override void OnConnectionRecovery()
  217. {
  218. Logger.WriteLineWarn("RtcPusher Tx connection recovery");
  219. }
  220. public override void OnConnectOtherRoom(string userId, int errCode, string errMsg)
  221. {
  222. Logger.WriteLineInfo($"onConnectOtherRoom userId :{userId}, errCode: {errCode}, errMsg: {errMsg}");
  223. }
  224. public override void OnFirstVideoFrame(string p0, int p1, int p2, int p3)
  225. {
  226. }
  227. public override void OnSpeedTestResult(TRTCSpeedTestResult currentResult)
  228. {
  229. }
  230. #endregion 回调
  231. }
  232. }