|
@@ -12,6 +12,7 @@ let protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
|
|
let port = window.location.port ? window.location.port : (protocol === 'wss' ? 443 : 80);
|
|
let port = window.location.port ? window.location.port : (protocol === 'wss' ? 443 : 80);
|
|
let hidSocketURL = `${protocol}://${window.location.hostname}:${port}/api/v1/hid/{uuid}/events`;
|
|
let hidSocketURL = `${protocol}://${window.location.hostname}:${port}/api/v1/hid/{uuid}/events`;
|
|
let audioSocketURL = `${protocol}://${window.location.hostname}:${port}/api/v1/stream/{uuid}/audio`;
|
|
let audioSocketURL = `${protocol}://${window.location.hostname}:${port}/api/v1/stream/{uuid}/audio`;
|
|
|
|
+
|
|
let mouseMoveAbsolute = true; // Set to true for absolute mouse coordinates, false for relative
|
|
let mouseMoveAbsolute = true; // Set to true for absolute mouse coordinates, false for relative
|
|
let mouseIsOutside = false; //Mouse is outside capture element
|
|
let mouseIsOutside = false; //Mouse is outside capture element
|
|
let audioFrontendStarted = false; //Audio frontend has been started
|
|
let audioFrontendStarted = false; //Audio frontend has been started
|
|
@@ -22,6 +23,7 @@ if (window.location.hash.length > 1){
|
|
kvmDeviceUUID = window.location.hash.substring(1);
|
|
kvmDeviceUUID = window.location.hash.substring(1);
|
|
hidSocketURL = hidSocketURL.replace("{uuid}", kvmDeviceUUID);
|
|
hidSocketURL = hidSocketURL.replace("{uuid}", kvmDeviceUUID);
|
|
audioSocketURL = audioSocketURL.replace("{uuid}", kvmDeviceUUID);
|
|
audioSocketURL = audioSocketURL.replace("{uuid}", kvmDeviceUUID);
|
|
|
|
+ massStorageSwitchURL = massStorageSwitchURL.replace("{uuid}", kvmDeviceUUID);
|
|
}
|
|
}
|
|
|
|
|
|
$(document).ready(function() {
|
|
$(document).ready(function() {
|
|
@@ -30,7 +32,7 @@ $(document).ready(function() {
|
|
startHidWebSocket();
|
|
startHidWebSocket();
|
|
});
|
|
});
|
|
|
|
|
|
-/* Stream endpoint */
|
|
|
|
|
|
+/* Initiate API endpoint */
|
|
function setStreamingSource(deviceUUID) {
|
|
function setStreamingSource(deviceUUID) {
|
|
let videoStreamURL = `/api/v1/stream/${deviceUUID}/video`
|
|
let videoStreamURL = `/api/v1/stream/${deviceUUID}/video`
|
|
let videoElement = document.getElementById("remoteCapture");
|
|
let videoElement = document.getElementById("remoteCapture");
|
|
@@ -303,7 +305,7 @@ function startAudioWebSocket(quality="standard") {
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
- const MAX_AUDIO_QUEUE = 8;
|
|
|
|
|
|
+ const MAX_AUDIO_QUEUE = 4;
|
|
let PCM_SAMPLE_RATE;
|
|
let PCM_SAMPLE_RATE;
|
|
if (quality == "high"){
|
|
if (quality == "high"){
|
|
PCM_SAMPLE_RATE = 48000; // Use 48kHz for high quality
|
|
PCM_SAMPLE_RATE = 48000; // Use 48kHz for high quality
|
|
@@ -349,24 +351,13 @@ function startAudioWebSocket(quality="standard") {
|
|
console.error("Audio WebSocket error", e);
|
|
console.error("Audio WebSocket error", e);
|
|
};
|
|
};
|
|
|
|
|
|
- // Periodically resync scheduledTime to avoid drift
|
|
|
|
- let lastResync = 0;
|
|
|
|
- const RESYNC_INTERVAL = 60; // seconds
|
|
|
|
-
|
|
|
|
function scheduleAudioPlayback() {
|
|
function scheduleAudioPlayback() {
|
|
if (!audioContext || audioQueue.length === 0) return;
|
|
if (!audioContext || audioQueue.length === 0) return;
|
|
|
|
|
|
- // Resync scheduledTime every RESYNC_INTERVAL seconds to avoid drift
|
|
|
|
|
|
+ // Use audioContext.currentTime to schedule buffers back-to-back
|
|
if (scheduledTime < audioContext.currentTime) {
|
|
if (scheduledTime < audioContext.currentTime) {
|
|
scheduledTime = audioContext.currentTime;
|
|
scheduledTime = audioContext.currentTime;
|
|
}
|
|
}
|
|
- if (scheduledTime - audioContext.currentTime > RESYNC_INTERVAL) {
|
|
|
|
- scheduledTime = audioContext.currentTime;
|
|
|
|
- }
|
|
|
|
- if (audioContext.currentTime - lastResync > RESYNC_INTERVAL) {
|
|
|
|
- scheduledTime = audioContext.currentTime;
|
|
|
|
- lastResync = audioContext.currentTime;
|
|
|
|
- }
|
|
|
|
|
|
|
|
while (audioQueue.length > 0) {
|
|
while (audioQueue.length > 0) {
|
|
let floatBuf = audioQueue.shift();
|
|
let floatBuf = audioQueue.shift();
|
|
@@ -378,6 +369,11 @@ function startAudioWebSocket(quality="standard") {
|
|
channelData[i] = floatBuf[i * 2 + ch];
|
|
channelData[i] = floatBuf[i * 2 + ch];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (scheduledTime - audioContext.currentTime > 0.2) {
|
|
|
|
+ console.warn("Audio buffer too far ahead, discarding frame");
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
let source = audioContext.createBufferSource();
|
|
let source = audioContext.createBufferSource();
|
|
source.buffer = buffer;
|
|
source.buffer = buffer;
|
|
source.connect(audioContext.destination);
|
|
source.connect(audioContext.destination);
|