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(); } } }