Fixed errors not showing up
Set timeout for the stream to 10 seconds instead of the default 5 minutes Added Close menu
This commit is contained in:
parent
8f61224777
commit
c334b7fdac
@ -12,12 +12,20 @@ namespace IPCamAppBar
|
|||||||
public Image Image { get; set; }
|
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 FrameEvent(object sender, FrameEventArgs args);
|
||||||
|
public delegate void StreamExceptionEvent(object sender, StreamExceptionEventArgs args);
|
||||||
|
|
||||||
|
|
||||||
internal abstract class CameraStream : IDisposable
|
internal abstract class CameraStream : IDisposable
|
||||||
{
|
{
|
||||||
public event FrameEvent Frame;
|
public event FrameEvent Frame;
|
||||||
|
public event StreamExceptionEvent StreamException;
|
||||||
|
|
||||||
private readonly CancellationTokenSource cancelTaskTokenSource = new CancellationTokenSource();
|
private readonly CancellationTokenSource cancelTaskTokenSource = new CancellationTokenSource();
|
||||||
private Task streamTask;
|
private Task streamTask;
|
||||||
@ -57,6 +65,8 @@ namespace IPCamAppBar
|
|||||||
request.Credentials = new NetworkCredential(parts[0], parts.Length > 1 ? parts[1] : "");
|
request.Credentials = new NetworkCredential(parts[0], parts.Length > 1 ? parts[1] : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request.ReadWriteTimeout = 10;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HttpWebResponse response;
|
HttpWebResponse response;
|
||||||
@ -83,7 +93,11 @@ namespace IPCamAppBar
|
|||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// TODO onException
|
OnStreamException(new StreamExceptionEventArgs
|
||||||
|
{
|
||||||
|
Exception = e
|
||||||
|
});
|
||||||
|
|
||||||
await Task.Delay(5000, cancellationToken);
|
await Task.Delay(5000, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,6 +111,12 @@ namespace IPCamAppBar
|
|||||||
{
|
{
|
||||||
Frame?.Invoke(this, args);
|
Frame?.Invoke(this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected virtual void OnStreamException(StreamExceptionEventArgs args)
|
||||||
|
{
|
||||||
|
StreamException?.Invoke(this, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
36
CameraView.Designer.cs
generated
36
CameraView.Designer.cs
generated
@ -28,9 +28,11 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
this.ConnectingLabel = new System.Windows.Forms.Label();
|
this.ConnectingLabel = new System.Windows.Forms.Label();
|
||||||
this.StreamView = new System.Windows.Forms.PictureBox();
|
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();
|
((System.ComponentModel.ISupportInitialize)(this.StreamView)).BeginInit();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
@ -57,26 +59,31 @@
|
|||||||
this.StreamView.TabStop = false;
|
this.StreamView.TabStop = false;
|
||||||
this.StreamView.Visible = 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)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.NoDataLabel.BackColor = System.Drawing.Color.Black;
|
this.IssueLabel.BackColor = System.Drawing.Color.Black;
|
||||||
this.NoDataLabel.ForeColor = System.Drawing.Color.DarkRed;
|
this.IssueLabel.ForeColor = System.Drawing.Color.DarkRed;
|
||||||
this.NoDataLabel.Location = new System.Drawing.Point(0, 129);
|
this.IssueLabel.Location = new System.Drawing.Point(0, 0);
|
||||||
this.NoDataLabel.Name = "NoDataLabel";
|
this.IssueLabel.Name = "IssueLabel";
|
||||||
this.NoDataLabel.Size = new System.Drawing.Size(150, 21);
|
this.IssueLabel.Size = new System.Drawing.Size(150, 21);
|
||||||
this.NoDataLabel.TabIndex = 2;
|
this.IssueLabel.TabIndex = 2;
|
||||||
this.NoDataLabel.Text = "No data for x seconds";
|
this.IssueLabel.Text = "Someone set up us the bomb";
|
||||||
this.NoDataLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
this.IssueLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||||
this.NoDataLabel.Visible = false;
|
this.IssueLabel.Visible = false;
|
||||||
|
//
|
||||||
|
// NoDataTimer
|
||||||
|
//
|
||||||
|
this.NoDataTimer.Interval = 1000;
|
||||||
|
this.NoDataTimer.Tick += new System.EventHandler(this.NoDataTimer_Tick);
|
||||||
//
|
//
|
||||||
// CameraView
|
// CameraView
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.BackColor = System.Drawing.Color.Gray;
|
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.StreamView);
|
||||||
this.Controls.Add(this.ConnectingLabel);
|
this.Controls.Add(this.ConnectingLabel);
|
||||||
this.Margin = new System.Windows.Forms.Padding(0);
|
this.Margin = new System.Windows.Forms.Padding(0);
|
||||||
@ -90,6 +97,7 @@
|
|||||||
|
|
||||||
private System.Windows.Forms.Label ConnectingLabel;
|
private System.Windows.Forms.Label ConnectingLabel;
|
||||||
private System.Windows.Forms.PictureBox StreamView;
|
private System.Windows.Forms.PictureBox StreamView;
|
||||||
private System.Windows.Forms.Label NoDataLabel;
|
private System.Windows.Forms.Label IssueLabel;
|
||||||
|
private System.Windows.Forms.Timer NoDataTimer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,7 @@ namespace IPCamAppBar
|
|||||||
public partial class CameraView : UserControl
|
public partial class CameraView : UserControl
|
||||||
{
|
{
|
||||||
private DateTime lastFrameTime;
|
private DateTime lastFrameTime;
|
||||||
private Timer noDataTimer;
|
|
||||||
|
|
||||||
|
|
||||||
public CameraView(string url)
|
public CameraView(string url)
|
||||||
{
|
{
|
||||||
@ -18,22 +17,15 @@ namespace IPCamAppBar
|
|||||||
|
|
||||||
var cameraStream = new CameraMJPEGStream();
|
var cameraStream = new CameraMJPEGStream();
|
||||||
cameraStream.Frame += CameraStreamOnFrame;
|
cameraStream.Frame += CameraStreamOnFrame;
|
||||||
|
cameraStream.StreamException += CameraStreamOnStreamException;
|
||||||
cameraStream.Start(url);
|
cameraStream.Start(url);
|
||||||
|
|
||||||
noDataTimer = new Timer
|
|
||||||
{
|
|
||||||
Interval = 1000
|
|
||||||
};
|
|
||||||
noDataTimer.Tick += CheckNoData;
|
|
||||||
|
|
||||||
Disposed += (sender, args) =>
|
Disposed += (sender, args) =>
|
||||||
{
|
{
|
||||||
noDataTimer?.Dispose();
|
|
||||||
cameraStream?.Dispose();
|
cameraStream?.Dispose();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void CameraStreamOnFrame(object sender, FrameEventArgs args)
|
private void CameraStreamOnFrame(object sender, FrameEventArgs args)
|
||||||
{
|
{
|
||||||
// The event comes from a background thread, so if needed invoke it on the main thread
|
// 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;
|
ConnectingLabel.Visible = false;
|
||||||
StreamView.Visible = true;
|
StreamView.Visible = true;
|
||||||
NoDataLabel.Visible = false;
|
IssueLabel.Visible = false;
|
||||||
|
|
||||||
lastFrameTime = DateTime.Now;
|
lastFrameTime = DateTime.Now;
|
||||||
noDataTimer.Start();
|
NoDataTimer.Start();
|
||||||
|
|
||||||
var viewImage = new Bitmap(Width, Height);
|
var viewImage = new Bitmap(Width, Height);
|
||||||
using (var graphics = Graphics.FromImage(viewImage))
|
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;
|
var timeSinceLastFrame = DateTime.Now - lastFrameTime;
|
||||||
if (timeSinceLastFrame.TotalSeconds < 10)
|
if (timeSinceLastFrame.TotalSeconds < 10)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
NoDataLabel.Text = $@"No data for {timeSinceLastFrame.TotalSeconds} seconds";
|
IssueLabel.Text = $@"No data for {(int)timeSinceLastFrame.TotalSeconds} seconds";
|
||||||
NoDataLabel.Visible = true;
|
IssueLabel.Visible = true;
|
||||||
|
IssueLabel.BringToFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,4 +117,7 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<metadata name="NoDataTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
</root>
|
</root>
|
23
MainForm.Designer.cs
generated
23
MainForm.Designer.cs
generated
@ -28,18 +28,36 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
this.CameraViewContainer = new System.Windows.Forms.FlowLayoutPanel();
|
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();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// CameraViewContainer
|
// CameraViewContainer
|
||||||
//
|
//
|
||||||
|
this.CameraViewContainer.ContextMenuStrip = this.DefaultContextMenu;
|
||||||
this.CameraViewContainer.Dock = System.Windows.Forms.DockStyle.Fill;
|
this.CameraViewContainer.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
this.CameraViewContainer.Location = new System.Drawing.Point(0, 0);
|
this.CameraViewContainer.Location = new System.Drawing.Point(0, 0);
|
||||||
this.CameraViewContainer.Margin = new System.Windows.Forms.Padding(0);
|
this.CameraViewContainer.Margin = new System.Windows.Forms.Padding(0);
|
||||||
this.CameraViewContainer.Name = "CameraViewContainer";
|
this.CameraViewContainer.Name = "CameraViewContainer";
|
||||||
this.CameraViewContainer.Size = new System.Drawing.Size(269, 211);
|
this.CameraViewContainer.Size = new System.Drawing.Size(269, 211);
|
||||||
this.CameraViewContainer.TabIndex = 0;
|
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
|
// MainForm
|
||||||
//
|
//
|
||||||
@ -53,6 +71,7 @@
|
|||||||
this.ShowInTaskbar = false;
|
this.ShowInTaskbar = false;
|
||||||
this.Text = "IPCam AppBar";
|
this.Text = "IPCam AppBar";
|
||||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MainForm_FormClosed);
|
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MainForm_FormClosed);
|
||||||
|
this.DefaultContextMenu.ResumeLayout(false);
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -60,6 +79,8 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private System.Windows.Forms.FlowLayoutPanel CameraViewContainer;
|
private System.Windows.Forms.FlowLayoutPanel CameraViewContainer;
|
||||||
|
private System.Windows.Forms.ContextMenuStrip DefaultContextMenu;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,9 +85,9 @@ namespace IPCamAppBar
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void CameraViewContainer_Click(object sender, EventArgs e)
|
private void CloseToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
//Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,4 +117,7 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<metadata name="DefaultContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
</root>
|
</root>
|
Loading…
Reference in New Issue
Block a user