diff --git a/CameraStream.cs b/CameraStream.cs
index 2da6a35..b27d01e 100644
--- a/CameraStream.cs
+++ b/CameraStream.cs
@@ -12,12 +12,20 @@ namespace IPCamAppBar
public Image Image { get; set; }
}
+ public class StreamExceptionEventArgs : EventArgs
+ {
+ public Exception Exception { get; set; }
+ }
+
+
public delegate void FrameEvent(object sender, FrameEventArgs args);
+ public delegate void StreamExceptionEvent(object sender, StreamExceptionEventArgs args);
internal abstract class CameraStream : IDisposable
{
public event FrameEvent Frame;
+ public event StreamExceptionEvent StreamException;
private readonly CancellationTokenSource cancelTaskTokenSource = new CancellationTokenSource();
private Task streamTask;
@@ -57,6 +65,8 @@ namespace IPCamAppBar
request.Credentials = new NetworkCredential(parts[0], parts.Length > 1 ? parts[1] : "");
}
+ request.ReadWriteTimeout = 10;
+
try
{
HttpWebResponse response;
@@ -83,7 +93,11 @@ namespace IPCamAppBar
if (cancellationToken.IsCancellationRequested)
break;
- // TODO onException
+ OnStreamException(new StreamExceptionEventArgs
+ {
+ Exception = e
+ });
+
await Task.Delay(5000, cancellationToken);
}
}
@@ -97,6 +111,12 @@ namespace IPCamAppBar
{
Frame?.Invoke(this, args);
}
+
+
+ protected virtual void OnStreamException(StreamExceptionEventArgs args)
+ {
+ StreamException?.Invoke(this, args);
+ }
}
diff --git a/CameraView.Designer.cs b/CameraView.Designer.cs
index e4ca926..7a3d2d9 100644
--- a/CameraView.Designer.cs
+++ b/CameraView.Designer.cs
@@ -28,9 +28,11 @@
///
private void InitializeComponent()
{
+ this.components = new System.ComponentModel.Container();
this.ConnectingLabel = new System.Windows.Forms.Label();
this.StreamView = new System.Windows.Forms.PictureBox();
- this.NoDataLabel = new System.Windows.Forms.Label();
+ this.IssueLabel = new System.Windows.Forms.Label();
+ this.NoDataTimer = new System.Windows.Forms.Timer(this.components);
((System.ComponentModel.ISupportInitialize)(this.StreamView)).BeginInit();
this.SuspendLayout();
//
@@ -57,26 +59,31 @@
this.StreamView.TabStop = false;
this.StreamView.Visible = false;
//
- // NoDataLabel
+ // IssueLabel
//
- this.NoDataLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
+ this.IssueLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
- this.NoDataLabel.BackColor = System.Drawing.Color.Black;
- this.NoDataLabel.ForeColor = System.Drawing.Color.DarkRed;
- this.NoDataLabel.Location = new System.Drawing.Point(0, 129);
- this.NoDataLabel.Name = "NoDataLabel";
- this.NoDataLabel.Size = new System.Drawing.Size(150, 21);
- this.NoDataLabel.TabIndex = 2;
- this.NoDataLabel.Text = "No data for x seconds";
- this.NoDataLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.NoDataLabel.Visible = false;
+ this.IssueLabel.BackColor = System.Drawing.Color.Black;
+ this.IssueLabel.ForeColor = System.Drawing.Color.DarkRed;
+ this.IssueLabel.Location = new System.Drawing.Point(0, 0);
+ this.IssueLabel.Name = "IssueLabel";
+ this.IssueLabel.Size = new System.Drawing.Size(150, 21);
+ this.IssueLabel.TabIndex = 2;
+ this.IssueLabel.Text = "Someone set up us the bomb";
+ this.IssueLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ this.IssueLabel.Visible = false;
+ //
+ // NoDataTimer
+ //
+ this.NoDataTimer.Interval = 1000;
+ this.NoDataTimer.Tick += new System.EventHandler(this.NoDataTimer_Tick);
//
// CameraView
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Gray;
- this.Controls.Add(this.NoDataLabel);
+ this.Controls.Add(this.IssueLabel);
this.Controls.Add(this.StreamView);
this.Controls.Add(this.ConnectingLabel);
this.Margin = new System.Windows.Forms.Padding(0);
@@ -90,6 +97,7 @@
private System.Windows.Forms.Label ConnectingLabel;
private System.Windows.Forms.PictureBox StreamView;
- private System.Windows.Forms.Label NoDataLabel;
+ private System.Windows.Forms.Label IssueLabel;
+ private System.Windows.Forms.Timer NoDataTimer;
}
}
diff --git a/CameraView.cs b/CameraView.cs
index 24dcb0c..00a5d16 100644
--- a/CameraView.cs
+++ b/CameraView.cs
@@ -9,8 +9,7 @@ namespace IPCamAppBar
public partial class CameraView : UserControl
{
private DateTime lastFrameTime;
- private Timer noDataTimer;
-
+
public CameraView(string url)
{
@@ -18,22 +17,15 @@ namespace IPCamAppBar
var cameraStream = new CameraMJPEGStream();
cameraStream.Frame += CameraStreamOnFrame;
+ cameraStream.StreamException += CameraStreamOnStreamException;
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
@@ -45,10 +37,10 @@ namespace IPCamAppBar
ConnectingLabel.Visible = false;
StreamView.Visible = true;
- NoDataLabel.Visible = false;
+ IssueLabel.Visible = false;
lastFrameTime = DateTime.Now;
- noDataTimer.Start();
+ NoDataTimer.Start();
var viewImage = new Bitmap(Width, Height);
using (var graphics = Graphics.FromImage(viewImage))
@@ -86,14 +78,23 @@ namespace IPCamAppBar
}
- private void CheckNoData(object sender, EventArgs e)
+ private void CameraStreamOnStreamException(object sender, StreamExceptionEventArgs args)
+ {
+ 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;
- NoDataLabel.Text = $@"No data for {timeSinceLastFrame.TotalSeconds} seconds";
- NoDataLabel.Visible = true;
+ IssueLabel.Text = $@"No data for {(int)timeSinceLastFrame.TotalSeconds} seconds";
+ IssueLabel.Visible = true;
+ IssueLabel.BringToFront();
}
}
}
diff --git a/CameraView.resx b/CameraView.resx
index 1af7de1..0c1ffce 100644
--- a/CameraView.resx
+++ b/CameraView.resx
@@ -117,4 +117,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ 17, 17
+
\ No newline at end of file
diff --git a/MainForm.Designer.cs b/MainForm.Designer.cs
index f265fd7..f2906d1 100644
--- a/MainForm.Designer.cs
+++ b/MainForm.Designer.cs
@@ -28,18 +28,36 @@
///
private void InitializeComponent()
{
+ this.components = new System.ComponentModel.Container();
this.CameraViewContainer = new System.Windows.Forms.FlowLayoutPanel();
+ this.DefaultContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.DefaultContextMenu.SuspendLayout();
this.SuspendLayout();
//
// CameraViewContainer
//
+ this.CameraViewContainer.ContextMenuStrip = this.DefaultContextMenu;
this.CameraViewContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.CameraViewContainer.Location = new System.Drawing.Point(0, 0);
this.CameraViewContainer.Margin = new System.Windows.Forms.Padding(0);
this.CameraViewContainer.Name = "CameraViewContainer";
this.CameraViewContainer.Size = new System.Drawing.Size(269, 211);
this.CameraViewContainer.TabIndex = 0;
- this.CameraViewContainer.Click += new System.EventHandler(this.CameraViewContainer_Click);
+ //
+ // DefaultContextMenu
+ //
+ this.DefaultContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.closeToolStripMenuItem});
+ this.DefaultContextMenu.Name = "ContextMenu";
+ this.DefaultContextMenu.Size = new System.Drawing.Size(181, 48);
+ //
+ // closeToolStripMenuItem
+ //
+ this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
+ this.closeToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
+ this.closeToolStripMenuItem.Text = "&Close";
+ this.closeToolStripMenuItem.Click += new System.EventHandler(this.CloseToolStripMenuItem_Click);
//
// MainForm
//
@@ -53,6 +71,7 @@
this.ShowInTaskbar = false;
this.Text = "IPCam AppBar";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MainForm_FormClosed);
+ this.DefaultContextMenu.ResumeLayout(false);
this.ResumeLayout(false);
}
@@ -60,6 +79,8 @@
#endregion
private System.Windows.Forms.FlowLayoutPanel CameraViewContainer;
+ private System.Windows.Forms.ContextMenuStrip DefaultContextMenu;
+ private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
}
}
diff --git a/MainForm.cs b/MainForm.cs
index 25cb2d5..b03ce03 100644
--- a/MainForm.cs
+++ b/MainForm.cs
@@ -85,9 +85,9 @@ namespace IPCamAppBar
}
- private void CameraViewContainer_Click(object sender, EventArgs e)
+ private void CloseToolStripMenuItem_Click(object sender, EventArgs e)
{
- //Close();
+ Close();
}
}
}
diff --git a/MainForm.resx b/MainForm.resx
index 1af7de1..fbef4e5 100644
--- a/MainForm.resx
+++ b/MainForm.resx
@@ -117,4 +117,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ 17, 17
+
\ No newline at end of file