mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
Added auto image quality.
This commit is contained in:
parent
8a626e6406
commit
2b6a8bc342
@ -15,6 +15,7 @@ using Remotely.Shared.Win32;
|
||||
using Remotely.ScreenCast.Core.Interfaces;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
namespace Remotely.ScreenCast.Core.Capture
|
||||
{
|
||||
@ -72,16 +73,6 @@ namespace Remotely.ScreenCast.Core.Capture
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Conductor.Current.IsDebug)
|
||||
{
|
||||
while (fpsQueue.Any() && DateTime.Now - fpsQueue.Peek() > TimeSpan.FromSeconds(1))
|
||||
{
|
||||
fpsQueue.Dequeue();
|
||||
}
|
||||
fpsQueue.Enqueue(DateTime.Now);
|
||||
Debug.WriteLine("Capture FPS: " + fpsQueue.Count);
|
||||
}
|
||||
|
||||
if (OSUtils.IsWindows)
|
||||
{
|
||||
var currentDesktopName = Win32Interop.GetCurrentDesktop();
|
||||
@ -95,13 +86,14 @@ namespace Remotely.ScreenCast.Core.Capture
|
||||
}
|
||||
|
||||
|
||||
if (viewer.PendingFrames > 10)
|
||||
if (Conductor.Current.IsDebug)
|
||||
{
|
||||
Logger.Write($"Throttling screen capture. Latency: {viewer.Latency}. Pending Frames: {viewer.PendingFrames}");
|
||||
// This is to prevent dead-lock in case updates are missed from the browser.
|
||||
viewer.PendingFrames = Math.Max(0, viewer.PendingFrames - 1);
|
||||
await Task.Delay(10);
|
||||
continue;
|
||||
while (fpsQueue.Any() && DateTime.Now - fpsQueue.Peek() > TimeSpan.FromSeconds(1))
|
||||
{
|
||||
fpsQueue.Dequeue();
|
||||
}
|
||||
fpsQueue.Enqueue(DateTime.Now);
|
||||
Debug.WriteLine("Capture FPS: " + fpsQueue.Count);
|
||||
}
|
||||
|
||||
capturer.GetNextFrame();
|
||||
@ -120,12 +112,27 @@ namespace Remotely.ScreenCast.Core.Capture
|
||||
capturer.CaptureFullscreen = false;
|
||||
}
|
||||
|
||||
encodedImageBytes = ImageUtils.EncodeBitmap(newImage, viewer.EncoderParams);
|
||||
if (viewer.AutoAdjustQuality && viewer.Latency > 1000)
|
||||
{
|
||||
var quality = (int)(viewer.ImageQuality * 1000 / viewer.Latency);
|
||||
Logger.Write($"Auto-adjusting image quality. Latency: {viewer.Latency}. Quality: {quality}");
|
||||
encodedImageBytes = ImageUtils.EncodeBitmap(newImage, new EncoderParameters()
|
||||
{
|
||||
Param = new[]
|
||||
{
|
||||
new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality)
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
encodedImageBytes = ImageUtils.EncodeBitmap(newImage, viewer.EncoderParams);
|
||||
}
|
||||
|
||||
if (encodedImageBytes?.Length > 0)
|
||||
{
|
||||
await conductor.CasterSocket.SendScreenCapture(encodedImageBytes, viewerID, diffArea.Left, diffArea.Top, diffArea.Width, diffArea.Height, DateTime.UtcNow);
|
||||
viewer.PendingFrames++;
|
||||
viewer.Latency += 300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,20 +11,18 @@ namespace Remotely.ScreenCast.Core.Models
|
||||
{
|
||||
public class Viewer
|
||||
{
|
||||
private long imageQuality = 50;
|
||||
|
||||
public Viewer()
|
||||
{
|
||||
ImageQuality = 50;
|
||||
}
|
||||
public string ViewerConnectionID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool AutoAdjustQuality { get; internal set; }
|
||||
public ICapturer Capturer { get; set; }
|
||||
public bool DisconnectRequested { get; set; }
|
||||
public EncoderParameters EncoderParams { get; private set; }
|
||||
public bool FullScreenRefreshNeeded { get; internal set; }
|
||||
public bool HasControl { get; set; }
|
||||
public double Latency { get; set; } = 1;
|
||||
public int PendingFrames { get; set; }
|
||||
|
||||
private long imageQuality = 50;
|
||||
public long ImageQuality
|
||||
{
|
||||
get
|
||||
@ -42,17 +40,19 @@ namespace Remotely.ScreenCast.Core.Models
|
||||
return;
|
||||
}
|
||||
imageQuality = value;
|
||||
|
||||
|
||||
EncoderParams = new EncoderParameters()
|
||||
{
|
||||
Param = new []
|
||||
Param = new[]
|
||||
{
|
||||
new EncoderParameter(Encoder.Quality, value)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
public bool FullScreenRefreshNeeded { get; internal set; }
|
||||
|
||||
public double Latency { get; set; } = 1;
|
||||
public string Name { get; set; }
|
||||
public string ViewerConnectionID { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -277,7 +277,6 @@ namespace Remotely.ScreenCast.Core.Sockets
|
||||
{
|
||||
var latency = DateTime.UtcNow - sentTime;
|
||||
viewer.Latency = latency.TotalMilliseconds;
|
||||
viewer.PendingFrames = Math.Max(0, viewer.PendingFrames - 1);
|
||||
}
|
||||
});
|
||||
|
||||
@ -297,6 +296,14 @@ namespace Remotely.ScreenCast.Core.Sockets
|
||||
}
|
||||
});
|
||||
|
||||
Connection.On("AutoQualityAdjust", (bool isOn, string viewerID) =>
|
||||
{
|
||||
if (conductor.Viewers.TryGetValue(viewerID, out var viewer))
|
||||
{
|
||||
viewer.AutoAdjustQuality = isOn;
|
||||
}
|
||||
});
|
||||
|
||||
Connection.On("ToggleAudio", (bool toggleOn, string viewerID) =>
|
||||
{
|
||||
if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl)
|
||||
|
||||
@ -90,7 +90,13 @@
|
||||
<div style="color:white; font-size:12px">
|
||||
Image Quality
|
||||
</div>
|
||||
<input id="qualityRangeInput" value="50" max="100" class="form-control-range" type="range" />
|
||||
<div>
|
||||
<input id="qualityRangeInput" value="50" max="100" class="form-control-range" type="range" />
|
||||
<div style="color:white; font-size:12px; text-align: left">
|
||||
<input id="autoAdjustQualityCheckBox" type="checkbox" checked />
|
||||
<label>Auto Adjust</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="clipboardTransferBar" class="horizontal-button-bar">
|
||||
|
||||
@ -160,6 +160,11 @@ namespace Remotely.Server.Services
|
||||
await RCDeviceHub.Clients.Client(ScreenCasterID).SendAsync("QualityChange", qualityLevel, Context.ConnectionId);
|
||||
}
|
||||
|
||||
public async Task SendAutoQualityAdjust(bool isOn)
|
||||
{
|
||||
await RCDeviceHub.Clients.Client(ScreenCasterID).SendAsync("AutoQualityAdjust", isOn, Context.ConnectionId);
|
||||
}
|
||||
|
||||
public async Task SendScreenCastRequestToDevice(string screenCasterID, string requesterName, int remoteControlMode)
|
||||
{
|
||||
if ((RemoteControlMode)remoteControlMode == RemoteControlMode.Normal)
|
||||
|
||||
@ -101,6 +101,9 @@ export class RCBrowserSockets {
|
||||
SendQualityChange(qualityLevel: number) {
|
||||
this.Connection.invoke("SendQualityChange", qualityLevel);
|
||||
}
|
||||
SendAutoQualityAdjust(isOn: boolean) {
|
||||
this.Connection.invoke("SendAutoQualityAdjust", isOn);
|
||||
}
|
||||
SendToggleAudio(toggleOn: boolean) {
|
||||
this.Connection.invoke("SendToggleAudio", toggleOn);
|
||||
};
|
||||
|
||||
@ -16,6 +16,7 @@ export var ConnectBox = document.getElementById("connectBox");
|
||||
export var ScreenSelectBar = document.getElementById("screenSelectBar");
|
||||
export var QualityBar = document.getElementById("qualityBar");
|
||||
export var QualitySlider = document.getElementById("qualityRangeInput");
|
||||
export var AutoQualityAdjustCheckBox = document.getElementById("autoAdjustQualityCheckBox");
|
||||
export var ActionsBar = document.getElementById("actionsBar");
|
||||
export var ViewBar = document.getElementById("viewBar");
|
||||
export var ChangeScreenButton = document.getElementById("changeScreenButton");
|
||||
@ -150,6 +151,9 @@ export function ApplyInputHandlers(sockets) {
|
||||
QualitySlider.addEventListener("change", (ev) => {
|
||||
sockets.SendQualityChange(Number(QualitySlider.value));
|
||||
});
|
||||
AutoQualityAdjustCheckBox.addEventListener("change", ev => {
|
||||
sockets.SendAutoQualityAdjust(AutoQualityAdjustCheckBox.checked);
|
||||
});
|
||||
ScreenViewer.addEventListener("pointermove", function (e) {
|
||||
currentPointerDevice = e.pointerType;
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -19,6 +19,7 @@ export var ConnectBox = document.getElementById("connectBox") as HTMLDivElement;
|
||||
export var ScreenSelectBar = document.getElementById("screenSelectBar") as HTMLDivElement;
|
||||
export var QualityBar = document.getElementById("qualityBar") as HTMLDivElement;
|
||||
export var QualitySlider = document.getElementById("qualityRangeInput") as HTMLInputElement;
|
||||
export var AutoQualityAdjustCheckBox = document.getElementById("autoAdjustQualityCheckBox") as HTMLInputElement;
|
||||
export var ActionsBar = document.getElementById("actionsBar") as HTMLDivElement;
|
||||
export var ViewBar = document.getElementById("viewBar") as HTMLDivElement;
|
||||
export var ChangeScreenButton = document.getElementById("changeScreenButton") as HTMLButtonElement;
|
||||
@ -155,7 +156,10 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
|
||||
})
|
||||
QualitySlider.addEventListener("change", (ev) => {
|
||||
sockets.SendQualityChange(Number(QualitySlider.value));
|
||||
})
|
||||
});
|
||||
AutoQualityAdjustCheckBox.addEventListener("change", ev => {
|
||||
sockets.SendAutoQualityAdjust(AutoQualityAdjustCheckBox.checked);
|
||||
});
|
||||
ScreenViewer.addEventListener("pointermove", function (e) {
|
||||
currentPointerDevice = e.pointerType;
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user