Discovery VideoSources and Dynamically Update Editor

This commit is contained in:
Lord-Grey 2021-02-14 11:39:03 +01:00
parent f25b152d51
commit 054d3dac41
11 changed files with 2782 additions and 2515 deletions

View File

@ -343,6 +343,7 @@
"edt_conf_general_port_title": "Port",
"edt_conf_general_priority_expl": "The priority of this component",
"edt_conf_general_priority_title": "Priority channel",
"edt_conf_grabber_discovered_none": "No Devices Discovered",
"edt_conf_instC_systemEnable_expl": "Enables the platform capture for this led hardware instance",
"edt_conf_instC_systemEnable_title": "Enable platform capture",
"edt_conf_instC_v4lEnable_expl": "Enables the USB capture for this led hardware instance",
@ -429,20 +430,20 @@
"edt_conf_v4l2_standard_title": "Video standard",
"edt_conf_v4l2_flip_expl": "This allows you to flip the image horizontally, vertically, or both.",
"edt_conf_v4l2_flip_title": "Image flip",
"edt_conf_v4l2_fpsSoftwareDecimation_title" : "Software frame skipping",
"edt_conf_v4l2_fpsSoftwareDecimation_expl" : "To save resources every n'th frame will be processed only. For ex. if grabber is set to 30FPS with this option set to 5 the final result will be around 6FPS (1 - disabled)",
"edt_conf_v4l2_encoding_title" : "Encoding format",
"edt_conf_v4l2_encoding_expl" : "Force video encoding for multiformat capable grabbers",
"edt_conf_v4l2_hardware_brightness_title" : "Hardware brightness control",
"edt_conf_v4l2_hardware_brightness_expl" : "Set hardware brightness if device supports it, check logs (0=disabled)",
"edt_conf_v4l2_hardware_contrast_title" : "Hardware contrast control",
"edt_conf_v4l2_hardware_contrast_expl" : "Set hardware contrast if device supports it, check logs (0=disabled)",
"edt_conf_v4l2_noSignalCounterThreshold_title" : "Signal Counter Threshold",
"edt_conf_v4l2_noSignalCounterThreshold_expl" : "Count of frames (check that with grabber's current FPS mode) after which the no signal is triggered",
"edt_conf_v4l2_hardware_saturation_title" : "Hardware saturation control",
"edt_conf_v4l2_hardware_saturation_expl" : "Set hardware saturation if device supports it, check logs (0=disabled)",
"edt_conf_v4l2_hardware_hue_title" : "Hardware hue control",
"edt_conf_v4l2_hardware_hue_expl" : "Set hardware hue if device supports it, check logs (0=disabled)",
"edt_conf_v4l2_fpsSoftwareDecimation_title": "Software frame skipping",
"edt_conf_v4l2_fpsSoftwareDecimation_expl": "To save resources every n'th frame will be processed only. For ex. if grabber is set to 30FPS with this option set to 5 the final result will be around 6FPS (1 - disabled)",
"edt_conf_v4l2_encoding_title": "Encoding format",
"edt_conf_v4l2_encoding_expl": "Force video encoding for multiformat capable grabbers",
"edt_conf_v4l2_hardware_brightness_title": "Hardware brightness control",
"edt_conf_v4l2_hardware_brightness_expl": "Set hardware brightness if device supports it, check logs (0=disabled)",
"edt_conf_v4l2_hardware_contrast_title": "Hardware contrast control",
"edt_conf_v4l2_hardware_contrast_expl": "Set hardware contrast if device supports it, check logs (0=disabled)",
"edt_conf_v4l2_noSignalCounterThreshold_title": "Signal Counter Threshold",
"edt_conf_v4l2_noSignalCounterThreshold_expl": "Count of frames (check that with grabber's current FPS mode) after which the no signal is triggered",
"edt_conf_v4l2_hardware_saturation_title": "Hardware saturation control",
"edt_conf_v4l2_hardware_saturation_expl": "Set hardware saturation if device supports it, check logs (0=disabled)",
"edt_conf_v4l2_hardware_hue_title": "Hardware hue control",
"edt_conf_v4l2_hardware_hue_expl": "Set hardware hue if device supports it, check logs (0=disabled)",
"edt_conf_webc_crtPath_expl": "Path to the certification file (format should be PEM)",
"edt_conf_webc_crtPath_title": "Certificate path",
"edt_conf_webc_docroot_expl": "Local webinterface root path (just for webui developer)",

View File

@ -3,214 +3,7 @@ $(document).ready(function () {
var conf_editor_v4l2 = null;
var conf_editor_fg = null;
var conf_editor_instCapt = null;
var V4L2_AVAIL = window.serverInfo.grabbers.available.includes("v4l2");
if (V4L2_AVAIL) {
// Dynamic v4l2 enum schema
var v4l2_dynamic_enum_schema = {
"available_devices":
{
"type": "string",
"title": "edt_conf_v4l2_device_title",
"propertyOrder": 1,
"required": true,
"custom": true
},
"device_inputs":
{
"type": "string",
"title": "edt_conf_v4l2_input_title",
"propertyOrder": 3,
"required": true,
"custom": false
},
"encoding_format":
{
"type": "string",
"title": "edt_conf_v4l2_encoding_title",
"propertyOrder": 5,
"required": true,
"custom": false
},
"resolutions":
{
"type": "string",
"title": "edt_conf_v4l2_resolution_title",
"propertyOrder": 9,
"required": true,
"custom": true
},
"framerates":
{
"type": "string",
"title": "edt_conf_v4l2_framerate_title",
"propertyOrder": 12,
"required": true,
"custom": true
}
};
// Build dynamic v4l2 enum schema parts
var buildSchemaPart = function (key, schema, device) {
if (schema[key]) {
var enumVals = [];
var enumTitelVals = [];
var v4l2_properties = JSON.parse(JSON.stringify(window.serverInfo.grabbers.video_sources));
if (key == 'available_devices') {
for (var i = 0; i < v4l2_properties.length; i++) {
enumVals.push(v4l2_properties[i]['device']);
v4l2_properties[i].hasOwnProperty('name')
? enumTitelVals.push(v4l2_properties[i]['name'])
: enumTitelVals.push(v4l2_properties[i]['device']);
}
} else if (key == 'device_inputs') {
return; // TODO Fix V4L2 WebUI
for (var i = 0; i < v4l2_properties.length; i++) {
if (v4l2_properties[i]['device'] == device) {
for (var index = 0; index < v4l2_properties[i]['device_inputs'].length; index++) {
enumVals.push(v4l2_properties[i]['device_inputs'][index]['inputIndex'].toString());
enumTitelVals.push(v4l2_properties[i]['device_inputs'][index]['inputName']);
}
break;
}
}
} else if (key == 'encoding_format') {
for (var i = 0; i < v4l2_properties.length; i++) {
if (v4l2_properties[i]['device'] == device) {
enumVals = enumTitelVals = v4l2_properties[i][key];
break;
}
}
}
else if (key == 'resolutions') {
for (var i = 0; i < v4l2_properties.length; i++) {
if (v4l2_properties[i]['device'] == device) {
enumVals = enumTitelVals = v4l2_properties[i][key];
break;
}
}
} else if (key == 'framerates') {
for (var i = 0; i < v4l2_properties.length; i++) {
if (v4l2_properties[i]['device'] == device) {
enumVals = enumTitelVals = v4l2_properties[i][key];
break;
}
}
}
window.schema.grabberV4L2.properties[key] = {
"type": schema[key].type,
"title": schema[key].title,
...(schema[key].custom ? {"enum": [].concat(["auto"], enumVals, ["custom"]),} : {"enum": [].concat(["auto"], enumVals),}),
"options":
{
"enum_titles": [].concat(["edt_conf_enum_automatic"], enumTitelVals, ["edt_conf_enum_custom"]),
},
"propertyOrder": schema[key].propertyOrder,
"required": schema[key].required
};
}
};
// Switch between visible states
function toggleOption(option, state) {
$('[data-schemapath="root.grabberV4L2.' + option + '"]').toggle(state);
if (state) (
$('[data-schemapath="root.grabberV4L2.' + option + '"]').addClass('col-md-12'),
$('label[for="root_grabberV4L2_' + option + '"]').css('left', '10px'),
$('[id="root_grabberV4L2_' + option + '"]').css('left', '10px')
);
}
// Watch all v4l2 dynamic fields
var setWatchers = function (schema) {
var path = 'root.grabberV4L2.';
Object.keys(schema).forEach(function (key) {
conf_editor_v4l2.watch(path + key, function () {
var ed = conf_editor_v4l2.getEditor(path + key);
var val = ed.getValue();
if (key == 'available_devices') {
var V4L2properties = ['device_inputs', 'resolutions', 'framerates', 'encoding_format'];
if (val == 'custom') {
var grabberV4L2 = ed.parent;
V4L2properties.forEach(function (item) {
buildSchemaPart(item, v4l2_dynamic_enum_schema, 'none');
grabberV4L2.original_schema.properties[item] = window.schema.grabberV4L2.properties[item];
grabberV4L2.schema.properties[item] = window.schema.grabberV4L2.properties[item];
conf_editor_v4l2.validator.schema.properties.grabberV4L2.properties[item] = window.schema.grabberV4L2.properties[item];
grabberV4L2.removeObjectProperty(item);
delete grabberV4L2.cached_editors[item];
grabberV4L2.addObjectProperty(item);
conf_editor_v4l2.getEditor(path + item).enable();
});
conf_editor_v4l2.getEditor(path + 'standard').enable();
toggleOption('device', true);
} else if (val == 'auto') {
V4L2properties.forEach(function (item) {
conf_editor_v4l2.getEditor(path + item).setValue('auto');
conf_editor_v4l2.getEditor(path + item).disable();
});
conf_editor_v4l2.getEditor(path + 'standard').setValue('auto');
conf_editor_v4l2.getEditor(path + 'standard').disable();
(toggleOption('device', false), toggleOption('input', false),
toggleOption('width', false), toggleOption('height', false),
toggleOption('fps', false), toggleOption('encoding', false));
} else {
var grabberV4L2 = ed.parent;
V4L2properties.forEach(function (item) {
buildSchemaPart(item, v4l2_dynamic_enum_schema, val);
grabberV4L2.original_schema.properties[item] = window.schema.grabberV4L2.properties[item];
grabberV4L2.schema.properties[item] = window.schema.grabberV4L2.properties[item];
conf_editor_v4l2.validator.schema.properties.grabberV4L2.properties[item] = window.schema.grabberV4L2.properties[item];
grabberV4L2.removeObjectProperty(item);
delete grabberV4L2.cached_editors[item];
grabberV4L2.addObjectProperty(item);
conf_editor_v4l2.getEditor(path + item).enable();
});
conf_editor_v4l2.getEditor(path + 'standard').enable();
toggleOption('device', false);
}
}
if (key == 'resolutions')
val != 'custom'
? (toggleOption('width', false), toggleOption('height', false))
: (toggleOption('width', true), toggleOption('height', true));
if (key == 'framerates')
val != 'custom'
? toggleOption('fps', false)
: toggleOption('fps', true);
if (key == 'device_inputs')
val != 'custom'
? toggleOption('input', false)
: toggleOption('input', true);
if (key == 'encoding_format')
val != 'custom'
? toggleOption('encoding', false)
: toggleOption('encoding', true);
});
});
};
// Insert dynamic v4l2 enum schema parts
Object.keys(v4l2_dynamic_enum_schema).forEach(function (key) {
buildSchemaPart(key, v4l2_dynamic_enum_schema, window.serverConfig.grabberV4L2.device);
});
}
var VIDEOGRABBER_AVAIL = window.serverInfo.grabbers.available.includes("v4l2");
if (window.showOptHelp) {
// Instance Capture
@ -224,7 +17,7 @@ $(document).ready(function () {
$('#conf_cont_fg').append(createHelpTable(window.schema.framegrabber.properties, $.i18n("edt_conf_fg_heading_title")));
// V4L2 - hide if not available
if (V4L2_AVAIL) {
if (VIDEOGRABBER_AVAIL) {
$('#conf_cont').append(createRow('conf_cont_v4l'));
$('#conf_cont_v4l').append(createOptPanel('fa-camera', $.i18n("edt_conf_v4l2_heading_title"), 'editor_container_v4l2', 'btn_submit_v4l2'));
$('#conf_cont_v4l').append(createHelpTable(window.schema.grabberV4L2.properties, $.i18n("edt_conf_v4l2_heading_title")));
@ -233,7 +26,7 @@ $(document).ready(function () {
$('#conf_cont').addClass('row');
$('#conf_cont').append(createOptPanel('fa-camera', $.i18n("edt_conf_instCapture_heading_title"), 'editor_container_instCapt', 'btn_submit_instCapt'));
$('#conf_cont').append(createOptPanel('fa-camera', $.i18n("edt_conf_fg_heading_title"), 'editor_container_fg', 'btn_submit_fg'));
if (V4L2_AVAIL) {
if (VIDEOGRABBER_AVAIL) {
$('#conf_cont').append(createOptPanel('fa-camera', $.i18n("edt_conf_v4l2_heading_title"), 'editor_container_v4l2', 'btn_submit_v4l2'));
}
}
@ -244,14 +37,12 @@ $(document).ready(function () {
}, true, true);
// Hide V4L2 elements, if not available
if (!V4L2_AVAIL) {
var instCapOptions = conf_editor_instCapt;
if (!VIDEOGRABBER_AVAIL) {
$('[data-schemapath*="root.instCapture.v4lEnable' + '"]').hide();
$('[data-schemapath*="root.instCapture.v4lPriority' + '"]').hide();
}
conf_editor_instCapt.on('change', function () {
var systemEnable = conf_editor_instCapt.getEditor("root.instCapture.systemEnable").getValue();
if (systemEnable) {
$('[data-schemapath*="root.instCapture.systemPriority' + '"]').show();
@ -261,121 +52,40 @@ $(document).ready(function () {
$('[data-schemapath*="root.instCapture.systemPriority' + '"]').hide();
}
if (V4L2_AVAIL) {
if (VIDEOGRABBER_AVAIL) {
var v4lEnable = conf_editor_instCapt.getEditor("root.instCapture.v4lEnable").getValue();
if (v4lEnable) {
$('[data-schemapath*="root.instCapture.v4lPriority' + '"]').show();
$('#conf_cont_v4l').show();
} else {
}
else {
$('[data-schemapath*="root.instCapture.v4lPriority' + '"]').hide();
$('#conf_cont_v4l').hide();
}
}
conf_editor_instCapt.validate().length || window.readOnlyMode ? $('#btn_submit_instCapt').attr('disabled', true) : $('#btn_submit_instCapt').attr('disabled', false);
});
conf_editor_instCapt.watch('root.instCapture.v4lEnable', () => {
if (VIDEOGRABBER_AVAIL) {
var v4lEnable = conf_editor_instCapt.getEditor("root.instCapture.v4lEnable").getValue();
if (v4lEnable) {
discoverInputSources("video");
}
}
});
$('#btn_submit_instCapt').off().on('click', function () {
requestWriteConfig(conf_editor_instCapt.getValue());
});
$('#btn_submit_fg').off().on('click', function () {
requestWriteConfig(conf_editor_fg.getValue());
});
if (V4L2_AVAIL) {
conf_editor_v4l2 = createJsonEditor('editor_container_v4l2', {
grabberV4L2: window.schema.grabberV4L2
}, true, true);
conf_editor_v4l2.on('change', function () {
conf_editor_v4l2.validate().length || window.readOnlyMode ? $('#btn_submit_v4l2').attr('disabled', true) : $('#btn_submit_v4l2').attr('disabled', false);
});
conf_editor_v4l2.on('ready', function () {
setWatchers(v4l2_dynamic_enum_schema);
if (window.serverConfig.grabberV4L2.available_devices == 'custom' && window.serverConfig.grabberV4L2.device != 'auto')
toggleOption('device', true);
if (window.serverConfig.grabberV4L2.device == 'auto')
conf_editor_v4l2.getEditor('root.grabberV4L2.available_devices').setValue('auto');
if (window.serverConfig.grabberV4L2.available_devices == 'auto') {
['device_inputs', 'standard', 'resolutions', 'framerates', 'encoding_format'].forEach(function (item) {
conf_editor_v4l2.getEditor('root.grabberV4L2.' + item).setValue('auto');
conf_editor_v4l2.getEditor('root.grabberV4L2.' + item).disable();
});
}
if (window.serverConfig.grabberV4L2.device_inputs == 'custom' && window.serverConfig.grabberV4L2.device != 'auto')
toggleOption('input', true);
if (window.serverConfig.grabberV4L2.resolutions == 'custom' && window.serverConfig.grabberV4L2.device != 'auto')
(toggleOption('width', true), toggleOption('height', true));
if (window.serverConfig.grabberV4L2.framerates == 'custom' && window.serverConfig.grabberV4L2.device != 'auto')
toggleOption('fps', true);
if (window.serverConfig.grabberV4L2.encoding_format == 'custom' && window.serverConfig.grabberV4L2.device != 'auto')
toggleOption('encoding', true);
});
$('#btn_submit_v4l2').off().on('click', function () {
var v4l2Options = conf_editor_v4l2.getValue();
if (v4l2Options.grabberV4L2.available_devices != 'custom' && v4l2Options.grabberV4L2.available_devices != 'auto')
v4l2Options.grabberV4L2.device = v4l2Options.grabberV4L2.available_devices;
if (v4l2Options.grabberV4L2.available_devices == 'auto')
v4l2Options.grabberV4L2.device = 'auto';
if (v4l2Options.grabberV4L2.device_inputs != 'custom' && v4l2Options.grabberV4L2.device_inputs != 'auto' && v4l2Options.grabberV4L2.available_devices != 'auto')
v4l2Options.grabberV4L2.input = parseInt(v4l2Options.grabberV4L2.device_inputs);
if (v4l2Options.grabberV4L2.device_inputs == 'auto')
v4l2Options.grabberV4L2.input = -1;
if (v4l2Options.grabberV4L2.encoding_format != 'custom' && v4l2Options.grabberV4L2.encoding_format != 'auto' && v4l2Options.grabberV4L2.available_devices != 'auto')
v4l2Options.grabberV4L2.encoding = v4l2Options.grabberV4L2.encoding_format;
if (v4l2Options.grabberV4L2.encoding_format == 'auto' || v4l2Options.grabberV4L2.encoding_format == 'NO_CHANGE')
v4l2Options.grabberV4L2.encoding = 'NO_CHANGE';
if (v4l2Options.grabberV4L2.resolutions != 'custom' && v4l2Options.grabberV4L2.resolutions != 'auto' && v4l2Options.grabberV4L2.available_devices != 'auto')
(v4l2Options.grabberV4L2.width = parseInt(v4l2Options.grabberV4L2.resolutions.split('x')[0]),
v4l2Options.grabberV4L2.height = parseInt(v4l2Options.grabberV4L2.resolutions.split('x')[1]));
if (v4l2Options.grabberV4L2.resolutions == 'auto')
(v4l2Options.grabberV4L2.width = 0, v4l2Options.grabberV4L2.height = 0);
if (v4l2Options.grabberV4L2.framerates != 'custom' && v4l2Options.grabberV4L2.framerates != 'auto' && v4l2Options.grabberV4L2.available_devices != 'auto')
v4l2Options.grabberV4L2.fps = parseInt(v4l2Options.grabberV4L2.framerates);
if (v4l2Options.grabberV4L2.framerates == 'auto')
v4l2Options.grabberV4L2.fps = 15;
requestWriteConfig(v4l2Options);
});
}
//////////////////////////////////////////////////
//create introduction
if (window.showOptHelp) {
createHint("intro", $.i18n('conf_grabber_fg_intro'), "editor_container_fg");
if (V4L2_AVAIL) {
createHint("intro", $.i18n('conf_grabber_v4l_intro'), "editor_container_v4l2");
}
}
// Framegrabber
conf_editor_fg = createJsonEditor('editor_container_fg', {
framegrabber: window.schema.framegrabber
}, true, true);
conf_editor_fg.on('ready', function () {
var availableGrabbers = window.serverInfo.grabbers.available;
var fgOptions = conf_editor_fg.getEditor('root.framegrabber');
var orginalGrabberTypes = fgOptions.schema.properties.type.enum;
@ -419,7 +129,6 @@ $(document).ready(function () {
}
function filerFgGrabberOptions(type) {
//hide specific options for grabbers found
var grabbers = window.serverInfo.grabbers.available;
if (grabbers.indexOf(type) > -1) {
@ -450,6 +159,344 @@ $(document).ready(function () {
}
};
removeOverlay();
});
$('#btn_submit_fg').off().on('click', function () {
requestWriteConfig(conf_editor_fg.getValue());
});
// External Input Sources (Video-Grabbers)
var configuredDevice = "";
var discoveredInputSources = {};
var deviceProperties = {};
if (VIDEOGRABBER_AVAIL) {
conf_editor_v4l2 = createJsonEditor('editor_container_v4l2', {
grabberV4L2: window.schema.grabberV4L2
}, true, true);
conf_editor_v4l2.on('ready', function () {
var v4lEnable = conf_editor_instCapt.getEditor("root.instCapture.v4lEnable").getValue();
if (v4lEnable) {
discoverInputSources("video");
}
});
conf_editor_v4l2.on('change', function () {
var deviceSelected = conf_editor_v4l2.getEditor("root.grabberV4L2.available_devices").getValue();
if (!conf_editor_v4l2.validate().length) {
if (deviceSelected !== "NONE") {
window.readOnlyMode ? $('#btn_submit_v4l2').attr('disabled', true) : $('#btn_submit_v4l2').attr('disabled', false);
}
}
});
conf_editor_v4l2.watch('root.grabberV4L2.available_devices', () => {
var deviceSelected = conf_editor_v4l2.getEditor("root.grabberV4L2.available_devices").getValue();
if (deviceSelected === "NONE" || deviceSelected === "") {
$('#btn_submit_v4l2').attr('disabled', true);
}
else {
var addSchemaElements = {};
var enumVals = [];
var enumTitelVals = [];
var enumDefaultVal = "";
var deviceProperties = getPropertiesOfDevice(deviceSelected);
//Update hidden input element
conf_editor_v4l2.getEditor("root.grabberV4L2.device").setValue(deviceProperties.device);
var video_inputs = deviceProperties.video_inputs;
if (video_inputs.length <= 1) {
addSchemaElements.access = "expert";
}
for (const video_input of video_inputs) {
enumVals.push(video_input.inputIdx);
enumTitelVals.push(video_input.name);
}
if (enumVals.length > 0) {
if (deviceSelected === configuredDevice) {
var configuredVideoInput = window.serverConfig.grabberV4L2.input;
if ($.inArray(configuredVideoInput, enumVals) != -1) {
enumDefaultVal = configuredVideoInput;
}
}
updateJsonEditorSelection(conf_editor_v4l2.getEditor('root.grabberV4L2'),
'device_inputs', addSchemaElements, enumVals, enumTitelVals, enumDefaultVal, false);
}
if (!window.readOnlyMode) {
$('#btn_submit_v4l2').attr('disabled', false);
}
}
});
conf_editor_v4l2.watch('root.grabberV4L2.device_inputs', () => {
var deviceSelected = conf_editor_v4l2.getEditor("root.grabberV4L2.available_devices").getValue();
var videoInputSelected = conf_editor_v4l2.getEditor("root.grabberV4L2.device_inputs").getValue();
var addSchemaElements = {};
var enumVals = [];
var enumTitelVals = [];
var enumDefaultVal = "";
var deviceProperties = getPropertiesOfDevice(deviceSelected);
var formats = deviceProperties.video_inputs[videoInputSelected].formats;
//Hide, if only one record available for selection
if (formats.length <= 1) {
addSchemaElements.access = "expert";
}
for (var i = 0; i < formats.length; i++) {
if (formats[i].format) {
enumVals.push(formats[i].format);
enumTitelVals.push(formats[i].format.toUpperCase());
}
else {
enumVals.push("NONE");
}
}
if (enumVals.length > 0) {
if (deviceSelected === configuredDevice) {
var configuredEncoding = window.serverConfig.grabberV4L2.encoding;
if ($.inArray(configuredEncoding, enumVals) != -1) {
enumDefaultVal = configuredEncoding;
}
}
updateJsonEditorSelection(conf_editor_v4l2.getEditor('root.grabberV4L2'),
'encoding', addSchemaElements, enumVals, enumTitelVals, enumDefaultVal, false);
}
var enumVals = [];
var enumDefaultVal = "";
var standards = deviceProperties.video_inputs[videoInputSelected].standards;
if (!standards) {
enumVals.push("NONE");
addSchemaElements.options = { "hidden": true };
} else {
enumVals = standards;
}
if (enumVals.length > 0) {
if (deviceSelected === configuredDevice) {
var configuredStandard = window.serverConfig.grabberV4L2.standard;
if ($.inArray(configuredStandard, enumVals) != -1) {
enumDefaultVal = configuredStandard;
}
}
updateJsonEditorSelection(conf_editor_v4l2.getEditor('root.grabberV4L2'),
'standard', addSchemaElements, enumVals, [], enumDefaultVal, false);
}
if (!window.readOnlyMode) {
$('#btn_submit_v4l2').attr('disabled', false);
}
});
conf_editor_v4l2.watch('root.grabberV4L2.encoding', () => {
var deviceSelected = conf_editor_v4l2.getEditor("root.grabberV4L2.available_devices").getValue();
var videoInputSelected = conf_editor_v4l2.getEditor("root.grabberV4L2.device_inputs").getValue();
var formatSelected = conf_editor_v4l2.getEditor("root.grabberV4L2.encoding").getValue();
//Update hidden input element
conf_editor_v4l2.getEditor("root.grabberV4L2.input").setValue(parseInt(videoInputSelected));
var addSchemaElements = {};
var enumVals = [];
var enumTitelVals = [];
var enumDefaultVal = "";
var deviceProperties = getPropertiesOfDevice(deviceSelected);
var formats = deviceProperties.video_inputs[videoInputSelected].formats;
var formatIdx = 0;
if (formatSelected !== "NONE") {
formatIdx = formats.findIndex(x => x.format === formatSelected);
}
var resolutions = formats[formatIdx].resolutions;
if (resolutions.length <= 1) {
addSchemaElements.access = "expert";
} else {
resolutions.sort(compareTwoValues('width', 'height', 'asc'));
}
for (var i = 0; i < resolutions.length; i++) {
enumVals.push(i);
var resolutionText = resolutions[i].width + "x" + resolutions[i].height;
enumTitelVals.push(resolutionText);
}
if (enumVals.length > 0) {
if (deviceSelected === configuredDevice) {
var configuredResolutionText = window.serverConfig.grabberV4L2.width + "x" + window.serverConfig.grabberV4L2.height;
var idx = $.inArray(configuredResolutionText, enumTitelVals)
if (idx != -1) {
enumDefaultVal = idx;
}
}
updateJsonEditorSelection(conf_editor_v4l2.getEditor('root.grabberV4L2'),
'resolutions', addSchemaElements, enumVals, enumTitelVals, enumDefaultVal, false);
}
if (!window.readOnlyMode) {
$('#btn_submit_v4l2').attr('disabled', false);
}
});
conf_editor_v4l2.watch('root.grabberV4L2.resolutions', () => {
var deviceSelected = conf_editor_v4l2.getEditor("root.grabberV4L2.available_devices").getValue();
var videoInputSelected = conf_editor_v4l2.getEditor("root.grabberV4L2.device_inputs").getValue();
var formatSelected = conf_editor_v4l2.getEditor("root.grabberV4L2.encoding").getValue();
var resolutionSelected = conf_editor_v4l2.getEditor("root.grabberV4L2.resolutions").getValue();
var addSchemaElements = {};
var enumVals = [];
var enumDefaultVal = "";
var deviceProperties = getPropertiesOfDevice(deviceSelected);
var formats = deviceProperties.video_inputs[videoInputSelected].formats;
var formatIdx = 0;
if (formatSelected !== "NONE") {
formatIdx = formats.findIndex(x => x.format === formatSelected);
}
//Update hidden resolution related elements
var width = parseInt(formats[formatIdx].resolutions[resolutionSelected].width);
conf_editor_v4l2.getEditor("root.grabberV4L2.width").setValue(width);
var height = parseInt(formats[formatIdx].resolutions[resolutionSelected].height);
conf_editor_v4l2.getEditor("root.grabberV4L2.height").setValue(height);
var fps = formats[formatIdx].resolutions[resolutionSelected].fps;
if (!fps) {
enumVals.push("NONE");
addSchemaElements.options = { "hidden": true };
} else {
fps.sort((a, b) => a - b);
for (var i = 0; i < fps.length; i++) {
enumVals.push(fps[i]);
}
}
if (enumVals.length <= 1) {
addSchemaElements.access = "expert";
}
if (enumVals.length > 0) {
if (deviceSelected === configuredDevice) {
var configuredFps = window.serverConfig.grabberV4L2.fps;
if ($.inArray(configuredFps, enumVals) != -1) {
enumDefaultVal = configuredFps;
}
}
updateJsonEditorSelection(conf_editor_v4l2.getEditor('root.grabberV4L2'),
'framerates', addSchemaElements, enumVals, [], enumDefaultVal, false);
}
if (!window.readOnlyMode) {
$('#btn_submit_v4l2').attr('disabled', false);
}
});
conf_editor_v4l2.watch('root.grabberV4L2.framerates', () => {
//Update hidden fps element
var fps = 0;
var framerates = conf_editor_v4l2.getEditor("root.grabberV4L2.framerates").getValue();
if (framerates !== "NONE") {
fps = parseInt(framerates);
}
//Show Frameskipping only when more than 2 fps
if (fps > 2) {
$('[data-schemapath*="root.grabberV4L2.fpsSoftwareDecimation').toggle(true);
}
else {
$('[data-schemapath*="root.grabberV4L2.fpsSoftwareDecimation').toggle(false);
}
conf_editor_v4l2.getEditor("root.grabberV4L2.fps").setValue(fps);
});
$('#btn_submit_v4l2').off().on('click', function () {
var v4l2Options = conf_editor_v4l2.getValue();
requestWriteConfig(v4l2Options);
});
}
//////////////////////////////////////////////////
//create introduction
if (window.showOptHelp) {
createHint("intro", $.i18n('conf_grabber_fg_intro'), "editor_container_fg");
if (VIDEOGRABBER_AVAIL) {
createHint("intro", $.i18n('conf_grabber_v4l_intro'), "editor_container_v4l2");
}
}
removeOverlay();
// build dynamic enum
var updateVideoSourcesList = function (type, discoveryInfo) {
var enumVals = [];
var enumTitelVals = [];
var enumDefaultVal = "";
if (jQuery.isEmptyObject(discoveryInfo)) {
enumVals.push("NONE");
enumTitelVals.push($.i18n('edt_conf_grabber_discovered_none'));
conf_editor_v4l2.getEditor('root.grabberV4L2').disable();
}
else {
for (const device of discoveryInfo) {
enumVals.push(device.device_name);
}
conf_editor_v4l2.getEditor('root.grabberV4L2').enable();
}
if (enumVals.length > 0) {
configuredDevice = window.serverConfig.grabberV4L2.available_devices;
if ($.inArray(configuredDevice, enumVals) != -1) {
enumDefaultVal = configuredDevice;
}
updateJsonEditorSelection(conf_editor_v4l2.getEditor('root.grabberV4L2'),
'available_devices', {}, enumVals, enumTitelVals, enumDefaultVal, false);
}
}
async function discoverInputSources(type, params) {
const result = await requestInputSourcesDiscovery(type, params);
var discoveryResult;
if (result && !result.error) {
discoveryResult = result.info;
}
else {
discoveryResult = {
"video_sources": []
}
}
discoveredInputSources = discoveryResult.video_sources;
updateVideoSourcesList(type, discoveredInputSources);
}
function getPropertiesOfDevice(deviceName) {
deviceProperties = {};
for (const deviceRecord of discoveredInputSources) {
if (deviceRecord.device_name === deviceName) {
deviceProperties = deviceRecord;
break;
}
}
return deviceProperties;
}
});

View File

@ -470,8 +470,14 @@ async function requestLedDeviceProperties(type, params)
function requestLedDeviceIdentification(type, params)
{
//sendToHyperion("leddevice", "identify", '"ledDeviceType": "'+type+'","params": '+JSON.stringify(params)+'');
let data = { ledDeviceType: type, params: params };
return sendAsyncToHyperion("leddevice", "identify", data, Math.floor(Math.random() * 1000));
}
async function requestInputSourcesDiscovery(type, params) {
let data = { sourceType: type, params: params };
return sendAsyncToHyperion("inputsource", "discover", data, Math.floor(Math.random() * 1000));
}

View File

@ -549,9 +549,9 @@ function updateJsonEditorSelection(editor, key, addElements, newEnumVals, newTit
{
"type": "string",
"enum": [],
"propertyOrder": 1,
"required": true,
"options": { "enum_titles": [] }
"options": { "enum_titles": [], "infoText": "" },
"propertyOrder": 1
};
//Add additional elements to overwrite defaults
@ -559,6 +559,21 @@ function updateJsonEditorSelection(editor, key, addElements, newEnumVals, newTit
newSchema[key][item] = addElements[item];
}
if (orginalProperties) {
if (orginalProperties["title"]) {
newSchema[key]["title"] = orginalProperties["title"];
}
if (orginalProperties["options"] && orginalProperties["options"]["infoText"]) {
newSchema[key]["options"]["infoText"] = orginalProperties["options"]["infoText"];
}
if (orginalProperties["propertyOrder"]) {
newSchema[key]["propertyOrder"] = orginalProperties["propertyOrder"];
}
}
if (addCustom) {
newEnumVals.push("custom");
newTitelVals.push("edt_conf_enum_custom");
@ -580,8 +595,66 @@ function updateJsonEditorSelection(editor, key, addElements, newEnumVals, newTit
newSchema[key]["default"] = newDefaultVal;
}
editor.original_schema.properties = orginalProperties;
editor.schema.properties = newSchema;
editor.original_schema.properties[key] = orginalProperties;
editor.schema.properties[key] = newSchema[key];
editor.removeObjectProperty(key);
delete editor.cached_editors[key];
editor.addObjectProperty(key);
}
function updateJsonEditorMultiSelection(editor, key, addElements, newEnumVals, newTitelVals, newDefaultVal) {
var orginalProperties = editor.schema.properties[key];
var newSchema = [];
newSchema[key] =
{
"type": "array",
"format": "select",
"items": {
"type": "string",
"enum": [],
"options": { "enum_titles": [] },
},
"options": { "infoText": "" },
"default": [],
"propertyOrder": 1
};
//Add additional elements to overwrite defaults
for (var item in addElements) {
newSchema[key][item] = addElements[item];
}
if (orginalProperties) {
if (orginalProperties["title"]) {
newSchema[key]["title"] = orginalProperties["title"];
}
if (orginalProperties["options"] && orginalProperties["options"]["infoText"]) {
newSchema[key]["options"]["infoText"] = orginalProperties["options"]["infoText"];
}
if (orginalProperties["propertyOrder"]) {
newSchema[key]["propertyOrder"] = orginalProperties["propertyOrder"];
}
}
if (newEnumVals) {
newSchema[key]["items"]["enum"] = newEnumVals;
}
if (newTitelVals) {
newSchema[key]["items"]["options"]["enum_titles"] = newTitelVals;
}
if (newDefaultVal) {
newSchema[key]["default"] = newDefaultVal;
}
editor.original_schema.properties[key] = orginalProperties;
editor.schema.properties[key] = newSchema[key];
editor.removeObjectProperty(key);
delete editor.cached_editors[key];
@ -794,6 +867,49 @@ function createOptPanel(phicon, phead, bodyid, footerid)
return createPanel(phead, "", pfooter, "panel-default", bodyid);
}
function compareTwoValues(key1, key2, order = 'asc') {
return function innerSort(a, b) {
if (!a.hasOwnProperty(key1) || !b.hasOwnProperty(key1)) {
// property key1 doesn't exist on either object
return 0;
}
const varA1 = (typeof a[key1] === 'string')
? a[key1].toUpperCase() : a[key1];
const varB1 = (typeof b[key1] === 'string')
? b[key1].toUpperCase() : b[key1];
let comparison = 0;
if (varA1 > varB1) {
comparison = 1;
} else {
if (varA1 < varB1) {
comparison = -1;
} else {
if (!a.hasOwnProperty(key2) || !b.hasOwnProperty(key2)) {
// property key2 doesn't exist on either object
return 0;
}
const varA2 = (typeof a[key2] === 'string')
? a[key2].toUpperCase() : a[key2];
const varB2 = (typeof b[key1] === 'string')
? b[key2].toUpperCase() : b[key2];
if (varA2 > varB2) {
comparison = 1;
} else {
comparison = -1;
}
}
}
return (
(order === 'desc') ? (comparison * -1) : comparison
);
};
}
function sortProperties(list)
{
for(var key in list)

View File

@ -278,6 +278,12 @@ private:
///
void handleLedDeviceCommand(const QJsonObject &message, const QString &command, int tan);
/// Handle an incoming JSON message regarding Input Sources (Grabbers)
///
/// @param message the incoming message
///
void handleInputSourceCommand(const QJsonObject& message, const QString& command, int tan);
///
/// Handle an incoming JSON message of unknown type
///

View File

@ -0,0 +1,28 @@
{
"type":"object",
"required":true,
"properties": {
"command": {
"type": "string",
"required": true,
"enum": [ "inputsource" ]
},
"tan": {
"type": "integer"
},
"subcommand": {
"type": "string",
"required": true,
"enum": [ "discover", "getProperties" ]
},
"sourceType": {
"type": "string",
"required": true
},
"params": {
"type": "object",
"required": false
}
},
"additionalProperties": false
}

View File

@ -5,7 +5,7 @@
"command": {
"type" : "string",
"required" : true,
"enum" : ["color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging", "processing", "sysinfo", "videomode", "authorize", "instance", "leddevice", "transform", "correction" , "temperature"]
"enum": [ "color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging", "processing", "sysinfo", "videomode", "authorize", "instance", "leddevice", "inputsource", "transform", "correction", "temperature" ]
}
}
}

View File

@ -21,6 +21,7 @@
<file alias="schema-authorize">JSONRPC_schema/schema-authorize.json</file>
<file alias="schema-instance">JSONRPC_schema/schema-instance.json</file>
<file alias="schema-leddevice">JSONRPC_schema/schema-leddevice.json</file>
<file alias="schema-inputsource">JSONRPC_schema/schema-inputsource.json</file>
<!-- The following schemas are derecated but used to ensure backward compatibility with hyperion Classic remote control-->
<file alias="schema-transform">JSONRPC_schema/schema-hyperion-classic.json</file>
<file alias="schema-correction">JSONRPC_schema/schema-hyperion-classic.json</file>

View File

@ -174,6 +174,8 @@ proceed:
handleInstanceCommand(message, command, tan);
else if (command == "leddevice")
handleLedDeviceCommand(message, command, tan);
else if (command == "inputsource")
handleInputSourceCommand(message, command, tan);
// BEGIN | The following commands are deprecated but used to ensure backward compatibility with hyperion Classic remote control
else if (command == "clearall")
@ -487,75 +489,6 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString
availableGrabbers.append(grabber);
}
#endif
#if defined(ENABLE_V4L2) || defined(ENABLE_MF)
QJsonArray availableDevices;
for (const auto& devicePath : GrabberWrapper::getInstance()->getDevices())
{
QJsonObject device;
device["device"] = devicePath;
device["device_name"] = GrabberWrapper::getInstance()->getDeviceName(devicePath);
device["type"] = "v4l2";
QJsonArray video_inputs;
QMultiMap<QString, int> inputs = GrabberWrapper::getInstance()->getDeviceInputs(devicePath);
for (auto input = inputs.begin(); input != inputs.end(); input++)
{
QJsonObject in;
in["name"] = input.key();
in["inputIdx"] = input.value();
QJsonArray standards;
QList<VideoStandard> videoStandards = GrabberWrapper::getInstance()->getAvailableDeviceStandards(devicePath, input.value());
for (auto standard : videoStandards)
{
standards.append(VideoStandard2String(standard));
}
QJsonArray formats;
QStringList encodingFormats = GrabberWrapper::getInstance()->getAvailableEncodingFormats(devicePath, input.value());
for (auto encodingFormat : encodingFormats)
{
QJsonObject format;
format["format"] = encodingFormat;
QJsonArray resolutionArray;
QMultiMap<int, int> deviceResolutions = GrabberWrapper::getInstance()->getAvailableDeviceResolutions(devicePath, input.value(), parsePixelFormat(encodingFormat));
for (auto width_height = deviceResolutions.begin(); width_height != deviceResolutions.end(); width_height++)
{
QJsonObject resolution;
resolution["width"] = width_height.key();
resolution["height"] = width_height.value();
QJsonArray fps;
QIntList framerates = GrabberWrapper::getInstance()->getAvailableDeviceFramerates(devicePath, input.value(), parsePixelFormat(encodingFormat), width_height.key(), width_height.value());
for (auto framerate : framerates)
{
fps.append(framerate);
}
resolution["fps"] = fps;
resolutionArray.append(resolution);
}
format["resolutions"] = resolutionArray;
formats.append(format);
}
in["standards"] = standards;
in["formats"] = formats;
video_inputs.append(in);
}
device["video_inputs"] = video_inputs;
availableDevices.append(device);
}
grabbers["video_sources"] = availableDevices;
#endif
grabbers["available"] = availableGrabbers;
@ -1485,6 +1418,117 @@ void JsonAPI::handleLedDeviceCommand(const QJsonObject &message, const QString &
}
}
void JsonAPI::handleInputSourceCommand(const QJsonObject& message, const QString& command, int tan)
{
Debug(_log, "message: [%s]", QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toUtf8().constData());
const QString& subc = message["subcommand"].toString().trimmed();
const QString& sourceType = message["sourceType"].toString().trimmed();
QString full_command = command + "-" + subc;
// TODO: Validate that source type is a valid one
/* if ( ! valid type )
{
sendErrorReply("Unknown device", full_command, tan);
}
else
*/ {
if (subc == "discover")
{
QJsonObject inputSourcesDiscovered;
inputSourcesDiscovered.insert("sourceType", sourceType);
QJsonArray videoInputs;
#if defined(ENABLE_V4L2) || defined(ENABLE_MF)
if (sourceType == "video" )
{
//for (const auto& instance : GrabberWrapper::getInstance()->getDevices())
//{
for (const auto& devicePath : GrabberWrapper::getInstance()->getDevices())
{
QJsonObject device;
device["device"] = devicePath;
device["device_name"] = GrabberWrapper::getInstance()->getDeviceName(devicePath);
device["type"] = "v4l2";
QJsonArray video_inputs;
QMultiMap<QString, int> inputs = GrabberWrapper::getInstance()->getDeviceInputs(devicePath);
for (auto input = inputs.begin(); input != inputs.end(); input++)
{
QJsonObject in;
in["name"] = input.key();
in["inputIdx"] = input.value();
QJsonArray standards;
QList<VideoStandard> videoStandards = GrabberWrapper::getInstance()->getAvailableDeviceStandards(devicePath, input.value());
for (auto standard : videoStandards)
{
standards.append(VideoStandard2String(standard));
}
if (!standards.isEmpty())
{
in["standards"] = standards;
}
QJsonArray formats;
QStringList encodingFormats = GrabberWrapper::getInstance()->getAvailableEncodingFormats(devicePath, input.value());
for (auto encodingFormat : encodingFormats)
{
QJsonObject format;
format["format"] = encodingFormat;
QJsonArray resolutionArray;
QMultiMap<int, int> deviceResolutions = GrabberWrapper::getInstance()->getAvailableDeviceResolutions(devicePath, input.value(), parsePixelFormat(encodingFormat));
for (auto width_height = deviceResolutions.begin(); width_height != deviceResolutions.end(); width_height++)
{
QJsonObject resolution;
resolution["width"] = width_height.key();
resolution["height"] = width_height.value();
QJsonArray fps;
QIntList framerates = GrabberWrapper::getInstance()->getAvailableDeviceFramerates(devicePath, input.value(), parsePixelFormat(encodingFormat), width_height.key(), width_height.value());
for (auto framerate : framerates)
{
fps.append(framerate);
}
resolution["fps"] = fps;
resolutionArray.append(resolution);
}
format["resolutions"] = resolutionArray;
formats.append(format);
}
in["formats"] = formats;
video_inputs.append(in);
}
device["video_inputs"] = video_inputs;
videoInputs.append(device);
}
}
#endif
inputSourcesDiscovered["video_sources"] = videoInputs;
Debug(_log, "response: [%s]", QString(QJsonDocument(inputSourcesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData());
sendSuccessDataReply(QJsonDocument(inputSourcesDiscovered), full_command, tan);
}
else
{
sendErrorReply("Unknown or missing subcommand", full_command, tan);
}
}
}
void JsonAPI::handleNotImplemented(const QString &command, int tan)
{
sendErrorReply("Command not implemented", command, tan);

View File

@ -234,5 +234,18 @@ bool SettingsManager::handleConfigUpgrade(QJsonObject& config)
Debug(_log,"LED Layout migrated");
}
}
if (config.contains("grabberV4L2"))
{
QJsonObject newGrabberV4L2Config = config["grabberV4L2"].toObject();
if (newGrabberV4L2Config.contains("encoding_format"))
{
newGrabberV4L2Config.remove("encoding_format");
config["grabberV4L2"] = newGrabberV4L2Config;
migrated = true;
Debug(_log, "GrabberV4L2 Layout migrated");
}
}
return migrated;
}

View File

@ -2,345 +2,350 @@
"type" : "object",
"required" : true,
"title" : "edt_conf_v4l2_heading_title",
"properties" :
{
"device" :
{
"type" : "string",
"title" : "edt_conf_enum_custom",
"default" : "auto",
"options" : {
"hidden":true
"properties": {
"available_devices": {
"type": "string",
"title": "edt_conf_v4l2_device_title",
"propertyOrder": 1,
"required": true
},
"required" : true,
"propertyOrder" : 2,
"comment" : "The 'available_devices' settings are dynamically inserted into the WebUI under PropertyOrder '1'."
"device": {
"type": "string",
"title": "edt_conf_enum_custom",
"options": {
"hidden": true
},
"input" :
{
"type" : "integer",
"title" : "edt_conf_enum_custom",
"default" : 0,
"options" : {
"hidden":true
"required": true,
"comment": "The 'available_devices' settings are dynamically inserted into the WebUI under PropertyOrder '1'.",
"propertyOrder": 2
},
"required" : true,
"propertyOrder" : 4,
"comment" : "The 'device_inputs' settings are dynamically inserted into the WebUI under PropertyOrder '3'."
"device_inputs": {
"type": "string",
"title": "edt_conf_v4l2_input_title",
"propertyOrder": 3,
"required": true
},
"encoding" :
{
"type" : "string",
"title" : "edt_conf_enum_custom",
"default" : "auto",
"options" : {
"hidden":true
"input": {
"type": "integer",
"title": "edt_conf_enum_custom",
"default": 0,
"options": {
"hidden": true
},
"required" : true,
"propertyOrder" : 6,
"comment" : "The 'device_encodings' settings are dynamically inserted into the WebUI under PropertyOrder '5'."
"required": true,
"propertyOrder": 4,
"comment": "The 'device_inputs' settings are dynamically inserted into the WebUI under PropertyOrder '3'."
},
"standard" :
{
"type" : "string",
"title" : "edt_conf_v4l2_standard_title",
"enum" : ["NO_CHANGE", "PAL","NTSC","SECAM"],
"default" : "NO_CHANGE",
"options" : {
"enum_titles" : ["edt_conf_enum_NO_CHANGE", "edt_conf_enum_PAL", "edt_conf_enum_NTSC", "edt_conf_enum_SECAM"]
"standard": {
"type": "string",
"title": "edt_conf_v4l2_standard_title",
"default": "auto",
"required": true,
"propertyOrder": 5
},
"required" : true,
"propertyOrder" : 7
"encoding": {
"type": "string",
"title": "edt_conf_v4l2_encoding_title",
"default": "auto",
"required": true,
"propertyOrder": 6
},
"flip" :
{
"type" : "string",
"title" : "edt_conf_v4l2_flip_title",
"enum" : ["NO_CHANGE", "HORIZONTAL","VERTICAL","BOTH"],
"default" : "NO_CHANGE",
"options" : {
"enum_titles" : ["edt_conf_enum_NO_CHANGE", "edt_conf_enum_HORIZONTAL", "edt_conf_enum_VERTICAL", "edt_conf_enum_BOTH"]
"resolutions": {
"type": "string",
"title": "edt_conf_v4l2_resolution_title",
"propertyOrder": 7,
"required": true
},
"required" : true,
"propertyOrder" : 8
"width": {
"type": "integer",
"title": "edt_conf_fg_width_title",
"default": 0,
"minimum": 0,
"append": "edt_append_pixel",
"options": {
"hidden": true
},
"width" :
{
"type" : "integer",
"title" : "edt_conf_fg_width_title",
"default" : 0,
"minimum" : 0,
"append" : "edt_append_pixel",
"options" : {
"hidden":true
"required": true,
"propertyOrder": 8,
"comment": "The 'resolutions' settings are dynamically inserted into the WebUI under PropertyOrder '7'."
},
"required" : true,
"propertyOrder" : 10,
"comment" : "The 'resolutions' settings are dynamically inserted into the WebUI under PropertyOrder '9'."
"height": {
"type": "integer",
"title": "edt_conf_fg_height_title",
"default": 0,
"minimum": 0,
"append": "edt_append_pixel",
"options": {
"hidden": true
},
"height" :
{
"type" : "integer",
"title" : "edt_conf_fg_height_title",
"default" : 0,
"minimum" : 0,
"append" : "edt_append_pixel",
"options" : {
"hidden":true
"required": true,
"propertyOrder": 9,
"comment": "The 'resolutions' settings are dynamically inserted into the WebUI under PropertyOrder '7'."
},
"required" : true,
"propertyOrder" : 11,
"comment" : "The 'resolutions' settings are dynamically inserted into the WebUI under PropertyOrder '9'."
"framerates": {
"type": "string",
"title": "edt_conf_v4l2_framerate_title",
"propertyOrder": 10,
"required": true
},
"fps" :
{
"type" : "integer",
"title" : "edt_conf_enum_custom",
"default" : 15,
"minimum" : 1,
"append" : "fps",
"options" : {
"hidden":true
"fps": {
"type": "integer",
"title": "edt_conf_enum_custom",
"default": 15,
"minimum": 0,
"append": "fps",
"options": {
"hidden": true
},
"required" : true,
"propertyOrder" : 13,
"comment" : "The 'framerates' setting is dynamically inserted into the WebUI under PropertyOrder '12'."
"required": true,
"propertyOrder": 11,
"comment": "The 'framerates' setting is dynamically inserted into the WebUI under PropertyOrder '10'."
},
"fpsSoftwareDecimation" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_fpsSoftwareDecimation_title",
"minimum" : 0,
"maximum" : 60,
"default" : 0,
"required" : true,
"propertyOrder" : 14
"fpsSoftwareDecimation": {
"type": "integer",
"title": "edt_conf_v4l2_fpsSoftwareDecimation_title",
"minimum": 0,
"maximum": 60,
"default": 0,
"required": true,
"access": "advanced",
"propertyOrder": 12
},
"sizeDecimation" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_sizeDecimation_title",
"minimum" : 1,
"maximum" : 30,
"default" : 6,
"required" : true,
"propertyOrder" : 15
"flip": {
"type": "string",
"title": "edt_conf_v4l2_flip_title",
"enum": [ "NO_CHANGE", "HORIZONTAL", "VERTICAL", "BOTH" ],
"default": "NO_CHANGE",
"options": {
"enum_titles": [ "edt_conf_enum_NO_CHANGE", "edt_conf_enum_HORIZONTAL", "edt_conf_enum_VERTICAL", "edt_conf_enum_BOTH" ]
},
"cropLeft" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_cropLeft_title",
"minimum" : 0,
"default" : 0,
"append" : "edt_append_pixel",
"required" : true,
"propertyOrder" : 16
"required": true,
"access": "advanced",
"propertyOrder": 13
},
"cropRight" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_cropRight_title",
"minimum" : 0,
"default" : 0,
"append" : "edt_append_pixel",
"required" : true,
"propertyOrder" : 17
"sizeDecimation": {
"type": "integer",
"title": "edt_conf_v4l2_sizeDecimation_title",
"minimum": 1,
"maximum": 30,
"default": 6,
"required": true,
"propertyOrder": 14
},
"cropTop" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_cropTop_title",
"minimum" : 0,
"default" : 0,
"append" : "edt_append_pixel",
"required" : true,
"propertyOrder" : 18
"cropLeft": {
"type": "integer",
"title": "edt_conf_v4l2_cropLeft_title",
"minimum": 0,
"default": 0,
"append": "edt_append_pixel",
"required": true,
"access": "advanced",
"propertyOrder": 15
},
"cropBottom" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_cropBottom_title",
"minimum" : 0,
"default" : 0,
"append" : "edt_append_pixel",
"required" : true,
"propertyOrder" : 19
"cropRight": {
"type": "integer",
"title": "edt_conf_v4l2_cropRight_title",
"minimum": 0,
"default": 0,
"append": "edt_append_pixel",
"required": true,
"access": "advanced",
"propertyOrder": 16
},
"cecDetection" :
{
"type" : "boolean",
"title" : "edt_conf_v4l2_cecDetection_title",
"default" : false,
"required" : true,
"propertyOrder" : 20
"cropTop": {
"type": "integer",
"title": "edt_conf_v4l2_cropTop_title",
"minimum": 0,
"default": 0,
"append": "edt_append_pixel",
"required": true,
"access": "advanced",
"propertyOrder": 17
},
"signalDetection" :
{
"type" : "boolean",
"title" : "edt_conf_v4l2_signalDetection_title",
"default" : false,
"required" : true,
"propertyOrder" : 21
"cropBottom": {
"type": "integer",
"title": "edt_conf_v4l2_cropBottom_title",
"minimum": 0,
"default": 0,
"append": "edt_append_pixel",
"required": true,
"access": "advanced",
"propertyOrder": 18
},
"redSignalThreshold" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_redSignalThreshold_title",
"minimum" : 0,
"maximum" : 100,
"default" : 5,
"append" : "edt_append_percent",
"cecDetection": {
"type": "boolean",
"title": "edt_conf_v4l2_cecDetection_title",
"default": false,
"required": true,
"propertyOrder": 19
},
"signalDetection": {
"type": "boolean",
"title": "edt_conf_v4l2_signalDetection_title",
"default": false,
"required": true,
"access": "advanced",
"propertyOrder": 20
},
"redSignalThreshold": {
"type": "integer",
"title": "edt_conf_v4l2_redSignalThreshold_title",
"minimum": 0,
"maximum": 100,
"default": 5,
"append": "edt_append_percent",
"options": {
"dependencies": {
"signalDetection": true
}
},
"required" : true,
"propertyOrder" : 22
"access": "advanced",
"required": true,
"propertyOrder": 21
},
"greenSignalThreshold" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_greenSignalThreshold_title",
"minimum" : 0,
"maximum" : 100,
"default" : 5,
"append" : "edt_append_percent",
"greenSignalThreshold": {
"type": "integer",
"title": "edt_conf_v4l2_greenSignalThreshold_title",
"minimum": 0,
"maximum": 100,
"default": 5,
"append": "edt_append_percent",
"options": {
"dependencies": {
"signalDetection": true
}
},
"required" : true,
"propertyOrder" : 23
"required": true,
"access": "advanced",
"propertyOrder": 22
},
"blueSignalThreshold" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_blueSignalThreshold_title",
"minimum" : 0,
"maximum" : 100,
"default" : 5,
"append" : "edt_append_percent",
"blueSignalThreshold": {
"type": "integer",
"title": "edt_conf_v4l2_blueSignalThreshold_title",
"minimum": 0,
"maximum": 100,
"default": 5,
"append": "edt_append_percent",
"options": {
"dependencies": {
"signalDetection": true
}
},
"required" : true,
"propertyOrder" : 24
"required": true,
"access": "advanced",
"propertyOrder": 23
},
"noSignalCounterThreshold" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_noSignalCounterThreshold_title",
"minimum" : 1,
"maximum" : 1000,
"default" : 200,
"noSignalCounterThreshold": {
"type": "integer",
"title": "edt_conf_v4l2_noSignalCounterThreshold_title",
"minimum": 1,
"maximum": 1000,
"default": 200,
"options": {
"dependencies": {
"signalDetection": true
}
},
"required" : true,
"propertyOrder" : 25
"required": true,
"access": "advanced",
"propertyOrder": 24
},
"sDVOffsetMin" :
{
"type" : "number",
"title" : "edt_conf_v4l2_sDVOffsetMin_title",
"minimum" : 0.0,
"maximum" : 1.0,
"default" : 0.25,
"step" : 0.01,
"sDVOffsetMin": {
"type": "number",
"title": "edt_conf_v4l2_sDVOffsetMin_title",
"minimum": 0.0,
"maximum": 1.0,
"default": 0.25,
"step": 0.01,
"options": {
"dependencies": {
"signalDetection": true
}
},
"required" : true,
"propertyOrder" : 26
"required": true,
"access": "advanced",
"propertyOrder": 25
},
"sDVOffsetMax" :
{
"type" : "number",
"title" : "edt_conf_v4l2_sDVOffsetMax_title",
"minimum" : 0.0,
"maximum" : 1.0,
"default" : 0.75,
"step" : 0.01,
"sDVOffsetMax": {
"type": "number",
"title": "edt_conf_v4l2_sDVOffsetMax_title",
"minimum": 0.0,
"maximum": 1.0,
"default": 0.75,
"step": 0.01,
"options": {
"dependencies": {
"signalDetection": true
}
},
"required" : true,
"propertyOrder" : 27
"required": true,
"access": "advanced",
"propertyOrder": 26
},
"sDHOffsetMin" :
{
"type" : "number",
"title" : "edt_conf_v4l2_sDHOffsetMin_title",
"minimum" : 0.0,
"maximum" : 1.0,
"default" : 0.25,
"step" : 0.01,
"sDHOffsetMin": {
"type": "number",
"title": "edt_conf_v4l2_sDHOffsetMin_title",
"minimum": 0.0,
"maximum": 1.0,
"default": 0.25,
"step": 0.01,
"options": {
"dependencies": {
"signalDetection": true
}
},
"required" : true,
"propertyOrder" : 28
"required": true,
"access": "advanced",
"propertyOrder": 27
},
"sDHOffsetMax" :
{
"type" : "number",
"title" : "edt_conf_v4l2_sDHOffsetMax_title",
"minimum" : 0.0,
"maximum" : 1.0,
"default" : 0.75,
"step" : 0.01,
"sDHOffsetMax": {
"type": "number",
"title": "edt_conf_v4l2_sDHOffsetMax_title",
"minimum": 0.0,
"maximum": 1.0,
"default": 0.75,
"step": 0.01,
"options": {
"dependencies": {
"signalDetection": true
}
},
"required" : true,
"propertyOrder" : 29
"required": true,
"propertyOrder": 28
},
"hardware_brightness" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_hardware_brightness_title",
"default" : 0,
"required" : true,
"propertyOrder" : 30
"hardware_brightness": {
"type": "integer",
"title": "edt_conf_v4l2_hardware_brightness_title",
"default": 0,
"required": true,
"access": "advanced",
"propertyOrder": 29
},
"hardware_contrast" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_hardware_contrast_title",
"default" : 0,
"required" : true,
"propertyOrder" : 31
"hardware_contrast": {
"type": "integer",
"title": "edt_conf_v4l2_hardware_contrast_title",
"default": 0,
"required": true,
"access": "advanced",
"propertyOrder": 30
},
"hardware_saturation" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_hardware_saturation_title",
"default" : 0,
"required" : true,
"propertyOrder" : 32
"hardware_saturation": {
"type": "integer",
"title": "edt_conf_v4l2_hardware_saturation_title",
"default": 0,
"required": true,
"access": "advanced",
"propertyOrder": 31
},
"hardware_hue" :
{
"type" : "integer",
"title" : "edt_conf_v4l2_hardware_hue_title",
"default" : 0,
"required" : true,
"propertyOrder" : 33
"hardware_hue": {
"type": "integer",
"title": "edt_conf_v4l2_hardware_hue_title",
"default": 0,
"required": true,
"access": "advanced",
"propertyOrder": 32
}
},
"additionalProperties" : true
}
"additionalProperties": true
}