123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- using ManageLiteAV;
- using System;
- using System.IO;
- using System.Threading;
- using Vinno.FIS.TRTCClient.Common.Enum;
- using Vinno.FIS.TRTCClient.Common.Log;
- using Vinno.FIS.TRTCClient.Common.Models;
- namespace Vinno.FIS.TRTCClient
- {
- internal class TRTCLivePusher : ITRTCCloudCallback, IDisposable
- {
- private readonly ManualResetEvent _exitResetEvent = new ManualResetEvent(false);
- private ITRTCCloud _cloud;
- private ITXDeviceManager _deviceManager;
- private TRTCVideoFrame _videoFrame;
- public EventHandler<bool> SendFirstLocalVideoFrame;
- public TRTCLivePusher(string path, EnumLiveChannelCategory category)
- {
- _cloud = ITRTCCloud.getTRTCShareInstance();
- _deviceManager = _cloud.getDeviceManager();
- var logPath = Path.Combine(path, category.ToString());
- if (!Directory.Exists(logPath))
- {
- Directory.CreateDirectory(logPath);
- }
- _cloud.setLogCompressEnabled(false);
- _cloud.setLogLevel(TRTCLogLevel.TRTCLogLevelError);
- _cloud.setLogDirPath(logPath);
- _cloud.addCallback(this);
- _cloud.setLocalVideoRenderCallback(TRTCVideoPixelFormat.TRTCVideoPixelFormat_BGRA32, TRTCVideoBufferType.TRTCVideoBufferType_Buffer, null);
- }
- public void EnterRoom(TRTCRoomInfo roomInfo)
- {
- TRTCParams trtcParams = new TRTCParams
- {
- sdkAppId = roomInfo.AppId,
- roomId = roomInfo.RoomId,
- userId = roomInfo.UserId,
- userSig = roomInfo.UserSig,
- // 如果您有进房权限保护的需求,则参考文档{https://cloud.tencent.com/document/product/647/32240}完成该功能。
- // 在有权限进房的用户中的下面字段中添加在服务器获取到的privateMapKey。
- privateMapKey = "",
- businessInfo = "",
- role = TRTCRoleType.TRTCRoleAnchor
- };
- var resolution = GetResolution(roomInfo.OutputWidth, roomInfo.OutputHeight);
- InitVideoParam(resolution, roomInfo.VideoFps, roomInfo.VideoBitrate, roomInfo.MinVideoBitrate);
- _cloud.setDefaultStreamRecvMode(false, false);
- _cloud.setVideoEncoderMirror(false);
- var correctMicId = GetCorrectId(HardwareType.Mic, roomInfo.MicDeviceId);
- if (!string.IsNullOrEmpty(correctMicId))
- {
- _deviceManager.setCurrentDevice(TXMediaDeviceType.TXMediaDeviceTypeMic, correctMicId);
- _cloud.startLocalAudio(TRTCAudioQuality.TRTCAudioQualityDefault);//开启本地音频的采集和上行
- }
- _cloud.muteLocalAudio(roomInfo.IsMute);
- _cloud.muteAllRemoteAudio(true);
- _cloud.muteAllRemoteVideoStreams(true);
- _cloud.enableCustomVideoCapture(TRTCVideoStreamType.TRTCVideoStreamTypeBig, true);
- _cloud.enterRoom(ref trtcParams, TRTCAppScene.TRTCAppSceneLIVE);
- }
- internal void AdjustMicVolume(int value)
- {
- _cloud?.setAudioCaptureVolume(value);
- }
- /// <summary>
- /// 发送要推流的数据
- /// </summary>
- /// <param name="width"></param>
- /// <param name="height"></param>
- /// <param name="frameBuffer"></param>
- public void SendData(uint width, uint height, byte[] frameBuffer)
- {
- try
- {
- var len = width * height * 3 / 2;
- if (_videoFrame == null)
- {
- _videoFrame = new TRTCVideoFrame
- {
- videoFormat = TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420,
- bufferType = TRTCVideoBufferType.TRTCVideoBufferType_Buffer,
- data = new byte[len],
- width = width,
- height = height,
- length = len,
- timestamp = 0
- };
- }
- _videoFrame.data = frameBuffer;
- _cloud?.sendCustomVideoData(TRTCVideoStreamType.TRTCVideoStreamTypeBig, _videoFrame);
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"TRTCLivePusher Send Data Error:{ex}");
- }
- }
- public void ExitRoom()
- {
- Logger.WriteLineInfo("Exit Room");
- _cloud.stopAllRemoteView();
- _cloud.stopLocalPreview();
- _cloud.stopLocalAudio();
- _cloud.muteLocalAudio(true);
- _cloud.muteLocalVideo(TRTCVideoStreamType.TRTCVideoStreamTypeBig, true);
- _exitResetEvent.Reset();
- _cloud.exitRoom();
- _exitResetEvent.WaitOne(5000);
- }
- private void InitVideoParam(TRTCVideoResolution resolution, uint fps, uint videoBitrate, uint minVideoBitrate)
- {
- TRTCVideoEncParam videoEncParams = new TRTCVideoEncParam
- {
- videoBitrate = videoBitrate,
- minVideoBitrate = minVideoBitrate,
- videoFps = fps,
- videoResolution = resolution,
- resMode = TRTCVideoResolutionMode.TRTCVideoResolutionModeLandscape,
- enableAdjustRes = false
- };
- _cloud.setVideoEncoderParam(ref videoEncParams);
- var qosParams = new TRTCNetworkQosParam
- {
- preference = TRTCVideoQosPreference.TRTCVideoQosPreferenceClear,
- controlMode = TRTCQosControlMode.TRTCQosControlModeServer
- };
- _cloud.setNetworkQosParam(ref qosParams);
- }
- private TRTCVideoResolution GetResolution(int outputWidth, int outputHeight)
- {
- if (outputWidth <= 320 && outputHeight <= 240)//TRTC分辨率不支持,则通过ImageSender传图
- {
- return TRTCVideoResolution.TRTCVideoResolution_320_240;
- }
- else if (outputWidth <= 480 && outputHeight <= 360)
- {
- return TRTCVideoResolution.TRTCVideoResolution_480_360;
- }
- else if (outputWidth <= 640 && outputHeight <= 360)
- {
- return TRTCVideoResolution.TRTCVideoResolution_640_360;
- }
- else if (outputWidth <= 640 && outputHeight <= 480)
- {
- return TRTCVideoResolution.TRTCVideoResolution_640_480;
- }
- else if (outputWidth <= 960 && outputHeight <= 544)
- {
- return TRTCVideoResolution.TRTCVideoResolution_960_540;
- }
- else if (outputWidth <= 960 && outputHeight <= 720)
- {
- return TRTCVideoResolution.TRTCVideoResolution_960_720;
- }
- else if (outputWidth <= 1280 && outputHeight <= 720)
- {
- return TRTCVideoResolution.TRTCVideoResolution_1280_720;
- }
- else if (outputWidth <= 1920 && outputHeight <= 1080)
- {
- return TRTCVideoResolution.TRTCVideoResolution_1920_1080;
- }
- return TRTCVideoResolution.TRTCVideoResolution_640_480;
- }
- /// <summary>
- /// Get the Correct Id
- /// </summary>
- /// <param name="type"></param>
- /// <param name="deviceId"></param>
- /// <returns></returns>
- private string GetCorrectId(HardwareType type, string deviceId)
- {
- switch (type)
- {
- case HardwareType.Camera:
- var cameraList = _deviceManager.getDevicesList(TXMediaDeviceType.TXMediaDeviceTypeCamera);
- try
- {
- var count = cameraList.getCount();
- for (uint i = 0; i < count; i++)
- {
- var id = cameraList.getDevicePID(i);
- if (deviceId.Contains(id) || id.Contains(deviceId))
- {
- return id;
- }
- }
- }
- finally
- {
- cameraList.release();
- }
- break;
- case HardwareType.Mic:
- var micList = _deviceManager.getDevicesList(TXMediaDeviceType.TXMediaDeviceTypeMic);
- try
- {
- var count = micList.getCount();
- for (uint i = 0; i < count; i++)
- {
- var id = micList.getDevicePID(i);
- if (deviceId.Contains(id) || id.Contains(deviceId))
- {
- return id;
- }
- }
- }
- finally
- {
- micList.release();
- }
- break;
- case HardwareType.Speaker:
- var speakerList = _deviceManager.getDevicesList(TXMediaDeviceType.TXMediaDeviceTypeSpeaker);
- try
- {
- var count = speakerList.getCount();
- for (uint i = 0; i < count; i++)
- {
- var id = speakerList.getDevicePID(i);
- if (deviceId.Contains(id) || id.Contains(deviceId))
- {
- return id;
- }
- }
- }
- finally
- {
- speakerList.release();
- }
- break;
- }
- return string.Empty;
- }
- public void Dispose()
- {
- try
- {
- ExitRoom();
- _cloud.removeCallback(this);
- _cloud.setLogCallback(null);
- _cloud = null;
- ITRTCCloud.destroyTRTCShareInstance();
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"TRTCPusher Dispose Error:{ex}");
- }
- }
- #region callback
- public void onAudioEffectFinished(int effectId, int code)
- {
- }
- public void onCameraDidReady()
- {
- Logger.WriteLineInfo($"onCameraDidReady");
- }
- public void onConnectionLost()
- {
- Logger.WriteLineInfo($"onConnectionLost");
- }
- public void onConnectionRecovery()
- {
- Logger.WriteLineInfo($"onConnectionRecovery");
- }
- public void onConnectOtherRoom(string userId, TXLiteAVError errCode, string errMsg)
- {
- }
- public void onDeviceChange(string deviceId, TXMediaDeviceType type, TRTCDeviceState state)
- {
- }
- public void onDisconnectOtherRoom(TXLiteAVError errCode, string errMsg)
- {
- }
- public void onEnterRoom(int result)
- {
- Logger.WriteLineInfo($"Enter room :{result}");
- }
- public void onError(TXLiteAVError errCode, string errMsg, IntPtr arg)
- {
- Logger.WriteLineError($"onError errCode:{errCode}, msg:{errMsg}, arg:{arg}");
- }
- public void onExitRoom(int reason)
- {
- Logger.WriteLineInfo($"Exit room success:{reason}");
- _exitResetEvent.Set();
- }
- public void onFirstAudioFrame(string userId)
- {
- Logger.WriteLineInfo($"onFirstAudioFrame userId: {userId}");
- }
- public void onFirstVideoFrame(string userId, TRTCVideoStreamType streamType, int width, int height)
- {
- Logger.WriteLineInfo($"onFirstVideoFrame userId: {userId}, streamType: {streamType}, width:{width}, height:{height}");
- }
- public void onMicDidReady()
- {
- Logger.WriteLineInfo($"onMicDidReady");
- }
- public void onMissCustomCmdMsg(string userId, int cmdId, int errCode, int missed)
- {
- }
- public void onNetworkQuality(TRTCQualityInfo localQuality, TRTCQualityInfo[] remoteQuality, uint remoteQualityCount)
- {
- }
- public void onPlayBGMBegin(TXLiteAVError errCode)
- {
- }
- public void onPlayBGMComplete(TXLiteAVError errCode)
- {
- }
- public void onPlayBGMProgress(uint progressMS, uint durationMS)
- {
- }
- public void onRecvCustomCmdMsg(string userId, int cmdID, uint seq, byte[] msg, uint msgSize)
- {
- }
- public void onRecvSEIMsg(string userId, byte[] message, uint msgSize)
- {
- }
- public void onRemoteUserEnterRoom(string userId)
- {
- }
- public void onRemoteUserLeaveRoom(string userId, int reason)
- {
- }
- public void onScreenCaptureCovered()
- {
- }
- public void onScreenCapturePaused(int reason)
- {
- }
- public void onScreenCaptureResumed(int reason)
- {
- }
- public void onScreenCaptureStarted()
- {
- }
- public void onScreenCaptureStoped(int reason)
- {
- }
- public void onSendFirstLocalAudioFrame()
- {
- }
- public void onSendFirstLocalVideoFrame(TRTCVideoStreamType streamType)
- {
- Logger.WriteLineInfo($"onSendFirstLocalVideoFrame successed");
- SendFirstLocalVideoFrame?.Invoke(this, true);
- }
- public void onSetMixTranscodingConfig(int errCode, string errMsg)
- {
- }
- public void onSpeedTest(TRTCSpeedTestResult currentResult, uint finishedCount, uint totalCount)
- {
- }
- public void onStartPublishCDNStream(int errCode, string errMsg)
- {
- }
- public void onStartPublishing(int errCode, string errMsg)
- {
- }
- public void onStatistics(TRTCStatistics statis)
- {
- }
- public void onStopPublishCDNStream(int errCode, string errMsg)
- {
- }
- public void onStopPublishing(int errCode, string errMsg)
- {
- }
- public void onSwitchRole(TXLiteAVError errCode, string errMsg)
- {
- }
- public void onTestMicVolume(uint volume)
- {
- }
- public void onTestSpeakerVolume(uint volume)
- {
- }
- public void onTryToReconnect()
- {
- }
- public void onUserAudioAvailable(string userId, bool available)
- {
- }
- public void onUserEnter(string userId)
- {
- }
- public void onUserExit(string userId, int reason)
- {
- }
- public void onUserSubStreamAvailable(string userId, bool available)
- {
- }
- public void onUserVideoAvailable(string userId, bool available)
- {
- }
- public void onUserVoiceVolume(TRTCVolumeInfo[] userVolumes, uint userVolumesCount, uint totalVolume)
- {
- }
- public void onWarning(TXLiteAVWarning warningCode, string warningMsg, IntPtr arg)
- {
- Logger.WriteLineWarn($"onWarning errCode: {warningCode}, msg:{warningMsg}, arg:{arg}");
- }
- public void onSwitchRoom(TXLiteAVError errCode, string errMsg)
- {
- }
- public void onAudioDeviceCaptureVolumeChanged(uint volume, bool muted)
- {
- }
- public void onAudioDevicePlayoutVolumeChanged(uint volume, bool muted)
- {
- }
- internal void SetMute(bool isMute)
- {
- if (_cloud != null)
- {
- _cloud.muteLocalAudio(isMute);
- }
- }
- internal void SwitchMic(string micId)
- {
- if (_cloud != null)
- {
- _cloud.stopLocalAudio();
- var correctMicId = GetCorrectId(HardwareType.Mic, micId);
- if (!string.IsNullOrEmpty(correctMicId))
- {
- var deviceManager = _cloud.getDeviceManager();
- deviceManager.setCurrentDevice(TXMediaDeviceType.TXMediaDeviceTypeMic, correctMicId);
- _cloud.startLocalAudio(TRTCAudioQuality.TRTCAudioQualityDefault);//开启本地音频的采集和上行
- }
- }
- }
- public void onRemoteVideoStatusUpdated(string userId, TRTCVideoStreamType streamType, TRTCAVStatusType status, TRTCAVStatusChangeReason reason, IntPtr extrainfo)
- {
- }
- public void onSpeedTestResult(TRTCSpeedTestResult result)
- {
- }
- public void onStartPublishMediaStream(string taskId, int code, string message, IntPtr extraInfo)
- {
- }
- public void onUpdatePublishMediaStream(string taskId, int code, string message, IntPtr extraInfo)
- {
- }
- public void onStopPublishMediaStream(string taskId, int code, string message, IntPtr extraInfo)
- {
- }
- public void onCdnStreamStateChanged(string cdnUrl, int status, int code, string msg, IntPtr extraInfo)
- {
- }
- public void onLocalRecordBegin(int errCode, string storagePath)
- {
- }
- public void onLocalRecording(int duration, string storagePath)
- {
- }
- public void onLocalRecordComplete(int errCode, string storagePath)
- {
- }
- public void onSnapshotComplete(string userId, TRTCVideoStreamType type, byte[] data, uint length, uint width, uint height, TRTCVideoPixelFormat format)
- {
- }
- #endregion callback
- public enum HardwareType
- {
- Mic,
- Camera,
- Speaker
- }
- }
- }
|