This commit is contained in:
lxmou666 2021-01-05 21:55:48 +08:00
parent 6fdfc0db76
commit 98dd3da915
2 changed files with 40 additions and 121 deletions

View File

@ -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>

View File

@ -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)