????
This commit is contained in:
parent
6fdfc0db76
commit
98dd3da915
|
@ -200,6 +200,10 @@ namespace JianGongYun.TRTC
|
||||||
liveWinMode.CameraRunning = false;
|
liveWinMode.CameraRunning = false;
|
||||||
lTRTCCloud.stopLocalPreview();
|
lTRTCCloud.stopLocalPreview();
|
||||||
RemoveCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, true);
|
RemoveCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, true);
|
||||||
|
lock (MainFrame)
|
||||||
|
{
|
||||||
|
MainFrame.Create(1, 1, MatType.CV_8UC4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,6 +253,10 @@ namespace JianGongYun.TRTC
|
||||||
liveWinMode.ScreenRunning = false;
|
liveWinMode.ScreenRunning = false;
|
||||||
lTRTCCloud.stopScreenCapture();
|
lTRTCCloud.stopScreenCapture();
|
||||||
RemoveCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeSub, true);
|
RemoveCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeSub, true);
|
||||||
|
lock (SubFrame)
|
||||||
|
{
|
||||||
|
SubFrame.Create(1, 1, MatType.CV_8UC4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,19 +321,24 @@ namespace JianGongYun.TRTC
|
||||||
|
|
||||||
public static void VideoRecordTask(ref Action onEnd)
|
public static void VideoRecordTask(ref Action onEnd)
|
||||||
{
|
{
|
||||||
|
var backColor = Scalar.FromRgb(0x20, 0x20, 0x20);
|
||||||
|
var resolution = settingWindowViewModel.SubEncParams.videoResolution.ToString().Split('_');//屏幕分辨率,本地储存分辨率以屏幕分享分辨率为基准
|
||||||
|
var fps = settingWindowViewModel.LiveFps;//视频采集的fps
|
||||||
|
BackgroundFrame = new Mat(int.Parse(resolution[2]), int.Parse(resolution[1]), MatType.CV_8UC4, backColor);//合成双路视频的背景
|
||||||
|
var delay = 1000 / (int)fps;//每帧时间
|
||||||
|
var delayEqualize = 0;//每帧时间补偿,在性能和其他因素影响下delay的时间不一定充足
|
||||||
|
var _recoderDir = RecoderDir;
|
||||||
|
var videoFile = Path.Combine(_recoderDir, $"{Util.TimeStr()}_video.avi");
|
||||||
|
//var videoFrameTemp = Path.Combine(_recoderDir, $"videoFrameTemp.bmp");
|
||||||
|
var backHeight = BackgroundFrame.Rows;//画面高度
|
||||||
|
var backWidth = BackgroundFrame.Cols;//画面宽度
|
||||||
|
|
||||||
|
VideoWriter vw = new VideoWriter(videoFile, FourCC.H264, fps, BackgroundFrame.Size());
|
||||||
var end = false;
|
var end = false;
|
||||||
onEnd = () =>
|
onEnd = () =>
|
||||||
{
|
{
|
||||||
end = true;
|
end = true;
|
||||||
BackgroundFrame?.Dispose();
|
|
||||||
BackgroundFrame = null;
|
|
||||||
};
|
};
|
||||||
var backColor = Scalar.FromRgb(0x20, 0x20, 0x20);
|
|
||||||
var resolution = settingWindowViewModel.SubEncParams.videoResolution.ToString().Split('_');//屏幕分辨率,本地储存分辨率以屏幕分享分辨率为基准
|
|
||||||
var fps = settingWindowViewModel.LiveFps;//视频采集的fps
|
|
||||||
BackgroundFrame = new Mat(int.Parse(resolution[2]), int.Parse(resolution[1]), MatType.CV_8UC3, backColor);//合成双路视频的背景
|
|
||||||
var delay = 1000 / (int)fps;//每帧时间
|
|
||||||
var delayEqualize = 0;//每帧时间补偿,在性能和其他因素影响下delay的时间不一定充足
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -337,17 +350,10 @@ namespace JianGongYun.TRTC
|
||||||
bool onlyCameraInit = false;//只有摄像头的话背景填充为backColor,变量标记只需设置一次
|
bool onlyCameraInit = false;//只有摄像头的话背景填充为backColor,变量标记只需设置一次
|
||||||
bool noImgInit = false;//没有画面背景也填充backColor,变量标记只需设置一次
|
bool noImgInit = false;//没有画面背景也填充backColor,变量标记只需设置一次
|
||||||
|
|
||||||
var _recoderDir = RecoderDir;
|
|
||||||
var videoFile = Path.Combine(_recoderDir, $"{Util.TimeStr()}.avi");
|
|
||||||
VideoWriter vw = new VideoWriter(videoFile, FourCC.H264, fps, BackgroundFrame.Size());
|
|
||||||
|
|
||||||
|
|
||||||
var backHeight = BackgroundFrame.Rows;//画面高度
|
|
||||||
var backWidth = BackgroundFrame.Cols;//画面宽度
|
|
||||||
|
|
||||||
//屏幕分享画面
|
//屏幕分享画面
|
||||||
var screenRoi = BackgroundFrame[new OpenCvSharp.Rect(0, 0, backWidth, backHeight)];
|
var screenRoi = BackgroundFrame[new OpenCvSharp.Rect(0, 0, backWidth, backHeight)];
|
||||||
var screenMask = new Mat(backHeight, backWidth, MatType.CV_8UC1, new Scalar(1));
|
|
||||||
|
|
||||||
//摄像头小画面定位
|
//摄像头小画面定位
|
||||||
var cameraMargin = 20;//右下角偏移量
|
var cameraMargin = 20;//右下角偏移量
|
||||||
|
@ -355,11 +361,9 @@ namespace JianGongYun.TRTC
|
||||||
var smallX = backWidth - smallCameraSize - cameraMargin;
|
var smallX = backWidth - smallCameraSize - cameraMargin;
|
||||||
var smallY = backHeight - smallCameraSize - cameraMargin;
|
var smallY = backHeight - smallCameraSize - cameraMargin;
|
||||||
var smallRoi = BackgroundFrame[new OpenCvSharp.Rect(smallX, smallY, smallCameraSize, smallCameraSize)];
|
var smallRoi = BackgroundFrame[new OpenCvSharp.Rect(smallX, smallY, smallCameraSize, smallCameraSize)];
|
||||||
var smallMask = new Mat(smallCameraSize, smallCameraSize, MatType.CV_8UC1, new Scalar(1));
|
|
||||||
|
|
||||||
//摄像头大画面位置
|
//摄像头大画面位置
|
||||||
var bigRoi = BackgroundFrame[new OpenCvSharp.Rect((backWidth - backHeight) / 2, 0, backHeight, backHeight)];
|
var bigRoi = BackgroundFrame[new OpenCvSharp.Rect((backWidth - backHeight) / 2, 0, backHeight, backHeight)];
|
||||||
var bigMask = new Mat(backHeight, backHeight, MatType.CV_8UC1, new Scalar(1));
|
|
||||||
|
|
||||||
|
|
||||||
while (!end)
|
while (!end)
|
||||||
|
@ -383,7 +387,6 @@ namespace JianGongYun.TRTC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//BackgroundFrame.SetTo(backColor);
|
|
||||||
if (liveWinMode.ScreenRunning)//屏幕分享中
|
if (liveWinMode.ScreenRunning)//屏幕分享中
|
||||||
{
|
{
|
||||||
if (onlyCameraInit)
|
if (onlyCameraInit)
|
||||||
|
@ -396,7 +399,7 @@ namespace JianGongYun.TRTC
|
||||||
{
|
{
|
||||||
goto Skip1;//图像数据不正常直接跳过
|
goto Skip1;//图像数据不正常直接跳过
|
||||||
}
|
}
|
||||||
SubFrame.CopyTo(screenRoi, screenMask);//屏幕分享和背景一样大,直接覆盖上去
|
SubFrame.CopyTo(screenRoi);//屏幕分享和背景一样大,直接覆盖上去
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -408,7 +411,7 @@ namespace JianGongYun.TRTC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Skip1:
|
Skip1:
|
||||||
|
|
||||||
if (liveWinMode.CameraRunning)//摄像头分享中
|
if (liveWinMode.CameraRunning)//摄像头分享中
|
||||||
{
|
{
|
||||||
|
@ -424,23 +427,27 @@ namespace JianGongYun.TRTC
|
||||||
if (liveWinMode.ScreenRunning)//屏幕分享中摄像头150正方形大小并悬浮再右下角
|
if (liveWinMode.ScreenRunning)//屏幕分享中摄像头150正方形大小并悬浮再右下角
|
||||||
{
|
{
|
||||||
dst = dst.Resize(new OpenCvSharp.Size(smallCameraSize, smallCameraSize), interpolation: InterpolationFlags.Area);
|
dst = dst.Resize(new OpenCvSharp.Size(smallCameraSize, smallCameraSize), interpolation: InterpolationFlags.Area);
|
||||||
dst.CopyTo(smallRoi, smallMask);
|
dst.Rectangle(new OpenCvSharp.Rect(0, 0, dst.Cols, dst.Rows), Scalar.FromRgb(239, 239, 239), 1);
|
||||||
|
dst.CopyTo(smallRoi);
|
||||||
}
|
}
|
||||||
else//只有摄像头,摄像头画面全屏正方形
|
else//只有摄像头,摄像头画面全屏正方形
|
||||||
{
|
{
|
||||||
dst = dst.Resize(new OpenCvSharp.Size(backHeight, backHeight), interpolation: InterpolationFlags.Linear);
|
dst = dst.Resize(new OpenCvSharp.Size(backHeight, backHeight), interpolation: InterpolationFlags.Linear);
|
||||||
var roi = new Mat(BackgroundFrame, new OpenCvSharp.Rect(0, 0, dst.Width, dst.Height));
|
dst.CopyTo(bigRoi);
|
||||||
dst.CopyTo(roi);
|
|
||||||
Cv2.ImShow("123", BackgroundFrame);
|
|
||||||
Cv2.WaitKey(2);
|
|
||||||
}
|
}
|
||||||
dst.Dispose();
|
dst.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Skip2:
|
Skip2:
|
||||||
|
|
||||||
|
|
||||||
|
//Cv2.ImShow("preview", BackgroundFrame);
|
||||||
|
//Cv2.WaitKey(1);
|
||||||
|
//BackgroundFrame.SaveImage(videoFrameTemp);
|
||||||
|
//var temp = Cv2.ImRead(videoFrameTemp);
|
||||||
|
var temp = BackgroundFrame.CvtColor(ColorConversionCodes.BGRA2BGR);
|
||||||
|
vw.Write(temp);
|
||||||
|
temp.Dispose();
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
Debug.Print($"video frame run {stopwatch.ElapsedMilliseconds}");
|
Debug.Print($"video frame run {stopwatch.ElapsedMilliseconds}");
|
||||||
var sleep = delay - (int)stopwatch.ElapsedMilliseconds;//每帧时间减去每帧处理时间为sleep时间
|
var sleep = delay - (int)stopwatch.ElapsedMilliseconds;//每帧时间减去每帧处理时间为sleep时间
|
||||||
|
@ -454,83 +461,12 @@ namespace JianGongYun.TRTC
|
||||||
Thread.Sleep(sleep);
|
Thread.Sleep(sleep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BackgroundFrame?.Dispose();
|
||||||
|
BackgroundFrame = null;
|
||||||
|
vw.Dispose();
|
||||||
|
Debug.Print("录制结束");
|
||||||
}, TaskCreationOptions.LongRunning);//新开线程
|
}, TaskCreationOptions.LongRunning);//新开线程
|
||||||
|
|
||||||
//Stopwatch sw1 = new Stopwatch();
|
|
||||||
//Stopwatch sw2 = new Stopwatch();
|
|
||||||
//ConcurrentQueue<Mat> bitmaps = new ConcurrentQueue<Mat>();
|
|
||||||
//view.OnRenderVideoFrameHandler += (b) =>
|
|
||||||
//{
|
|
||||||
// sw1.Restart();
|
|
||||||
// bitmaps.Enqueue(b.ToMat());
|
|
||||||
// sw1.Stop();
|
|
||||||
// //Debug.Print("a" + sw1.Elapsed.TotalMilliseconds.ToString());
|
|
||||||
//};
|
|
||||||
////view.OnRenderVideoFrameHandler1 += (a, b, c) =>
|
|
||||||
////{
|
|
||||||
//// var bb = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(a[0]) * a.Length);
|
|
||||||
//// System.Runtime.InteropServices.Marshal.Copy(a, 0, bb, a.Length);
|
|
||||||
//// var mat = new Mat(c, b, MatType.CV_32SC4, bb);
|
|
||||||
//// mat.SaveImage("1.bmp");
|
|
||||||
////};
|
|
||||||
////view.OnViewRemove += () =>
|
|
||||||
////{
|
|
||||||
//// end = true;
|
|
||||||
////};
|
|
||||||
//var task = Task.Factory.StartNew(() =>
|
|
||||||
//{
|
|
||||||
// Console.WriteLine($"VideoRecordTask 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();
|
|
||||||
// bool videoWriterInit = false;
|
|
||||||
// var frameCount = 0;
|
|
||||||
// Timer timer = new Timer((a) =>
|
|
||||||
// {
|
|
||||||
// //Console.WriteLine($"{streamType} fps {frameCount}");
|
|
||||||
// Debug.Print($"{streamType} fps {frameCount}");
|
|
||||||
// Interlocked.Exchange(ref frameCount, 0);
|
|
||||||
// }, null, 0, 1000);
|
|
||||||
// while (!end || bitmaps.Count > 0)
|
|
||||||
// {
|
|
||||||
// if (bitmaps.Count == 0)
|
|
||||||
// {
|
|
||||||
// Thread.Sleep(100);
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// if (bitmaps.TryDequeue(out var mat))
|
|
||||||
// {
|
|
||||||
// sw2.Restart();
|
|
||||||
// //mat.SaveImage(imgTemp);
|
|
||||||
// //mat.Dispose();
|
|
||||||
// //mat = Cv2.ImRead(imgTemp, ImreadModes.AnyColor);
|
|
||||||
// //Cv2.ImShow(streamType.ToString(), mat);
|
|
||||||
// //Cv2.WaitKey(1);
|
|
||||||
// if (!videoWriterInit)
|
|
||||||
// {
|
|
||||||
// vw.Open(videoFile, FourCC.H264, settingWindowViewModel.LiveFps, mat.Size());
|
|
||||||
// videoWriterInit = true;
|
|
||||||
// }
|
|
||||||
// vw.Write(mat);
|
|
||||||
// mat.Dispose();
|
|
||||||
// Interlocked.Increment(ref frameCount);
|
|
||||||
// //Debug.Print("b"+sw2.Elapsed.TotalMilliseconds.ToString());
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// Thread.Sleep(100);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// vw?.Release();
|
|
||||||
// vw?.Dispose();
|
|
||||||
// if (File.Exists(imgTemp))
|
|
||||||
// {
|
|
||||||
// File.Delete(imgTemp);
|
|
||||||
// }
|
|
||||||
// timer.Dispose();
|
|
||||||
// Console.WriteLine($"VideoRecordTask End {streamType}");
|
|
||||||
//}, TaskCreationOptions.LongRunning);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -33,30 +33,13 @@ namespace JianGongYun.TRTC.Windows
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
NoticeManager.Initialize();
|
NoticeManager.Initialize();
|
||||||
//BeforeLiveSubViewWrap.SizeChanged += BeforeLiveSubViewWrap_SizeChanged;
|
//AttachConsole(-1);//把进程挂在控制台,通过命令行启动程序可以看到控制台输出
|
||||||
//AfterLiveSubViewWrap.SizeChanged += AfterLiveSubViewWrap_SizeChanged;
|
|
||||||
AttachConsole(-1);//把进程挂在控制台,通过命令行启动程序可以看到控制台输出
|
|
||||||
LiveWindowViewModel = new ViewModels.LiveWindowViewModel();
|
LiveWindowViewModel = new ViewModels.LiveWindowViewModel();
|
||||||
SettingWindowViewModel = ViewModels.SettingWindowViewModel.GetInstance();
|
SettingWindowViewModel = ViewModels.SettingWindowViewModel.GetInstance();
|
||||||
this.DataContext = LiveWindowViewModel;
|
this.DataContext = LiveWindowViewModel;
|
||||||
BorderBrush = new SolidColorBrush(color: Color.FromRgb(42, 43, 48));//窗口标题背景颜色
|
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)));
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,6 +94,7 @@ namespace JianGongYun.TRTC.Windows
|
||||||
base.OnClosing(e);
|
base.OnClosing(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Action onEnd = default;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 开始/结束直播
|
/// 开始/结束直播
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -120,7 +104,6 @@ namespace JianGongYun.TRTC.Windows
|
||||||
{
|
{
|
||||||
var btn = sender as AduFlatButton;
|
var btn = sender as AduFlatButton;
|
||||||
var start = Convert.ToBoolean(btn.Tag);
|
var start = Convert.ToBoolean(btn.Tag);
|
||||||
Action onEnd = default;
|
|
||||||
if (start)//开始直播
|
if (start)//开始直播
|
||||||
{
|
{
|
||||||
if (SettingWindowViewModel.DiskSize <= ViewModels.SettingWindowViewModel.DiskWarningSize)
|
if (SettingWindowViewModel.DiskSize <= ViewModels.SettingWindowViewModel.DiskWarningSize)
|
||||||
|
|
Loading…
Reference in New Issue