From 7c87c4fb302ff4a56d502362d7f37e1326a41456 Mon Sep 17 00:00:00 2001 From: lxmou666 <772765102@qq.com> Date: Mon, 28 Dec 2020 23:38:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=AD=A3=E5=B8=B8=E7=9B=B4=E6=92=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- JianGongYun/TRTC/LiveClassroom.cs | 68 +++++++- .../TRTC/ViewModels/LiveWindowViewModel.cs | 66 +++++--- .../TRTC/ViewModels/SettingWindowViewModel.cs | 2 +- JianGongYun/TRTC/Windows/LiveWindow.xaml | 145 +++++++++++------- JianGongYun/TRTC/Windows/LiveWindow.xaml.cs | 82 +++++++++- 5 files changed, 274 insertions(+), 89 deletions(-) diff --git a/JianGongYun/TRTC/LiveClassroom.cs b/JianGongYun/TRTC/LiveClassroom.cs index ef73903..999af7d 100644 --- a/JianGongYun/TRTC/LiveClassroom.cs +++ b/JianGongYun/TRTC/LiveClassroom.cs @@ -40,6 +40,7 @@ namespace JianGongYun.TRTC /// 直播窗口 /// public static Window CurrentLiveWindow; + private static LiveWindowViewModel liveWinMode; public static ClassroomEntity CurrentClassroomEntity { get; private set; } //public static int UserCount = 999; /// @@ -58,6 +59,7 @@ namespace JianGongYun.TRTC CallerWindow = callerWindow; CurrentClassroomEntity = classroomEntity; CurrentLiveWindow = new LiveWindow(); + liveWinMode = CurrentLiveWindow.DataContext as LiveWindowViewModel; CurrentLiveWindow.Closed += CurrentLiveWindow_Closed; lTRTCCloud = ITRTCCloud.getTRTCShareInstance();//创建TRTC实例 @@ -99,6 +101,8 @@ namespace JianGongYun.TRTC lTRTCCloud.setLocalRenderParams(ref renderParams); //设备完结 + //liveWinMode.LoadAllScreen(); + callerWindow.Hide();//隐藏调用窗口 CurrentLiveWindow.Show(); } @@ -117,7 +121,6 @@ namespace JianGongYun.TRTC /// 视频容器 public static void StartVideoMain(Panel parent) { - var liveWinMode = CurrentLiveWindow.DataContext as LiveWindowViewModel; if (!liveWinMode.CameraRunning) { lTRTCCloud.startLocalPreview(IntPtr.Zero); @@ -126,13 +129,21 @@ namespace JianGongYun.TRTC } } + public static void ResizeVideoMain(Panel parent) + { + if (liveWinMode.CameraRunning) + { + StopVideoMain(parent); + StartVideoMain(parent); + } + } + /// /// 停止摄像头 /// /// public static void StopVideoMain(Panel parent) { - var liveWinMode = CurrentLiveWindow.DataContext as LiveWindowViewModel; if (liveWinMode.CameraRunning) { liveWinMode.CameraRunning = false; @@ -147,7 +158,6 @@ namespace JianGongYun.TRTC /// public static void StartVideoSub(Panel parent) { - var liveWinMode = CurrentLiveWindow.DataContext as LiveWindowViewModel; if (!liveWinMode.ScreenRunning) { liveWinMode.ScreenRunning = true; @@ -156,13 +166,20 @@ namespace JianGongYun.TRTC AddCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeSub, true); } } + public static void ResizeVideoSub(Panel parent) + { + if (liveWinMode.ScreenRunning) + { + RemoveCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeSub, true); + AddCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeSub, true); + } + } /// /// 停止屏幕分享 /// /// public static void StopVideoSub(Panel parent) { - var liveWinMode = CurrentLiveWindow.DataContext as LiveWindowViewModel; if (liveWinMode.ScreenRunning) { liveWinMode.ScreenRunning = false; @@ -176,13 +193,46 @@ namespace JianGongYun.TRTC /// public static void SelectVieoSub() { - var liveWinMode = CurrentLiveWindow.DataContext as LiveWindowViewModel; var current = liveWinMode.CurrentShareScreen; var rect = new RECT(); var property = new TRTCScreenCaptureProperty(); lTRTCCloud.selectScreenCaptureTarget(ref current, ref rect, ref property); } + /// + /// 启动麦克风 + /// + public static void StartMic() + { + if (!liveWinMode.MicRunning) + { + liveWinMode.MicRunning = true; + lTRTCCloud.startLocalAudio(settingWindowViewModel.LiveAudioLevel); + } + } + /// + /// 关闭麦克风 + /// + public static void StopMic() + { + if (liveWinMode.MicRunning) + { + liveWinMode.MicRunning = false; + lTRTCCloud.stopLocalAudio(); + } + } + /// + /// 设置麦克风静音 + /// + public static void SetMicMute(bool? mute = true) + { + if (liveWinMode.MicRunning) + { + liveWinMode.MicMute = mute.HasValue ? mute.Value : !liveWinMode.MicMute; + lTRTCCloud.muteLocalAudio(liveWinMode.MicMute); + } + } + /// /// 添加自定义渲染 View 并绑定渲染回调 /// @@ -190,10 +240,11 @@ namespace JianGongYun.TRTC { TXLiteAVVideoView videoView = new TXLiteAVVideoView(); videoView.RegEngine(userId, streamType, lTRTCCloud, local); - videoView.SetRenderMode(settingWindowViewModel.RenderParams.fillMode); + videoView.SetRenderMode(streamType == TRTCVideoStreamType.TRTCVideoStreamTypeBig ? settingWindowViewModel.RenderParams.fillMode : TRTCVideoFillMode.TRTCVideoFillMode_Fit); videoView.Width = parent.ActualWidth; videoView.Height = parent.ActualHeight; - parent.Dispatcher.Invoke(new Action(() => { + parent.Dispatcher.Invoke(new Action(() => + { parent.Children.Add(videoView); })); string key = string.Format("{0}_{1}", userId, streamType); @@ -210,7 +261,8 @@ namespace JianGongYun.TRTC if (VideoViews.TryGetValue(key, out videoView)) { videoView.RemoveEngine(lTRTCCloud); - parent.Dispatcher.Invoke(new Action(() => { + parent.Dispatcher.Invoke(new Action(() => + { parent.Children.Remove(videoView); })); VideoViews.Remove(key); diff --git a/JianGongYun/TRTC/ViewModels/LiveWindowViewModel.cs b/JianGongYun/TRTC/ViewModels/LiveWindowViewModel.cs index 0b72bea..1619ee0 100644 --- a/JianGongYun/TRTC/ViewModels/LiveWindowViewModel.cs +++ b/JianGongYun/TRTC/ViewModels/LiveWindowViewModel.cs @@ -177,12 +177,28 @@ namespace JianGongYun.TRTC.ViewModels return _MicRunning; } } + /// + /// 麦克风静音 + /// + private bool _MicMute = false; + public bool MicMute + { + set + { + _MicMute = value; + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("MicMute")); + } + } + get + { + return _MicMute; + } + } - static object ScreenListLock = new object(); - private SIZE thumbSize = new SIZE { cx = 300, cy = 200 }; - private SIZE iconSize = new SIZE { cx = 50, cy = 50 }; - private ObservableCollection _LiveScreens; + private ObservableCollection _LiveScreens = new ObservableCollection(); /// /// 可分享桌面 /// @@ -190,24 +206,38 @@ namespace JianGongYun.TRTC.ViewModels { get { - lock (ScreenListLock) - { - _LiveScreens.Clear(); - var temp = LiveClassroom.lTRTCCloud.getScreenCaptureSources(ref thumbSize, ref iconSize); - var count = temp.getCount(); - for (uint i = 0; i < count; i++) - { - var info = temp.getSourceInfo(i); - //var icon = Util.ToWriteableBitmap(ref info.iconBGRA); - var thumb = info.thumbBGRA.ToWriteableBitmap(); - _LiveScreens.Add(new TRTCScreenEntity { SourceId = info.sourceId, SourceName = info.sourceName, Type = info.type, Thumb = thumb, Info = info }); - } - temp.release(); - } return _LiveScreens; } } + static object ScreenListLock = new object(); + private SIZE thumbSize = new SIZE { cx = 300, cy = 200 }; + private SIZE iconSize = new SIZE { cx = 50, cy = 50 }; + /// + /// 获取所有桌面列表 + /// + public void LoadAllScreen() + { + lock (ScreenListLock) + { + Console.WriteLine("get LiveScreens"); + _LiveScreens.Clear(); + Console.WriteLine("get LiveScreens Clear"); + var temp = LiveClassroom.lTRTCCloud.getScreenCaptureSources(ref thumbSize, ref iconSize); + var count = temp.getCount(); + Console.WriteLine($"get LiveScreens {count}"); + for (uint i = 0; i < count; i++) + { + var info = temp.getSourceInfo(i); + //var icon = Util.ToWriteableBitmap(ref info.iconBGRA); + Console.WriteLine($"get LiveScreens {i} {info.sourceId}"); + var thumb = info.thumbBGRA.ToWriteableBitmap(); + _LiveScreens.Add(new TRTCScreenEntity { SourceId = info.sourceId, SourceName = info.sourceName, Type = info.type, Thumb = thumb, Info = info }); + } + temp.release(); + } + } + /// /// 当前分享的桌面列表 diff --git a/JianGongYun/TRTC/ViewModels/SettingWindowViewModel.cs b/JianGongYun/TRTC/ViewModels/SettingWindowViewModel.cs index e5a9e07..ceeeee1 100644 --- a/JianGongYun/TRTC/ViewModels/SettingWindowViewModel.cs +++ b/JianGongYun/TRTC/ViewModels/SettingWindowViewModel.cs @@ -616,7 +616,7 @@ namespace JianGongYun.TRTC.ViewModels { get { - return new TRTCVideoEncParam { enableAdjustRes = true, resMode = TRTCVideoResolutionMode.TRTCVideoResolutionModeLandscape, videoBitrate = LiveMainBitrate, videoFps = LiveMainFps }; + return new TRTCVideoEncParam { enableAdjustRes = false, resMode = TRTCVideoResolutionMode.TRTCVideoResolutionModeLandscape, videoBitrate = LiveMainBitrate, videoFps = LiveMainFps }; } } public TRTCNetworkQosParam QosParams diff --git a/JianGongYun/TRTC/Windows/LiveWindow.xaml b/JianGongYun/TRTC/Windows/LiveWindow.xaml index 80b2b44..9428c91 100644 --- a/JianGongYun/TRTC/Windows/LiveWindow.xaml +++ b/JianGongYun/TRTC/Windows/LiveWindow.xaml @@ -19,6 +19,8 @@ M864 159.872L160 160c-17.696 0-32 14.176-32 31.872v448a32 32 0 0 0 32 32h704a32 32 0 0 0 32-32v-448a32 32 0 0 0-32-32zM864 640H160V191.872h704V640z M928 32H96a96 96 0 0 0-96 96v640a95.904 95.904 0 0 0 95.68 95.936H416v38.944l-199.744 25.952A31.968 31.968 0 0 0 224 991.872h576a32 32 0 0 0 7.744-63.072L608 902.88v-38.944h320.32A95.904 95.904 0 0 0 1024 768V128a96 96 0 0 0-96-96z m32 736c0 17.632-14.368 32-32 32H96c-17.664 0-32-14.368-32-32V128a32 32 0 0 1 32-32h832c17.632 0 32 14.336 32 32v640z M486.4 972.8v-128.9728A332.8 332.8 0 0 1 179.2 512a25.6 25.6 0 0 1 51.2 0 281.6 281.6 0 0 0 563.2 0 25.6 25.6 0 1 1 51.2 0 332.8 332.8 0 0 1-307.2 331.8272V972.8h153.6a25.6 25.6 0 1 1 0 51.2h-358.4a25.6 25.6 0 1 1 0-51.2h153.6zM512 51.2a153.6 153.6 0 0 0-153.6 153.6v307.2a153.6 153.6 0 0 0 307.2 0V204.8a153.6 153.6 0 0 0-153.6-153.6z m0-51.2a204.8 204.8 0 0 1 204.8 204.8v307.2a204.8 204.8 0 1 1-409.6 0V204.8a204.8 204.8 0 0 1 204.8-204.8z M511.626 1.896C229.572 1.896 0.927 230.541 0.927 512.595c0 282.055 228.645 510.699 510.699 510.699s510.698-228.645 510.698-510.699S793.68 1.896 511.626 1.896z m0 69.641c243.606 0 441.058 197.474 441.058 441.058 0 87.347-25.392 168.762-69.194 237.271-73.419-77.609-170.944-132.204-280.597-151.829 70.004-33.755 118.404-105.164 118.404-188.066 0-115.388-93.535-208.922-208.923-208.922S303.452 294.583 303.452 409.97c0 82.902 48.399 154.311 118.403 188.066-110.093 19.704-207.96 74.661-281.479 152.77-44.177-68.704-69.808-150.465-69.808-238.211 0-243.584 197.496-441.058 441.058-441.058z + M447.5904 819.1488H166.4a89.6 89.6 0 0 1-89.6-89.4976V166.4c0-49.3568 40.192-89.5488 89.6-89.5488h563.2c49.4592 0 89.6512 40.192 89.6512 89.5488v281.6H896v-281.6A166.5536 166.5536 0 0 0 729.6 0h-563.2A166.5536 166.5536 0 0 0 0 166.4v563.2512A166.656 166.656 0 0 0 166.4 896h281.1904v-76.8512z M947.2 238.5408V857.6c0 49.408-40.192 89.6-89.6 89.6H242.7904V1024H857.6A166.6048 166.6048 0 0 0 1024 857.6V238.5408h-76.8z M577.8944 813.8752h235.9808v-236.032h-76.8v104.96l-395.776-395.8784h104.9088V210.176H210.1248v235.9808h76.8V341.248l395.9296 395.8784h-104.96z + M2.896 921.614L924.656 0l102.385 102.386L105.354 1024z @@ -73,76 +75,105 @@ + + + + + + + + + + + + + + + + + - - - - 请选择授课方式 - 您可在上课期间随时调整授课方式 - - - - - - - - - - - - - - - + + + + + + + 请选择授课方式 + 您可在上课期间随时调整授课方式 + + + + + + + + + + + + + + + + + + + 摄像头预览 + - - - 摄像头预览 - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - true + + + + + + + + diff --git a/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs b/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs index 160c335..f19e9ca 100644 --- a/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs +++ b/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs @@ -15,6 +15,7 @@ using System.Linq; using System.Windows.Threading; using JianGongYun.TRTC.Components; using System.Runtime.InteropServices; +using System.ComponentModel; namespace JianGongYun.TRTC.Windows { @@ -31,13 +32,33 @@ namespace JianGongYun.TRTC.Windows public LiveWindow() { InitializeComponent(); - AttachConsole(-1);//把进程挂在控制台,通过命令行启动程序可以看到控制台输出 + BeforeLiveSubViewWrap.SizeChanged += BeforeLiveSubViewWrap_SizeChanged; + AfterLiveSubViewWrap.SizeChanged += AfterLiveSubViewWrap_SizeChanged; + //AttachConsole(-1);//把进程挂在控制台,通过命令行启动程序可以看到控制台输出 LiveWindowViewModel = new ViewModels.LiveWindowViewModel(); SettingWindowViewModel = ViewModels.SettingWindowViewModel.GetInstance(); this.DataContext = LiveWindowViewModel; BorderBrush = new SolidColorBrush(color: Color.FromRgb(42, 43, 48));//窗口标题背景颜色 } + private void AfterLiveSubViewWrap_SizeChanged(object sender, SizeChangedEventArgs e) + { + if (LiveWindowViewModel.IsLive) + { + this.Dispatcher.Invoke(new Action(() => LiveClassroom.ResizeVideoSub(AfterLiveSubViewWrap))); + } + } + + private void BeforeLiveSubViewWrap_SizeChanged(object sender, SizeChangedEventArgs e) + { + if (!LiveWindowViewModel.IsLive) + { + this.Dispatcher.Invoke(new Action(() => LiveClassroom.ResizeVideoSub(BeforeLiveSubViewWrap))); + } + } + + + protected override void OnActivated(EventArgs e) { base.OnActivated(e); @@ -72,6 +93,21 @@ namespace JianGongYun.TRTC.Windows base.OnClosed(e); } + protected override void OnClosing(CancelEventArgs e) + { + LiveClassroom.StopMic(); + if (LiveWindowViewModel.IsLive) + { + + } + else + { + LiveClassroom.StopVideoMain(BeforeLiveViewWrap); + LiveClassroom.StopVideoSub(BeforeLiveSubViewWrap); + } + base.OnClosing(e); + } + /// /// 开始/结束直播 /// @@ -83,6 +119,11 @@ namespace JianGongYun.TRTC.Windows var start = Convert.ToBoolean(btn.Tag); if (start)//开始直播 { + //停止预览 + LiveClassroom.StopMic(); + LiveClassroom.StopVideoMain(BeforeLiveViewWrap); + LiveClassroom.StopVideoSub(BeforeLiveSubViewWrap); + this.Dispatcher.Invoke(new Action(() => { btn.Type = AduSkin.Controls.FlatButtonSkinEnum.warning; @@ -96,11 +137,28 @@ namespace JianGongYun.TRTC.Windows btn.Type = AduSkin.Controls.FlatButtonSkinEnum.info; btn.Content = "开始直播"; })); + + //开始直播 + if (LiveWindowViewModel.LiveType == Models.LiveTypeEnum.CameraAndScreen || LiveWindowViewModel.LiveType == Models.LiveTypeEnum.OnlyCamera) + { + LiveClassroom.StartVideoMain(AfterLiveViewWrap); + } + if (LiveWindowViewModel.LiveType == Models.LiveTypeEnum.CameraAndScreen || LiveWindowViewModel.LiveType == Models.LiveTypeEnum.OnlyScreen) + { + LiveClassroom.StartVideoSub(AfterLiveSubViewWrap); + } + LiveClassroom.StartMic(); + LiveClassroom.SetMicMute(false); + }, SettingWindowViewModel.ScreenRecordingCountdown); } else { LiveWindowViewModel.IsLive = start; + //停止直播 + LiveClassroom.StopMic(); + LiveClassroom.StopVideoMain(AfterLiveViewWrap); + LiveClassroom.StopVideoSub(AfterLiveSubViewWrap); } } @@ -165,13 +223,15 @@ namespace JianGongYun.TRTC.Windows switch (LiveWindowViewModel.LiveType) { case Models.LiveTypeEnum.CameraAndScreen: - LiveClassroom.StopVideoSub(BeforeLiveSubViewWrap);//停止屏幕分享(二次选择需要先停止分享,不然界面会卡死) + LiveClassroom.StopVideoSub(BeforeLiveSubViewWrap);//停止屏幕分享(直播中SDK再次获取窗口列表会卡死) LiveWindowViewModel.ShowShareScreenList = true; + this.Dispatcher.Invoke(new Action(() => LiveWindowViewModel.LoadAllScreen())); break; case Models.LiveTypeEnum.OnlyScreen: - LiveClassroom.StopVideoSub(BeforeLiveSubViewWrap);//停止屏幕分享(二次选择需要先停止分享,不然界面会卡死) + LiveClassroom.StopVideoSub(BeforeLiveSubViewWrap);//停止屏幕分享(直播中SDK再次获取窗口列表会卡死) LiveClassroom.StopVideoMain(BeforeLiveViewWrap); //停止摄像头分享 LiveWindowViewModel.ShowShareScreenList = true; + this.Dispatcher.Invoke(new Action(() => LiveWindowViewModel.LoadAllScreen())); break; case Models.LiveTypeEnum.OnlyCamera: LiveClassroom.StopVideoSub(BeforeLiveSubViewWrap);//停止屏幕分享 @@ -194,11 +254,23 @@ namespace JianGongYun.TRTC.Windows private void ShareList_Selected(object sender, RoutedEventArgs e) { CloseShareList_Click(sender, e); - LiveClassroom.StartVideoSub(BeforeLiveSubViewWrap); - if (LiveWindowViewModel.LiveType== Models.LiveTypeEnum.CameraAndScreen) + if (LiveWindowViewModel.IsLive && LiveWindowViewModel.ScreenRunning) + { + LiveClassroom.SelectVieoSub(); + } + else + { + LiveClassroom.StartVideoSub(BeforeLiveSubViewWrap); + } + if (LiveWindowViewModel.LiveType == Models.LiveTypeEnum.CameraAndScreen) { LiveClassroom.StartVideoMain(BeforeLiveViewWrap); } } + + private void ChangeWin_Click(object sender, RoutedEventArgs e) + { + LiveWindowViewModel.ShowShareScreenList = true; + } } }