????
This commit is contained in:
parent
6fdfc0db76
commit
98dd3da915
|
@ -200,6 +200,10 @@ namespace JianGongYun.TRTC
|
|||
liveWinMode.CameraRunning = false;
|
||||
lTRTCCloud.stopLocalPreview();
|
||||
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;
|
||||
lTRTCCloud.stopScreenCapture();
|
||||
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)
|
||||
{
|
||||
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;
|
||||
onEnd = () =>
|
||||
{
|
||||
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 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 screenMask = new Mat(backHeight, backWidth, MatType.CV_8UC1, new Scalar(1));
|
||||
|
||||
//摄像头小画面定位
|
||||
var cameraMargin = 20;//右下角偏移量
|
||||
|
@ -355,11 +361,9 @@ namespace JianGongYun.TRTC
|
|||
var smallX = backWidth - smallCameraSize - cameraMargin;
|
||||
var smallY = backHeight - smallCameraSize - cameraMargin;
|
||||
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 bigMask = new Mat(backHeight, backHeight, MatType.CV_8UC1, new Scalar(1));
|
||||
|
||||
|
||||
while (!end)
|
||||
|
@ -383,7 +387,6 @@ namespace JianGongYun.TRTC
|
|||
}
|
||||
}
|
||||
|
||||
//BackgroundFrame.SetTo(backColor);
|
||||
if (liveWinMode.ScreenRunning)//屏幕分享中
|
||||
{
|
||||
if (onlyCameraInit)
|
||||
|
@ -396,7 +399,7 @@ namespace JianGongYun.TRTC
|
|||
{
|
||||
goto Skip1;//图像数据不正常直接跳过
|
||||
}
|
||||
SubFrame.CopyTo(screenRoi, screenMask);//屏幕分享和背景一样大,直接覆盖上去
|
||||
SubFrame.CopyTo(screenRoi);//屏幕分享和背景一样大,直接覆盖上去
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -408,7 +411,7 @@ namespace JianGongYun.TRTC
|
|||
}
|
||||
}
|
||||
|
||||
Skip1:
|
||||
Skip1:
|
||||
|
||||
if (liveWinMode.CameraRunning)//摄像头分享中
|
||||
{
|
||||
|
@ -424,23 +427,27 @@ namespace JianGongYun.TRTC
|
|||
if (liveWinMode.ScreenRunning)//屏幕分享中摄像头150正方形大小并悬浮再右下角
|
||||
{
|
||||
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//只有摄像头,摄像头画面全屏正方形
|
||||
{
|
||||
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(roi);
|
||||
Cv2.ImShow("123", BackgroundFrame);
|
||||
Cv2.WaitKey(2);
|
||||
dst.CopyTo(bigRoi);
|
||||
}
|
||||
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();
|
||||
Debug.Print($"video frame run {stopwatch.ElapsedMilliseconds}");
|
||||
var sleep = delay - (int)stopwatch.ElapsedMilliseconds;//每帧时间减去每帧处理时间为sleep时间
|
||||
|
@ -454,83 +461,12 @@ namespace JianGongYun.TRTC
|
|||
Thread.Sleep(sleep);
|
||||
}
|
||||
}
|
||||
BackgroundFrame?.Dispose();
|
||||
BackgroundFrame = null;
|
||||
vw.Dispose();
|
||||
Debug.Print("录制结束");
|
||||
}, 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>
|
||||
|
|
|
@ -33,30 +33,13 @@ namespace JianGongYun.TRTC.Windows
|
|||
{
|
||||
InitializeComponent();
|
||||
NoticeManager.Initialize();
|
||||
//BeforeLiveSubViewWrap.SizeChanged += BeforeLiveSubViewWrap_SizeChanged;
|
||||
//AfterLiveSubViewWrap.SizeChanged += AfterLiveSubViewWrap_SizeChanged;
|
||||
AttachConsole(-1);//把进程挂在控制台,通过命令行启动程序可以看到控制台输出
|
||||
//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)));
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
@ -111,6 +94,7 @@ namespace JianGongYun.TRTC.Windows
|
|||
base.OnClosing(e);
|
||||
}
|
||||
|
||||
static Action onEnd = default;
|
||||
/// <summary>
|
||||
/// 开始/结束直播
|
||||
/// </summary>
|
||||
|
@ -120,7 +104,6 @@ namespace JianGongYun.TRTC.Windows
|
|||
{
|
||||
var btn = sender as AduFlatButton;
|
||||
var start = Convert.ToBoolean(btn.Tag);
|
||||
Action onEnd = default;
|
||||
if (start)//开始直播
|
||||
{
|
||||
if (SettingWindowViewModel.DiskSize <= ViewModels.SettingWindowViewModel.DiskWarningSize)
|
||||
|
|
Loading…
Reference in New Issue