100 lines
3.1 KiB
C#
100 lines
3.1 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Windows.Forms;
|
|
using DateTime = System.DateTime;
|
|
|
|
namespace IPCamAppBar
|
|
{
|
|
public partial class CameraView : UserControl
|
|
{
|
|
private DateTime lastFrameTime;
|
|
private Timer noDataTimer;
|
|
|
|
|
|
public CameraView(string url)
|
|
{
|
|
InitializeComponent();
|
|
|
|
var cameraStream = new CameraMJPEGStream();
|
|
cameraStream.Frame += CameraStreamOnFrame;
|
|
cameraStream.Start(url);
|
|
|
|
noDataTimer = new Timer
|
|
{
|
|
Interval = 1000
|
|
};
|
|
noDataTimer.Tick += CheckNoData;
|
|
|
|
Disposed += (sender, args) =>
|
|
{
|
|
noDataTimer?.Dispose();
|
|
cameraStream?.Dispose();
|
|
};
|
|
}
|
|
|
|
|
|
private void CameraStreamOnFrame(object sender, FrameEventArgs args)
|
|
{
|
|
// The event comes from a background thread, so if needed invoke it on the main thread
|
|
if (InvokeRequired)
|
|
{
|
|
Invoke(new Action(() => { CameraStreamOnFrame(sender, args); }));
|
|
return;
|
|
}
|
|
|
|
ConnectingLabel.Visible = false;
|
|
StreamView.Visible = true;
|
|
NoDataLabel.Visible = false;
|
|
|
|
lastFrameTime = DateTime.Now;
|
|
noDataTimer.Start();
|
|
|
|
var viewImage = new Bitmap(Width, Height);
|
|
using (var graphics = Graphics.FromImage(viewImage))
|
|
{
|
|
graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
|
|
graphics.DrawImage(args.Image, 0, 0, viewImage.Width, viewImage.Height);
|
|
|
|
using (var path = new GraphicsPath())
|
|
{
|
|
path.AddString(
|
|
lastFrameTime.ToString("G"),
|
|
FontFamily.GenericSansSerif,
|
|
(int)FontStyle.Regular,
|
|
graphics.DpiY * 14 / 72,
|
|
Rectangle.Inflate(new Rectangle(0, 0, viewImage.Width, viewImage.Height), -4, -4),
|
|
new StringFormat
|
|
{
|
|
Alignment = StringAlignment.Far,
|
|
LineAlignment = StringAlignment.Far
|
|
});
|
|
|
|
graphics.DrawPath(new Pen(Color.Black, 3), path);
|
|
graphics.FillPath(Brushes.White, path);
|
|
}
|
|
|
|
graphics.Flush();
|
|
}
|
|
|
|
var oldImage = StreamView.Image;
|
|
StreamView.Image = viewImage;
|
|
oldImage?.Dispose();
|
|
}
|
|
|
|
|
|
private void CheckNoData(object sender, EventArgs e)
|
|
{
|
|
var timeSinceLastFrame = DateTime.Now - lastFrameTime;
|
|
if (timeSinceLastFrame.TotalSeconds < 10)
|
|
return;
|
|
|
|
NoDataLabel.Text = $@"No data for {timeSinceLastFrame.TotalSeconds} seconds";
|
|
NoDataLabel.Visible = true;
|
|
}
|
|
}
|
|
}
|