diff --git a/app/ui.js b/app/ui.js index f3fe5be4..4fe130e6 100644 --- a/app/ui.js +++ b/app/ui.js @@ -188,6 +188,18 @@ const UI = { UI.initSetting('view_clip', false); /* UI.initSetting('resize', 'off'); */ UI.initSetting('quality', 6); + UI.initSetting('dynamic_quality_min', 3); + UI.initSetting('dynamic_quality_max', 9); + UI.initSetting('treat_lossless', 7); + UI.initSetting('jpeg_video_quality', 5); + UI.initSetting('webp_video_quality', 5); + UI.initSetting('video_area', 65); + UI.initSetting('video_time', 5); + UI.initSetting('video_out_time', 3); + UI.initSetting('video_scaling', 2); + UI.initSetting('max_video_resolution_x', 960); + UI.initSetting('max_video_resolution_y', 540); + UI.initSetting('framerate', 30); UI.initSetting('compression', 2); UI.initSetting('shared', true); UI.initSetting('view_only', false); @@ -394,6 +406,30 @@ const UI = { UI.addSettingChangeHandler('resize', UI.updateViewClip); UI.addSettingChangeHandler('quality'); UI.addSettingChangeHandler('quality', UI.updateQuality); + UI.addSettingChangeHandler('dynamic_quality_min'); + UI.addSettingChangeHandler('dynamic_quality_min', UI.updateQuality); + UI.addSettingChangeHandler('dynamic_quality_max'); + UI.addSettingChangeHandler('dynamic_quality_max', UI.updateQuality); + UI.addSettingChangeHandler('treat_lossless'); + UI.addSettingChangeHandler('treat_lossless', UI.updateQuality); + UI.addSettingChangeHandler('jpeg_video_quality'); + UI.addSettingChangeHandler('jpeg_video_quality', UI.updateQuality); + UI.addSettingChangeHandler('webp_video_quality'); + UI.addSettingChangeHandler('webp_video_quality', UI.updateQuality); + UI.addSettingChangeHandler('video_area'); + UI.addSettingChangeHandler('video_area', UI.updateQuality); + UI.addSettingChangeHandler('video_time'); + UI.addSettingChangeHandler('video_time', UI.updateQuality); + UI.addSettingChangeHandler('video_out_time'); + UI.addSettingChangeHandler('video_out_time', UI.updateQuality); + UI.addSettingChangeHandler('video_scaling'); + UI.addSettingChangeHandler('video_scaling', UI.updateQuality); + UI.addSettingChangeHandler('max_video_resolution_x'); + UI.addSettingChangeHandler('max_video_resolution_x', UI.updateQuality); + UI.addSettingChangeHandler('max_video_resolution_y'); + UI.addSettingChangeHandler('max_video_resolution_y', UI.updateQuality); + UI.addSettingChangeHandler('framerate'); + UI.addSettingChangeHandler('framerate', UI.updateQuality); UI.addSettingChangeHandler('compression'); UI.addSettingChangeHandler('compression', UI.updateCompression); UI.addSettingChangeHandler('view_clip'); @@ -833,7 +869,11 @@ const UI = { } } } else { + let value_label = document.getElementById('noVNC_setting_' + name + '_output'); ctrl.value = value; + if (value_label) { + value_label.value = value; + } } }, @@ -910,6 +950,18 @@ const UI = { UI.updateSetting('view_clip'); UI.updateSetting('resize'); UI.updateSetting('quality'); + UI.updateSetting('dynamic_quality_min', 3); + UI.updateSetting('dynamic_quality_max', 9); + UI.updateSetting('treat_lossless', 7); + UI.updateSetting('jpeg_video_quality', 5); + UI.updateSetting('webp_video_quality', 5); + UI.updateSetting('video_area', 65); + UI.updateSetting('video_time', 5); + UI.updateSetting('video_out_time', 3); + UI.updateSetting('video_scaling', 2); + UI.updateSetting('max_video_resolution_x', 960); + UI.updateSetting('max_video_resolution_y', 540); + UI.updateSetting('framerate', 30); UI.updateSetting('compression'); UI.updateSetting('shared'); UI.updateSetting('view_only'); @@ -1214,6 +1266,18 @@ const UI = { UI.rfb.scaleViewport = UI.getSetting('resize') === 'scale'; UI.rfb.resizeSession = UI.getSetting('resize') === 'remote'; UI.rfb.qualityLevel = parseInt(UI.getSetting('quality')); + UI.rfb.dynamicQualityMin = parseInt(UI.getSetting('dynamic_quality_min')); + UI.rfb.dynamicQualityMax = parseInt(UI.getSetting('dynamic_quality_max')); + UI.rfb.jpegVideoQuality = parseInt(UI.getSetting('jpeg_video_quality')); + UI.rfb.webpVideoQuality = parseInt(UI.getSetting('webp_video_quality')); + UI.rfb.videoArea = parseInt(UI.getSetting('video_area')); + UI.rfb.videoTime = parseInt(UI.getSetting('video_time')); + UI.rfb.videoOutTime = parseInt(UI.getSetting('video_out_time')); + UI.rfb.videoScaling = parseInt(UI.getSetting('video_scaling')); + UI.rfb.treatLossless = parseInt(UI.getSetting('treat_lossless')); + UI.rfb.maxVideoResolutionX = parseInt(UI.getSetting('max_video_resolution_x')); + UI.rfb.maxVideoResolutionY = parseInt(UI.getSetting('max_video_resolution_y')); + UI.rfb.frameRate = parseInt(UI.getSetting('framerate')); UI.rfb.compressionLevel = parseInt(UI.getSetting('compression')); UI.rfb.showDotCursor = UI.getSetting('show_dot'); UI.rfb.idleDisconnect = UI.getSetting('idle_disconnect'); @@ -1624,7 +1688,26 @@ const UI = { updateQuality() { if (!UI.rfb) return; - UI.rfb.qualityLevel = parseInt(UI.getSetting('quality')); + if (!UI.updatingSettings) { + // avoid sending too many, will only apply when there are changes + setTimeout(function() { + UI.rfb.qualityLevel = parseInt(UI.getSetting('quality')); + UI.rfb.dynamicQualityMin = parseInt(UI.getSetting('dynamic_quality_min')); + UI.rfb.dynamicQualityMax = parseInt(UI.getSetting('dynamic_quality_max')); + UI.rfb.jpegVideoQuality = parseInt(UI.getSetting('jpeg_video_quality')); + UI.rfb.webpVideoQuality = parseInt(UI.getSetting('webp_video_quality')); + UI.rfb.videoArea = parseInt(UI.getSetting('video_area')); + UI.rfb.videoTime = parseInt(UI.getSetting('video_time')); + UI.rfb.videoOutTime = parseInt(UI.getSetting('video_out_time')); + UI.rfb.videoScaling = parseInt(UI.getSetting('video_scaling')); + UI.rfb.treatLossless = parseInt(UI.getSetting('treat_lossless')); + UI.rfb.maxVideoResolutionX = parseInt(UI.getSetting('max_video_resolution_x')); + UI.rfb.maxVideoResolutionY = parseInt(UI.getSetting('max_video_resolution_y')); + UI.rfb.frameRate = parseInt(UI.getSetting('framerate')); + UI.rfb.enableWebP = UI.getSetting('enable_webp'); + }, 2000); + + } }, /* ------^------- diff --git a/core/rfb.js b/core/rfb.js index db774e12..41808492 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -337,48 +337,9 @@ export default class RFB extends EventTargetMixin { get videoQuality() { return this._videoQuality; } set videoQuality(quality) { this._videoQuality = quality; } - get enableWebP() { return this._enableWebP; } - set enableWebP(enabled) { this._enableWebP = enabled; } - - get jpegVideoQuality() { return this._jpegVideoQuality; } - set jpegVideoQuality(val) { this._jpegVideoQuality = val; } - - get webpVideoQuality() { return this._webpVideoQuality; } - set webpVideoQuality(val) { this._webpVideoQuality = val; } - - get treatLossless() { return this._treatLossless; } - set treatLossless(val) { this._treatLossless = val; } - get preferBandwidth() { return this._preferBandwidth; } set preferBandwidth(val) { this._preferBandwidth = val; } - get dynamicQualityMin() { return this._dynamicQualityMin; } - set dynamicQualityMin(val) { this._dynamicQualityMin = val; } - - get dynamicQualityMax() { return this._dynamicQualityMax; } - set dynamicQualityMax(val) { this._dynamicQualityMax = val; } - - get videoArea() { return this._videoArea; } - set videoArea(val) { this._videoArea = val; } - - get videoTime() { return this._videoTime; } - set videoTime(val) { this._videoTime = val; } - - get videoOutTime() { return this._videoOutTime; } - set videoOutTime(val) { this._videoOutTime = val; } - - get videoScaling() { return this._videoScaling; } - set videoScaling(val) { this._videoScaling = val; } - - get frameRate() { return this._frameRate; } - set frameRate(val) { this._frameRate = val; } - - get maxVideoResolutionX() { return this._maxVideoResolutionX; } - set maxVideoResolutionX(val) { this._maxVideoResolutionX = val; } - - get maxVideoResolutionY() { return this._maxVideoResolutionY; } - set maxVideoResolutionY(val) { this._maxVideoResolutionY = val; } - get viewOnly() { return this._viewOnly; } set viewOnly(viewOnly) { this._viewOnly = viewOnly; @@ -436,6 +397,246 @@ export default class RFB extends EventTargetMixin { get background() { return this._screen.style.background; } set background(cssValue) { this._screen.style.background = cssValue; } + get enableWebP() { return this._enableWebP; } + set enableWebP(enabled) { + if (this._enableWebP === enabled) { + return; + } + this._enableWebP = enabled; + if (this._rfbConnectionState === 'connected') { + this._sendEncodings(); + } + } + + get jpegVideoQuality() { return this._jpegVideoQuality; } + set jpegVideoQuality(qualityLevel) { + if (!Number.isInteger(qualityLevel) || qualityLevel < 0 || qualityLevel > 9) { + Log.Error("qualityLevel must be an integer between 0 and 9"); + return; + } + + if (this._jpegVideoQuality === qualityLevel) { + return; + } + + this._jpegVideoQuality = qualityLevel; + + if (this._rfbConnectionState === 'connected') { + this._sendEncodings(); + } + } + + get webpVideoQuality() { return this._webpVideoQuality; } + set webpVideoQuality(qualityLevel) { + if (!Number.isInteger(qualityLevel) || qualityLevel < 0 || qualityLevel > 9) { + Log.Error("qualityLevel must be an integer between 0 and 9"); + return; + } + + if (this._webpVideoQuality === qualityLevel) { + return; + } + + this._webpVideoQuality = qualityLevel; + + if (this._rfbConnectionState === 'connected') { + this._sendEncodings(); + } + } + + get treatLossless() { return this._treatLossless; } + set treatLossless(qualityLevel) { + if (!Number.isInteger(qualityLevel) || qualityLevel < 0 || qualityLevel > 9) { + Log.Error("qualityLevel must be an integer between 0 and 9"); + return; + } + + if (this._treatLossless === qualityLevel) { + return; + } + + this._treatLossless = qualityLevel; + + if (this._rfbConnectionState === 'connected') { + this._sendEncodings(); + } + } + + get dynamicQualityMin() { return this._dynamicQualityMin; } + set dynamicQualityMin(qualityLevel) { + if (!Number.isInteger(qualityLevel) || qualityLevel < 0 || qualityLevel > 9) { + Log.Error("qualityLevel must be an integer between 0 and 9"); + return; + } + + if (this._dynamicQualityMin === qualityLevel) { + return; + } + + this._dynamicQualityMin = qualityLevel; + + if (this._rfbConnectionState === 'connected') { + this._sendEncodings(); + } + } + + get dynamicQualityMax() { return this._dynamicQualityMax; } + set dynamicQualityMax(qualityLevel) { + if (!Number.isInteger(qualityLevel) || qualityLevel < 0 || qualityLevel > 9) { + Log.Error("qualityLevel must be an integer between 0 and 9"); + return; + } + + if (this._dynamicQualityMax === qualityLevel) { + return; + } + + this._dynamicQualityMax = qualityLevel; + + if (this._rfbConnectionState === 'connected') { + this._sendEncodings(); + } + } + + get videoArea() { + return this._videoArea; + } + set videoArea(area) { + if (!Number.isInteger(area) || area < 0 || area > 100) { + Log.Error("video area must be an integer between 0 and 100"); + return; + } + + if (this._videoArea === area) { + return; + } + + this._videoArea = area; + + if (this._rfbConnectionState === 'connected') { + this._sendEncodings(); + } + } + + get videoTime() { + return this._videoTime; + } + set videoTime(value) { + if (!Number.isInteger(value) || value < 0 || value > 100) { + Log.Error("video time must be an integer between 0 and 100"); + return; + } + + if (this._videoTime === value) { + return; + } + + this._videoTime = value; + + if (this._rfbConnectionState === 'connected') { + this._sendEncodings(); + } + } + + get videoOutTime() { + return this._videoOutTime; + } + set videoOutTime(value) { + if (!Number.isInteger(value) || value < 0 || value > 100) { + Log.Error("video out time must be an integer between 0 and 100"); + return; + } + + if (this._videoOutTime === value) { + return; + } + + this._videoOutTime = value; + + if (this._rfbConnectionState === 'connected') { + this._sendEncodings(); + } + } + + get videoScaling() { + return this._videoScaling; + } + set videoScaling(value) { + if (!Number.isInteger(value) || value < 0 || value > 2) { + Log.Error("video scaling must be an integer between 0 and 2"); + return; + } + + if (this._videoScaling === value) { + return; + } + + this._videoScaling = value; + + if (this._rfbConnectionState === 'connected') { + this._sendEncodings(); + } + } + + get frameRate() { return this._frameRate; } + set frameRate(value) { + if (!Number.isInteger(value) || value < 1 || value > 120) { + Log.Error("frame rate must be an integer between 1 and 120"); + return; + } + + if (this._frameRate === value) { + return; + } + + this._frameRate = value; + + if (this._rfbConnectionState === 'connected') { + this._sendEncodings(); + } + } + + get maxVideoResolutionX() { return this._maxVideoResolutionX; } + set maxVideoResolutionX(value) { + if (!Number.isInteger(value) || value < 100 ) { + Log.Error("max video resolution must be an integer greater than 100"); + return; + } + + if (this._maxVideoResolutionX === value) { + return; + } + + this._maxVideoResolutionX = value; + + if (this._rfbConnectionState === 'connected') { + RFB.messages.setMaxVideoResolution(this._sock, + this._maxVideoResolutionX, + this._maxVideoResolutionY); + } + + } + + get maxVideoResolutionY() { return this._maxVideoResolutionY; } + set maxVideoResolutionY(value) { + if (!Number.isInteger(value) || value < 100 ) { + Log.Error("max video resolution must be an integer greater than 100"); + return; + } + + if (this._maxVideoResolutionY === value) { + return; + } + + this._maxVideoResolutionY = value; + + if (this._rfbConnectionState === 'connected') { + RFB.messages.setMaxVideoResolution(this._sock, + this._maxVideoResolutionX, + this._maxVideoResolutionY); + } + } + get qualityLevel() { return this._qualityLevel; } @@ -1878,7 +2079,6 @@ export default class RFB extends EventTargetMixin { _sendEncodings() { const encs = []; - var hasWebp; // In preference order encs.push(encodings.encodingCopyRect); @@ -1932,6 +2132,7 @@ export default class RFB extends EventTargetMixin { encs.push(encodings.pseudoEncodingVideoScalingLevel0 + this.videoScaling); encs.push(encodings.pseudoEncodingFrameRateLevel10 + this.frameRate - 10); encs.push(encodings.pseudoEncodingMaxVideoResolution); + // preferBandwidth choses preset settings. Since we expose all the settings, lets not pass this if (this.preferBandwidth) // must be last - server processes in reverse order encs.push(encodings.pseudoEncodingPreferBandwidth); diff --git a/load.html b/load.html index 984fb5d3..470c1780 100644 --- a/load.html +++ b/load.html @@ -48,7 +48,7 @@ - +
@@ -197,14 +197,6 @@