This commit is contained in:
lxmou666 2020-12-30 17:40:29 +08:00
parent 8d8cb28d66
commit bc46d869a0
5 changed files with 110 additions and 31 deletions

View File

@ -16,6 +16,7 @@ using System.Windows.Controls;
using Window = System.Windows.Window; using Window = System.Windows.Window;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Windows.Data; using System.Windows.Data;
using System.Drawing;
namespace JianGongYun.TRTC namespace JianGongYun.TRTC
{ {
@ -46,7 +47,7 @@ namespace JianGongYun.TRTC
public static ClassroomEntity CurrentClassroomEntity { get; private set; } public static ClassroomEntity CurrentClassroomEntity { get; private set; }
public static TRTCCloudCallback TRTCCloudCallback = new TRTCCloudCallback(); public static TRTCCloudCallback TRTCCloudCallback = new TRTCCloudCallback();
public static ConcurrentBag<Task> SaveFileTask = new ConcurrentBag<Task>(); //private static ConcurrentBag<Task> VedioRecords = new ConcurrentBag<Task>();
//public static int UserCount = 999; //public static int UserCount = 999;
/// <summary> /// <summary>
/// 进入直播教室 /// 进入直播教室
@ -138,7 +139,7 @@ namespace JianGongYun.TRTC
/// <summary> /// <summary>
/// 视频画面 /// 视频画面
/// </summary> /// </summary>
private static Dictionary<string, TXLiteAVVideoView> VideoViews = new Dictionary<string, TXLiteAVVideoView>(); public static Dictionary<string, TXLiteAVVideoView> VideoViews = new Dictionary<string, TXLiteAVVideoView>();
/// <summary> /// <summary>
/// 启动摄像头 /// 启动摄像头
/// </summary> /// </summary>
@ -149,20 +150,17 @@ namespace JianGongYun.TRTC
{ {
lTRTCCloud.startLocalPreview(IntPtr.Zero); lTRTCCloud.startLocalPreview(IntPtr.Zero);
liveWinMode.CameraRunning = true; liveWinMode.CameraRunning = true;
return AddCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, true); var view = AddCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, true);
if (liveWinMode.IsLive)
{
VedioRecordTask(view, TRTCVideoStreamType.TRTCVideoStreamTypeBig);
}
return view;
} }
return null; return null;
} }
public static void ResizeVideoMain(Panel parent)
{
if (liveWinMode.CameraRunning)
{
StopVideoMain(parent);
StartVideoMain(parent);
}
}
/// <summary> /// <summary>
/// 停止摄像头 /// 停止摄像头
@ -189,18 +187,15 @@ namespace JianGongYun.TRTC
liveWinMode.ScreenRunning = true; liveWinMode.ScreenRunning = true;
SelectVieoSub(); SelectVieoSub();
lTRTCCloud.startScreenCapture(IntPtr.Zero, TRTCVideoStreamType.TRTCVideoStreamTypeSub, settingWindowViewModel.EncParams); lTRTCCloud.startScreenCapture(IntPtr.Zero, TRTCVideoStreamType.TRTCVideoStreamTypeSub, settingWindowViewModel.EncParams);
return AddCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeSub, true); var view = AddCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeSub, true);
if (liveWinMode.IsLive)
{
VedioRecordTask(view, TRTCVideoStreamType.TRTCVideoStreamTypeSub);
}
return view;
} }
return null; return null;
} }
public static void ResizeVideoSub(Panel parent)
{
if (liveWinMode.ScreenRunning)
{
RemoveCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeSub, true);
AddCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeSub, true);
}
}
/// <summary> /// <summary>
/// 停止屏幕分享 /// 停止屏幕分享
/// </summary> /// </summary>
@ -238,7 +233,7 @@ namespace JianGongYun.TRTC
if (liveWinMode.IsLive && !liveWinMode.AudioRecordRunning) if (liveWinMode.IsLive && !liveWinMode.AudioRecordRunning)
{ {
liveWinMode.AudioRecordRunning = true; liveWinMode.AudioRecordRunning = true;
var time = DateTime.Now.ToString("yyyyMMddHHmmssfff"); var time = Util.TimeStr();
var pars = new TRTCAudioRecordingParams { filePath = Path.Combine(RecoderDir, $"{time}audio.pcm") }; var pars = new TRTCAudioRecordingParams { filePath = Path.Combine(RecoderDir, $"{time}audio.pcm") };
var res = lTRTCCloud.startAudioRecording(ref pars); var res = lTRTCCloud.startAudioRecording(ref pars);
Console.WriteLine(res); Console.WriteLine(res);
@ -273,6 +268,65 @@ namespace JianGongYun.TRTC
} }
} }
public static void VedioRecordTask(TXLiteAVVideoView view, TRTCVideoStreamType streamType)
{
var end = false;
ConcurrentQueue<Bitmap> bitmaps = new ConcurrentQueue<Bitmap>();
view.OnRenderVideoFrameHandler += (b) =>
{
bitmaps.Enqueue(b.ToBitmap());
};
view.OnViewRemove += () =>
{
end = true;
};
var task = Task.Factory.StartNew(() =>
{
Console.WriteLine($"VedioRecordTask Start {streamType}");
var _recoderDir = RecoderDir;
var imgTemp = Path.Combine(_recoderDir, $"{streamType}.png");
var videoFile = Path.Combine(_recoderDir, $"{Util.TimeStr()}_{streamType}.avi");
VideoWriter vw = new VideoWriter();
Mat mat = default;
bool videoWriterInit = false;
while (!end || bitmaps.Count > 0)
{
if (bitmaps.Count == 0)
{
Thread.Sleep(100);
continue;
}
if (bitmaps.TryDequeue(out var bitmap))
{
bitmap.Save(imgTemp, System.Drawing.Imaging.ImageFormat.Png);
bitmap.Dispose();
mat = Cv2.ImRead(imgTemp, ImreadModes.AnyColor);
Cv2.ImShow(streamType.ToString(), mat);
Cv2.WaitKey(1);
if (!videoWriterInit)
{
vw.Open(videoFile, FourCC.H264, settingWindowViewModel.EncParams.videoFps, mat.Size());
videoWriterInit = true;
}
vw.Write(mat);
}
else
{
Thread.Sleep(100);
}
}
mat?.Dispose();
vw?.Release();
vw?.Dispose();
if (File.Exists(imgTemp))
{
File.Delete(imgTemp);
}
Console.WriteLine($"VedioRecordTask End {streamType}");
}, TaskCreationOptions.LongRunning);
}
/// <summary> /// <summary>
/// 添加自定义渲染 View 并绑定渲染回调 /// 添加自定义渲染 View 并绑定渲染回调
/// </summary> /// </summary>
@ -294,6 +348,24 @@ namespace JianGongYun.TRTC
return videoView; return videoView;
} }
/// <summary>
/// 获取屏幕列表需要暂停屏幕分享渲染
/// </summary>
/// <param name="action"></param>
public static void WillGetScreens(Action action)
{
if (liveWinMode.ScreenRunning && VideoViews.TryGetValue($"{CurrentClassroomEntity.TeacherId}_{TRTCVideoStreamType.TRTCVideoStreamTypeSub}", out var view))
{
view.SetPause(true);
action.Invoke();
view.SetPause(false);
}
else
{
action.Invoke();
}
}
/// <summary> /// <summary>
/// 移除自定义渲染 View 并解绑渲染回调 /// 移除自定义渲染 View 并解绑渲染回调
/// </summary> /// </summary>

View File

@ -90,5 +90,6 @@ namespace JianGongYun.TRTC.Utils
return writeableBitmap; return writeableBitmap;
} }
public static string TimeStr() => DateTime.Now.ToString("yyyyMMddHHmmssfff");
} }
} }

View File

@ -229,7 +229,6 @@ namespace JianGongYun.TRTC.ViewModels
} }
} }
static object ScreenListLock = new object();
private SIZE thumbSize = new SIZE { cx = 300, cy = 200 }; private SIZE thumbSize = new SIZE { cx = 300, cy = 200 };
private SIZE iconSize = new SIZE { cx = 50, cy = 50 }; private SIZE iconSize = new SIZE { cx = 50, cy = 50 };
/// <summary> /// <summary>
@ -237,7 +236,7 @@ namespace JianGongYun.TRTC.ViewModels
/// </summary> /// </summary>
public void LoadAllScreen() public void LoadAllScreen()
{ {
lock (ScreenListLock) LiveClassroom.WillGetScreens(() =>
{ {
//Console.WriteLine("get LiveScreens"); //Console.WriteLine("get LiveScreens");
_LiveScreens.Clear(); _LiveScreens.Clear();
@ -254,7 +253,7 @@ namespace JianGongYun.TRTC.ViewModels
_LiveScreens.Add(new TRTCScreenEntity { SourceId = info.sourceId, SourceName = info.sourceName, Type = info.type, Thumb = thumb, Info = info }); _LiveScreens.Add(new TRTCScreenEntity { SourceId = info.sourceId, SourceName = info.sourceName, Type = info.type, Thumb = thumb, Info = info });
} }
temp.release(); temp.release();
} });
} }

View File

@ -640,6 +640,10 @@ namespace JianGongYun.TRTC.ViewModels
#region #region
/// <summary> /// <summary>
/// 磁盘最低容量分界线
/// </summary>
public const double DiskWarningSize = 5;
/// <summary>
/// 磁盘剩余空间 /// 磁盘剩余空间
/// </summary> /// </summary>
public double DiskSize public double DiskSize
@ -662,7 +666,7 @@ namespace JianGongYun.TRTC.ViewModels
{ {
get get
{ {
return DiskSize <= 20 ? Brushes.Orange : Brushes.LawnGreen; return DiskSize <= DiskWarningSize ? Brushes.Orange : Brushes.LawnGreen;
} }
} }
#endregion #endregion

View File

@ -98,7 +98,9 @@ namespace JianGongYun.TRTC.Windows
LiveClassroom.StopMic(); LiveClassroom.StopMic();
if (LiveWindowViewModel.IsLive) if (LiveWindowViewModel.IsLive)
{ {
LiveClassroom.StopVideoMain(AfterLiveViewWrap);
LiveClassroom.StopVideoSub(AfterLiveSubViewWrap);
LiveClassroom.StopMic();
} }
else else
{ {
@ -119,7 +121,7 @@ namespace JianGongYun.TRTC.Windows
var start = Convert.ToBoolean(btn.Tag); var start = Convert.ToBoolean(btn.Tag);
if (start)//开始直播 if (start)//开始直播
{ {
if (SettingWindowViewModel.DiskSize <= 20) if (SettingWindowViewModel.DiskSize <= ViewModels.SettingWindowViewModel.DiskWarningSize)
{ {
var res = AduMessageBox.Show("磁盘剩余空间不足,请选择其他磁盘", "提醒"); var res = AduMessageBox.Show("磁盘剩余空间不足,请选择其他磁盘", "提醒");
return; return;
@ -229,12 +231,12 @@ namespace JianGongYun.TRTC.Windows
switch (LiveWindowViewModel.LiveType) switch (LiveWindowViewModel.LiveType)
{ {
case Models.LiveTypeEnum.CameraAndScreen: case Models.LiveTypeEnum.CameraAndScreen:
LiveClassroom.StopVideoSub(BeforeLiveSubViewWrap);//停止屏幕分享(直播中SDK再次获取窗口列表会卡死) //LiveClassroom.StopVideoSub(BeforeLiveSubViewWrap);//停止屏幕分享(直播中SDK再次获取窗口列表会卡死)
LiveWindowViewModel.ShowShareScreenList = true; LiveWindowViewModel.ShowShareScreenList = true;
this.Dispatcher.Invoke(new Action(() => LiveWindowViewModel.LoadAllScreen())); this.Dispatcher.Invoke(new Action(() => LiveWindowViewModel.LoadAllScreen()));
break; break;
case Models.LiveTypeEnum.OnlyScreen: case Models.LiveTypeEnum.OnlyScreen:
LiveClassroom.StopVideoSub(BeforeLiveSubViewWrap);//停止屏幕分享(直播中SDK再次获取窗口列表会卡死) //LiveClassroom.StopVideoSub(BeforeLiveSubViewWrap);//停止屏幕分享(直播中SDK再次获取窗口列表会卡死)
LiveClassroom.StopVideoMain(BeforeLiveViewWrap); //停止摄像头分享 LiveClassroom.StopVideoMain(BeforeLiveViewWrap); //停止摄像头分享
LiveWindowViewModel.ShowShareScreenList = true; LiveWindowViewModel.ShowShareScreenList = true;
this.Dispatcher.Invoke(new Action(() => LiveWindowViewModel.LoadAllScreen())); this.Dispatcher.Invoke(new Action(() => LiveWindowViewModel.LoadAllScreen()));
@ -260,7 +262,7 @@ namespace JianGongYun.TRTC.Windows
private void ShareList_Selected(object sender, RoutedEventArgs e) private void ShareList_Selected(object sender, RoutedEventArgs e)
{ {
CloseShareList_Click(sender, e); CloseShareList_Click(sender, e);
if (LiveWindowViewModel.IsLive && LiveWindowViewModel.ScreenRunning) if (LiveWindowViewModel.ScreenRunning)
{ {
LiveClassroom.SelectVieoSub(); LiveClassroom.SelectVieoSub();
} }
@ -277,6 +279,7 @@ namespace JianGongYun.TRTC.Windows
private void ChangeWin_Click(object sender, RoutedEventArgs e) private void ChangeWin_Click(object sender, RoutedEventArgs e)
{ {
LiveWindowViewModel.ShowShareScreenList = true; LiveWindowViewModel.ShowShareScreenList = true;
this.Dispatcher.Invoke(new Action(() => LiveWindowViewModel.LoadAllScreen()));
} }
} }
} }