This commit is contained in:
parent
8d8cb28d66
commit
bc46d869a0
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -83,12 +83,13 @@ namespace JianGongYun.TRTC.Utils
|
||||||
public static WriteableBitmap ToWriteableBitmap(this TRTCImageBuffer data)
|
public static WriteableBitmap ToWriteableBitmap(this TRTCImageBuffer data)
|
||||||
{
|
{
|
||||||
var writeableBitmap = new WriteableBitmap((int)data.width, (int)data.height, 96, 96, PixelFormats.Pbgra32, null);
|
var writeableBitmap = new WriteableBitmap((int)data.width, (int)data.height, 96, 96, PixelFormats.Pbgra32, null);
|
||||||
writeableBitmap.Lock();
|
writeableBitmap.Lock();
|
||||||
Marshal.Copy(data.buffer, 0, writeableBitmap.BackBuffer, (int)data.length);
|
Marshal.Copy(data.buffer, 0, writeableBitmap.BackBuffer, (int)data.length);
|
||||||
writeableBitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, (int)data.width, (int)data.height));
|
writeableBitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, (int)data.width, (int)data.height));
|
||||||
writeableBitmap.Unlock();
|
writeableBitmap.Unlock();
|
||||||
return writeableBitmap;
|
return writeableBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string TimeStr() => DateTime.Now.ToString("yyyyMMddHHmmssfff");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue