Pause video feed while the computer is locked
This commit is contained in:
parent
6284bd0609
commit
3995ab92a2
17
IPCamAppBar/CameraView.Designer.cs
generated
17
IPCamAppBar/CameraView.Designer.cs
generated
@ -28,10 +28,13 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CameraView));
|
||||||
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.IssueLabel = new System.Windows.Forms.Label();
|
this.IssueLabel = new System.Windows.Forms.Label();
|
||||||
|
this.PausedOverlay = new System.Windows.Forms.PictureBox();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.StreamView)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.StreamView)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.PausedOverlay)).BeginInit();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// ConnectingLabel
|
// ConnectingLabel
|
||||||
@ -71,17 +74,30 @@
|
|||||||
this.IssueLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
this.IssueLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||||
this.IssueLabel.Visible = false;
|
this.IssueLabel.Visible = false;
|
||||||
//
|
//
|
||||||
|
// PausedOverlay
|
||||||
|
//
|
||||||
|
this.PausedOverlay.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.PausedOverlay.Image = ((System.Drawing.Image)(resources.GetObject("PausedOverlay.Image")));
|
||||||
|
this.PausedOverlay.Location = new System.Drawing.Point(19, 40);
|
||||||
|
this.PausedOverlay.Name = "PausedOverlay";
|
||||||
|
this.PausedOverlay.Size = new System.Drawing.Size(64, 64);
|
||||||
|
this.PausedOverlay.TabIndex = 3;
|
||||||
|
this.PausedOverlay.TabStop = false;
|
||||||
|
this.PausedOverlay.Visible = false;
|
||||||
|
//
|
||||||
// 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.PausedOverlay);
|
||||||
this.Controls.Add(this.IssueLabel);
|
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);
|
||||||
this.Name = "CameraView";
|
this.Name = "CameraView";
|
||||||
((System.ComponentModel.ISupportInitialize)(this.StreamView)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.StreamView)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.PausedOverlay)).EndInit();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -91,5 +107,6 @@
|
|||||||
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 IssueLabel;
|
private System.Windows.Forms.Label IssueLabel;
|
||||||
|
private System.Windows.Forms.PictureBox PausedOverlay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
@ -11,25 +12,40 @@ namespace IPCamAppBar
|
|||||||
{
|
{
|
||||||
public partial class CameraView : UserControl, IRetryableCameraObserver
|
public partial class CameraView : UserControl, IRetryableCameraObserver
|
||||||
{
|
{
|
||||||
|
private readonly ICamera camera;
|
||||||
private readonly bool overlayDateTime;
|
private readonly bool overlayDateTime;
|
||||||
private Bitmap viewBitmap;
|
private Bitmap viewBitmap;
|
||||||
|
private CancellationTokenSource streamCancellationTokenSource;
|
||||||
|
|
||||||
public CameraView(ICamera camera, bool overlayDateTime)
|
public CameraView(ICamera camera, bool overlayDateTime)
|
||||||
{
|
{
|
||||||
|
this.camera = camera;
|
||||||
this.overlayDateTime = overlayDateTime;
|
this.overlayDateTime = overlayDateTime;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
var streamCancellationTokenSource = new CancellationTokenSource();
|
StartCamera();
|
||||||
|
|
||||||
|
Disposed += (_, _) =>
|
||||||
|
{
|
||||||
|
StopCamera();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartCamera()
|
||||||
|
{
|
||||||
|
streamCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var retryableCamera = new RetryableCamera(camera);
|
var retryableCamera = new RetryableCamera(camera);
|
||||||
await retryableCamera.Fetch(this, streamCancellationTokenSource.Token);
|
await retryableCamera.Fetch(this, streamCancellationTokenSource.Token);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Disposed += (_, _) =>
|
|
||||||
{
|
private void StopCamera()
|
||||||
streamCancellationTokenSource.Cancel();
|
{
|
||||||
};
|
streamCancellationTokenSource.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -37,6 +53,9 @@ namespace IPCamAppBar
|
|||||||
|
|
||||||
public Task OnFrame(Image image)
|
public Task OnFrame(Image image)
|
||||||
{
|
{
|
||||||
|
if (streamCancellationTokenSource.IsCancellationRequested)
|
||||||
|
return Task.CompletedTask;
|
||||||
|
|
||||||
if (overlayDateTime || image is not Bitmap bitmap || image.Width != Width || image.Height != Height)
|
if (overlayDateTime || image is not Bitmap bitmap || image.Width != Width || image.Height != Height)
|
||||||
{
|
{
|
||||||
resizedBitmap ??= new Bitmap(Width, Height);
|
resizedBitmap ??= new Bitmap(Width, Height);
|
||||||
@ -100,6 +119,7 @@ namespace IPCamAppBar
|
|||||||
ConnectingLabel.Visible = false;
|
ConnectingLabel.Visible = false;
|
||||||
StreamView.Visible = true;
|
StreamView.Visible = true;
|
||||||
IssueLabel.Visible = false;
|
IssueLabel.Visible = false;
|
||||||
|
PausedOverlay.Visible = false;
|
||||||
|
|
||||||
|
|
||||||
if (viewBitmap == null)
|
if (viewBitmap == null)
|
||||||
@ -130,12 +150,28 @@ namespace IPCamAppBar
|
|||||||
|
|
||||||
private void InvokeDisconnected(Exception exception, TimeSpan retryDelay)
|
private void InvokeDisconnected(Exception exception, TimeSpan retryDelay)
|
||||||
{
|
{
|
||||||
if (IsDisposed)
|
if (IsDisposed || streamCancellationTokenSource.IsCancellationRequested)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IssueLabel.Text = (exception?.Message ?? "Camera disconnected") + $", retrying in {retryDelay.TotalSeconds} seconds";
|
IssueLabel.Text = (exception?.Message ?? "Camera disconnected") + $", retrying in {retryDelay.TotalSeconds} seconds";
|
||||||
IssueLabel.Visible = true;
|
IssueLabel.Visible = true;
|
||||||
IssueLabel.BringToFront();
|
IssueLabel.BringToFront();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SetPaused(bool pause)
|
||||||
|
{
|
||||||
|
if (pause)
|
||||||
|
{
|
||||||
|
StopCamera();
|
||||||
|
|
||||||
|
PausedOverlay.Left = (Width - PausedOverlay.Width) / 2;
|
||||||
|
PausedOverlay.Top = (Height - PausedOverlay.Height) / 2;
|
||||||
|
PausedOverlay.Visible = true;
|
||||||
|
PausedOverlay.BringToFront();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
StartCamera();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,4 +117,18 @@
|
|||||||
<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>
|
||||||
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
<data name="PausedOverlay.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m
|
||||||
|
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAF8SURBVHhetc8xCsAAEALB/P/TF9PaSZiBrcXnvG/j
|
||||||
|
TxQfiD60RvGB6ENrFB+IPrRG8YHoQ2sUH4g+tEbxgehDaxQfiD60RvGB6ENrFB+IPrRG8YHoQ2sUH4g+
|
||||||
|
tEbxgehDaxQfiD60RvGB6ENrFB+IPrRG8YHoQ2sUH4g+tEbxgehDaxQfiD60RvGB6ENrFB+IPrRG8YHo
|
||||||
|
Q2sUH4g+tEbxgehDaxQfiD60RvGB6ENrFB+IPrRG8YHoQ2sUH4g+tEbxgehDaxQfiD60RvGB6ENrFB+I
|
||||||
|
PrRG8YHoQ2sUH4g+tEbxgehDaxQfiD60RvGB6ENrFB+IPrRG8YHoQ2sUH4g+tEbxgehDaxQfiD60RvGB
|
||||||
|
6ENrFB+IPrRG8YHoQ2sUH4g+tEbxgehDaxQfiD60RvGB6ENrFB+IPrRG8YHoQ2sUH4g+tEbxgehDaxQf
|
||||||
|
iD60RvGB6ENrFB+IPrRG8YHoQ2sUH4g+tEbxgehDaxQfiD60RvGB6ENrFB+IPrQG3b1Awcd2Z2RJDQAA
|
||||||
|
AABJRU5ErkJggg==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -5,6 +5,7 @@ using System.Reflection;
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using IPCamLib;
|
using IPCamLib;
|
||||||
using IPCamLib.Concrete;
|
using IPCamLib.Concrete;
|
||||||
|
using Microsoft.Win32;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace IPCamAppBar
|
namespace IPCamAppBar
|
||||||
@ -13,6 +14,7 @@ namespace IPCamAppBar
|
|||||||
{
|
{
|
||||||
private readonly Config config;
|
private readonly Config config;
|
||||||
private readonly AppBar appBar;
|
private readonly AppBar appBar;
|
||||||
|
private bool paused = false;
|
||||||
|
|
||||||
|
|
||||||
public MainForm()
|
public MainForm()
|
||||||
@ -39,6 +41,9 @@ namespace IPCamAppBar
|
|||||||
: FlowDirection.LeftToRight;
|
: FlowDirection.LeftToRight;
|
||||||
|
|
||||||
config.Cameras?.ForEach(AddCamera);
|
config.Cameras?.ForEach(AddCamera);
|
||||||
|
|
||||||
|
|
||||||
|
SystemEvents.SessionSwitch += SystemEventsOnSessionSwitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -65,15 +70,14 @@ namespace IPCamAppBar
|
|||||||
|
|
||||||
private static AppBarPosition GetAppBarPosition(ConfigSide side)
|
private static AppBarPosition GetAppBarPosition(ConfigSide side)
|
||||||
{
|
{
|
||||||
switch (side)
|
return side switch
|
||||||
{
|
{
|
||||||
case ConfigSide.Top: return AppBarPosition.Top;
|
ConfigSide.Top => AppBarPosition.Top,
|
||||||
case ConfigSide.Bottom: return AppBarPosition.Bottom;
|
ConfigSide.Bottom => AppBarPosition.Bottom,
|
||||||
case ConfigSide.Left: return AppBarPosition.Left;
|
ConfigSide.Left => AppBarPosition.Left,
|
||||||
case ConfigSide.Right: return AppBarPosition.Right;
|
ConfigSide.Right => AppBarPosition.Right,
|
||||||
default:
|
_ => throw new ArgumentOutOfRangeException(nameof(side), side, @"Invalid side value")
|
||||||
throw new ArgumentOutOfRangeException(nameof(side), side, @"Invalid side value");
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -113,5 +117,31 @@ namespace IPCamAppBar
|
|||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void SystemEventsOnSessionSwitch(object sender, SessionSwitchEventArgs e)
|
||||||
|
{
|
||||||
|
if (InvokeRequired)
|
||||||
|
{
|
||||||
|
Invoke(new Action(() => SystemEventsOnSessionSwitch(sender, e)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pause = e.Reason == SessionSwitchReason.ConsoleDisconnect ||
|
||||||
|
e.Reason == SessionSwitchReason.RemoteDisconnect ||
|
||||||
|
e.Reason == SessionSwitchReason.SessionLock ||
|
||||||
|
e.Reason == SessionSwitchReason.SessionLogoff;
|
||||||
|
|
||||||
|
if (pause == paused)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var control in CameraViewContainer.Controls)
|
||||||
|
{
|
||||||
|
if (control is CameraView cameraView)
|
||||||
|
cameraView.SetPaused(pause);
|
||||||
|
}
|
||||||
|
|
||||||
|
paused = pause;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
IPCamAppBar/Resources/Paused.png
Normal file
BIN
IPCamAppBar/Resources/Paused.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1018 B |
Loading…
Reference in New Issue
Block a user