IPCamAppBar/CameraView.cs
Mark van Renswoude 5e0513fc81 Open config file from executable directory regardless of working directory (fixes startup issue)
Fixed ExceptionEvent not invoking to main thread
Bit more exception handling while shutting down
2019-08-25 20:02:22 +02:00

107 lines
3.4 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;
public CameraView(string url)
{
InitializeComponent();
var cameraStream = new CameraMJPEGStream();
cameraStream.Frame += CameraStreamOnFrame;
cameraStream.StreamException += CameraStreamOnStreamException;
cameraStream.Start(url);
Disposed += (sender, args) =>
{
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;
IssueLabel.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 CameraStreamOnStreamException(object sender, StreamExceptionEventArgs args)
{
if (InvokeRequired)
{
Invoke(new Action(() => { CameraStreamOnStreamException(sender, args); }));
return;
}
IssueLabel.Text = args.Exception.Message;
IssueLabel.Visible = true;
IssueLabel.BringToFront();
}
private void NoDataTimer_Tick(object sender, EventArgs e)
{
var timeSinceLastFrame = DateTime.Now - lastFrameTime;
if (timeSinceLastFrame.TotalSeconds < 10)
return;
IssueLabel.Text = $@"No data for {(int)timeSinceLastFrame.TotalSeconds} seconds";
IssueLabel.Visible = true;
IssueLabel.BringToFront();
}
}
}