mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
* - New Media Foundation grabber
- JsonAPI available grabber fix
- commented json config removed
* Added libjpeg-turbo to dependencies
* Fix OSX build
Removed Azure Pipelines from build scripts
* Remove Platform from Dashboard
* Correct Grabber Namings
* Grabber UI improvements, generic JSONEditor Selection Update
* Active grabber fix
* Stop Framebuffer grabber on failure
* - Image format NV12 and I420 added
- Flip mode
- Scaling factor for MJPEG
- VSCode (compile before run)
- CI (push) dependency libjpeg-turbo added
* Refactor MediaFoundation (Part 1)
* Remove QDebug output
* Added image flipping ability to MF Grabber
* fix issue 1160
* -Reload MF Grabber only once per WebUI update
- Cleanup
* Improvements
* - Set 'Software Frame Decimation' begin to 0
- Removed grabber specific device name from Log
- Keep pixel format when switching resolution
- Display 'Flip mode' correct in Log
- BGR24 images always flipped
* Refactor MediaFoundation (Part 2)
* Refactor V4L2 grabber (part 1) (#62)
* Media Foundation grabber adapted to V4L2 change
* Enable Media Foundation grabber on windows
* Have fps as int, fix height typo
* Added video standards to JsonAPI output
* Error handling in source reader improved
* Fix "Frame to small" error
* Discovery VideoSources and Dynamically Update Editor
* Hide all element when no video grabber discovered, upate naming
* Do not show unsupported grabbers
* Copy Log to Clipboard
* Update Grabber schema and Defaults
* Update access levels and validate crop ranges
* Height and width in Qt grabber corrected
* Correct formatting
* Untabify
* Global component states across instances
* Components divided on the dashboard
* refactor
* Fix Merge-issues
* Database migration aligning with updated grabber model
* Align Grabber.js with new utility functions
* Allow editor-validation for enum-lists
* Handle "Show Explainations scenario" correctly
* Grabber - Ensure save is only possible on valid content
* Dashboard update + fix GlobalSignal connection
* Ensure default database is populated with current release
* Correct grabber4L2 access level
* Display Signal detection area in preview
* Write Hyperion version into default config on compiling.
* Create defaultconfig.json dynamically
* WebUI changes
* Correct grabber config look-ups
* Refactor i18n language loading
* Fix en.json
* Split global capture from instance capture config
* Update grabber default values
* Standalone grabber: Add --debug switch
* Enhance showInputOptionsForKey for multiple keys
* Add grabber instance link to system grabber config
* Only show signal detection area, if grabber is enabled
* Always show Active element on grabber page
* Remote control - Only display gabber status, if global grabber is enabled
* WebUI optimization (thx to @mkcologne)
Start Grabber only when global settings are enabled
Fixed an issue in the WebUI preview
* V4L2/MF changes
* Jsoneditor, Correct translation for default values
* Refactor LED-Device handling in UI and make element naming consistent
* MF Discovery extended
* Fix LGTM finding
* Support Grabber Bri, Hue, Sat and Con in UI, plus their defaults
* Concider Access level for item filtering
* Concider Access level for item filtering
* Revert "Concider Access level for item filtering"
This reverts commit 5b0ce3c0f2
.
* Disable fpsSoftwareDecimation for framegrabber, as not supported yet
* JSON-Editor- Add updated schema for validation on dynamic elements
* added V4L2 color IDs
* LGTM findings fix
* destroy SR callback only on exit
* Grabber.js - Hide elements not supported by platform
* Fixed freezing start effect
* Grabber UI - Hardware controls - Show current values and allow to reset to defaults
* Grabber - Discovery - Add current values to properties
* Small things
* Clean-up Effects and have ENDLESS consistently defined
* Fix on/off/on priority during startup, by initializing _prevVisComp in line with background priority
* Add missing translation mappings
* DirectX Grabber reactivated/ QT Grabber size decimation fixed
* typo in push-master workflow
* Use PreciseTimer for Grabber to ensure stable FPS timing
* Set default Screencapture rate consistently
* Fix libjpeg-turbo download
* Remove Zero character from file
* docker-compile Add PLATFORM parameter, only copy output file after successful compile
* Framebuffer, Dispmanx, OSX, AML Grabber discovery, various clean-up and consistencies across grabbers
* Fix merge problem - on docker-compile Add PLATFORM parameter, only copy output file after successful compile
* Fix definition
* OSXFRameGrabber - Revert cast
* Clean-ups nach Feedback
* Disable certain libraries when building armlogic via standard stretch image as developer
* Add CEC availability to ServerInfo to have it platform independent
* Grabber UI - Fix problem that crop values are not populated when refining editor rage
* Preserve value when updating json-editor range
* LEDVisualisation - Clear image when source changes
* Fix - Preserve value when updating json-editor range
* LEDVisualisation - Clear image when no component is active
* Allow to have password handled by Password-Manager (#1263)
* Update default signal detection area to green assuming rainbow grabber
* LED Visualisation - Handle empty priority update
* Fix yuv420 in v4l2 grabber
* V4L2-Grabber discovery - Only report grabbers with valid video input information
* Grabber - Update static variables to have them working in release build
* LED Visualisation - ClearImage when no priorities
* LED Visualisation - Fix Logo resizing issue
* LED Visualisation - Have nearly black background and negative logo
Co-authored-by: LordGrey <lordgrey.emmel@gmail.com>
Co-authored-by: LordGrey <48840279+Lord-Grey@users.noreply.github.com>
399 lines
16 KiB
JavaScript
399 lines
16 KiB
JavaScript
$(document).ready(function () {
|
|
performTranslation();
|
|
|
|
// update instance listing
|
|
updateHyperionInstanceListing();
|
|
|
|
var oldEffects = [];
|
|
var cpcolor = '#B500FF';
|
|
var mappingList = window.serverSchema.properties.color.properties.imageToLedMappingType.enum;
|
|
var duration = ENDLESS;
|
|
var rgb = { r: 255, g: 0, b: 0 };
|
|
var lastImgData = "";
|
|
var lastFileName = "";
|
|
|
|
//create html
|
|
createTable('ssthead', 'sstbody', 'sstcont');
|
|
$('.ssthead').html(createTableRow([$.i18n('remote_input_origin'), $.i18n('remote_input_owner'), $.i18n('remote_input_priority'), $.i18n('remote_input_status')], true, true));
|
|
createTable('crthead', 'crtbody', 'adjust_content', true);
|
|
|
|
|
|
//create introduction
|
|
if (window.showOptHelp) {
|
|
createHint("intro", $.i18n('remote_color_intro', $.i18n('remote_losthint')), "color_intro");
|
|
createHint("intro", $.i18n('remote_input_intro', $.i18n('remote_losthint')), "sstcont");
|
|
createHint("intro", $.i18n('remote_adjustment_intro', $.i18n('remote_losthint')), "adjust_content");
|
|
createHint("intro", $.i18n('remote_components_intro', $.i18n('remote_losthint')), "comp_intro");
|
|
createHint("intro", $.i18n('remote_maptype_intro', $.i18n('remote_losthint')), "maptype_intro");
|
|
createHint("intro", $.i18n('remote_videoMode_intro', $.i18n('remote_losthint')), "videomode_intro");
|
|
}
|
|
|
|
//color adjustment
|
|
var sColor = sortProperties(window.serverSchema.properties.color.properties.channelAdjustment.items.properties);
|
|
var values = window.serverInfo.adjustment[0];
|
|
|
|
for (var key in sColor) {
|
|
if (sColor[key].key != "id" && sColor[key].key != "leds") {
|
|
var title = '<label for="cr_' + sColor[key].key + '">' + $.i18n(sColor[key].title) + '</label>';
|
|
var property;
|
|
var value = values[sColor[key].key];
|
|
|
|
if (sColor[key].type == "array") {
|
|
property = '<div id="cr_' + sColor[key].key + '" class="input-group colorpicker-component" ><input type="text" class="form-control" /><span class="input-group-addon"><i></i></span></div>';
|
|
$('.crtbody').append(createTableRow([title, property], false, true));
|
|
createCP('cr_' + sColor[key].key, value, function (rgb, hex, e) {
|
|
requestAdjustment(e.target.id.substr(e.target.id.indexOf("_") + 1), '[' + rgb.r + ',' + rgb.g + ',' + rgb.b + ']');
|
|
});
|
|
}
|
|
else if (sColor[key].type == "boolean") {
|
|
property = '<div class="checkbox"><input id="cr_' + sColor[key].key + '" type="checkbox" value="' + value + '"/><label></label></div>';
|
|
$('.crtbody').append(createTableRow([title, property], false, true));
|
|
|
|
$('#cr_' + sColor[key].key).off().on('change', function (e) {
|
|
requestAdjustment(e.target.id.substr(e.target.id.indexOf("_") + 1), e.currentTarget.checked);
|
|
});
|
|
}
|
|
else {
|
|
if (sColor[key].key == "brightness" || sColor[key].key == "brightnessCompensation" || sColor[key].key == "backlightThreshold")
|
|
property = '<div class="input-group"><input id="cr_' + sColor[key].key + '" type="number" class="form-control" min="0" max="100" step="10" value="' + value + '"/><span class="input-group-addon">' + $.i18n("edt_append_percent") + '</span></div>';
|
|
else
|
|
property = '<input id="cr_' + sColor[key].key + '" type="number" class="form-control" min="0.1" max="4.0" step="0.1" value="' + value + '"/>';
|
|
|
|
$('.crtbody').append(createTableRow([title, property], false, true));
|
|
$('#cr_' + sColor[key].key).off().on('change', function (e) {
|
|
valValue(this.id, this.value, this.min, this.max);
|
|
requestAdjustment(e.target.id.substr(e.target.id.indexOf("_") + 1), e.currentTarget.value);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
function sendEffect() {
|
|
var efx = $("#effect_select").val();
|
|
if (efx != "__none__") {
|
|
requestPriorityClear();
|
|
$(window.hyperion).one("cmd-clear", function (event) {
|
|
setTimeout(function () { requestPlayEffect(efx, duration) }, 100);
|
|
});
|
|
}
|
|
}
|
|
|
|
function sendColor() {
|
|
requestSetColor(rgb.r, rgb.g, rgb.b, duration);
|
|
}
|
|
|
|
function updateInputSelect() {
|
|
$('.sstbody').html("");
|
|
var prios = window.serverInfo.priorities;
|
|
var clearAll = false;
|
|
|
|
for (var i = 0; i < prios.length; i++) {
|
|
var origin = prios[i].origin ? prios[i].origin : "System";
|
|
origin = origin.split("@");
|
|
var ip = origin[1];
|
|
origin = origin[0];
|
|
|
|
var owner = prios[i].owner;
|
|
var active = prios[i].active;
|
|
var visible = prios[i].visible;
|
|
var priority = prios[i].priority;
|
|
var compId = prios[i].componentId;
|
|
var duration = prios[i].duration_ms / 1000;
|
|
var value = "0,0,0";
|
|
var btn_type = "default";
|
|
var btn_text = $.i18n('remote_input_setsource_btn');
|
|
var btn_state = "enabled";
|
|
|
|
if (active)
|
|
btn_type = "primary";
|
|
|
|
if (priority > 254)
|
|
continue;
|
|
if (priority < 254 && (compId == "EFFECT" || compId == "COLOR" || compId == "IMAGE"))
|
|
clearAll = true;
|
|
|
|
if (visible) {
|
|
btn_state = "disabled";
|
|
btn_type = "success";
|
|
btn_text = $.i18n('remote_input_sourceactiv_btn');
|
|
}
|
|
|
|
if (ip)
|
|
origin += '<br/><span style="font-size:80%; color:grey;">' + $.i18n('remote_input_ip') + ' ' + ip + '</span>';
|
|
|
|
if ("value" in prios[i])
|
|
value = prios[i].value.RGB;
|
|
|
|
switch (compId) {
|
|
case "EFFECT":
|
|
owner = $.i18n('remote_effects_label_effects') + ' ' + owner;
|
|
break;
|
|
case "COLOR":
|
|
owner = $.i18n('remote_color_label_color') + ' ' + '<div style="width:18px; height:18px; border-radius:20px; margin-bottom:-4px; border:1px grey solid; background-color: rgb(' + value + '); display:inline-block" title="RGB: (' + value + ')"></div>';
|
|
break;
|
|
case "IMAGE":
|
|
owner = $.i18n('remote_effects_label_picture') + ' ' + owner;
|
|
break;
|
|
case "GRABBER":
|
|
owner = $.i18n('general_comp_GRABBER') + ': (' + owner + ')';
|
|
break;
|
|
case "V4L":
|
|
owner = $.i18n('general_comp_V4L') + ': (' + owner + ')';
|
|
break;
|
|
case "BOBLIGHTSERVER":
|
|
owner = $.i18n('general_comp_BOBLIGHTSERVER');
|
|
break;
|
|
case "FLATBUFSERVER":
|
|
owner = $.i18n('general_comp_FLATBUFSERVER');
|
|
break;
|
|
case "PROTOSERVER":
|
|
owner = $.i18n('general_comp_PROTOSERVER');
|
|
break;
|
|
}
|
|
|
|
if (duration && compId != "GRABBER" && compId != "FLATBUFSERVER" && compId != "PROTOSERVER")
|
|
owner += '<br/><span style="font-size:80%; color:grey;">' + $.i18n('remote_input_duration') + ' ' + duration.toFixed(0) + $.i18n('edt_append_s') + '</span>';
|
|
|
|
var btn = '<button id="srcBtn' + i + '" type="button" ' + btn_state + ' class="btn btn-' + btn_type + ' btn_input_selection" onclick="requestSetSource(' + priority + ');">' + btn_text + '</button>';
|
|
|
|
if ((compId == "EFFECT" || compId == "COLOR" || compId == "IMAGE") && priority < 254)
|
|
btn += '<button type="button" class="btn btn-sm btn-danger" style="margin-left:10px;" onclick="requestPriorityClear(' + priority + ');"><i class="fa fa-close"></button>';
|
|
|
|
if (btn_type != 'default')
|
|
$('.sstbody').append(createTableRow([origin, owner, priority, btn], false, true));
|
|
}
|
|
var btn_auto_color = (window.serverInfo.priorities_autoselect ? "btn-success" : "btn-danger");
|
|
var btn_auto_state = (window.serverInfo.priorities_autoselect ? "disabled" : "enabled");
|
|
var btn_auto_text = (window.serverInfo.priorities_autoselect ? $.i18n('general_btn_on') : $.i18n('general_btn_off'));
|
|
var btn_call_state = (clearAll ? "enabled" : "disabled");
|
|
$('#auto_btn').html('<button id="srcBtn' + i + '" type="button" ' + btn_auto_state + ' class="btn ' + btn_auto_color + '" style="margin-right:5px;display:inline-block;" onclick="requestSetSource(\'auto\');">' + $.i18n('remote_input_label_autoselect') + ' (' + btn_auto_text + ')</button>');
|
|
$('#auto_btn').append('<button type="button" ' + btn_call_state + ' class="btn btn-danger" style="display:inline-block;" onclick="requestClearAll();">' + $.i18n('remote_input_clearall') + '</button>');
|
|
|
|
var max_width = 100;
|
|
$('.btn_input_selection').each(function () {
|
|
if ($(this).innerWidth() > max_width)
|
|
max_width = $(this).innerWidth();
|
|
});
|
|
$('.btn_input_selection').css("min-width", max_width + "px");
|
|
}
|
|
|
|
function updateLedMapping() {
|
|
var mapping = window.serverInfo.imageToLedMappingType;
|
|
|
|
$('#mappingsbutton').html("");
|
|
for (var ix = 0; ix < mappingList.length; ix++) {
|
|
if (mapping == mappingList[ix])
|
|
var btn_style = 'btn-success';
|
|
else
|
|
var btn_style = 'btn-primary';
|
|
|
|
$('#mappingsbutton').append('<button type="button" id="lmBtn_' + mappingList[ix] + '" class="btn ' + btn_style + '" style="margin:3px;min-width:200px" onclick="requestMappingType(\'' + mappingList[ix] + '\');">' + $.i18n('remote_maptype_label_' + mappingList[ix]) + '</button><br/>');
|
|
}
|
|
}
|
|
|
|
function initComponents() {
|
|
var components = window.comps;
|
|
var hyperionEnabled = true;
|
|
components.forEach(function (obj) {
|
|
if (obj.name == "ALL") {
|
|
hyperionEnabled = obj.enabled;
|
|
}
|
|
});
|
|
|
|
for (const comp of components) {
|
|
if (comp.name === "ALL" || (comp.name === "FORWARDER" && window.currentHyperionInstance != 0) ||
|
|
(comp.name === "GRABBER" && !window.serverConfig.framegrabber.enable) ||
|
|
(comp.name === "V4L" && !window.serverConfig.grabberV4L2.enable))
|
|
continue;
|
|
|
|
const enable_style = (comp.enabled ? "checked" : "");
|
|
const comp_btn_id = "comp_btn_" + comp.name;
|
|
|
|
if ($("#" + comp_btn_id).length === 0) {
|
|
var d = '<span style="display:block;margin:3px">'
|
|
+ '<label class="checkbox-inline">'
|
|
+ '<input id = "' + comp_btn_id + '"' + enable_style + ' type = "checkbox"'
|
|
+ 'data-toggle="toggle" data-onstyle="success" data-on="' + $.i18n('general_btn_on') + '" data-off="' + $.i18n('general_btn_off') + '">'
|
|
+ $.i18n('general_comp_' + comp.name) + '</label > '
|
|
+ '</span>';
|
|
|
|
$('#componentsbutton').append(d);
|
|
$(`#${comp_btn_id}`).bootstrapToggle();
|
|
$(`#${comp_btn_id}`).bootstrapToggle((hyperionEnabled ? "enable" : "disable"));
|
|
$(`#${comp_btn_id}`).change(e => {
|
|
requestSetComponentState(e.currentTarget.id.split('_').pop(), e.currentTarget.checked);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateComponent(component) {
|
|
if (component.name == "ALL") {
|
|
var components = window.comps;
|
|
var hyperionEnabled = component.enabled;
|
|
for (const comp of components) {
|
|
|
|
if (comp.name === "ALL")
|
|
continue;
|
|
|
|
const comp_btn_id = "comp_btn_" + comp.name;
|
|
|
|
if (!hyperionEnabled) {
|
|
$(`#${comp_btn_id}`).bootstrapToggle('off');
|
|
$(`#${comp_btn_id}`).bootstrapToggle("disable");
|
|
}
|
|
else {
|
|
$(`#${comp_btn_id}`).bootstrapToggle("enable");
|
|
if (comp.enabled !== $(`#${comp_btn_id}`).prop("checked")) {
|
|
$(`#${comp_btn_id}`).bootstrapToggle().prop('checked', comp.enabled).change();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
const comp_btn_id = "comp_btn_" + component.name;
|
|
|
|
//console.log ("updateComponent: ", component.name, "Current Checked: ", $(`#${comp_btn_id}`).prop("checked"), "New Checked: ", component.enabled, );
|
|
|
|
// In case Buttons were disabled before, status may be different to component status
|
|
if (component.enabled != $(`#${comp_btn_id}`).prop("checked")) {
|
|
// console.log ("Update status to Checked = ", component.enabled);
|
|
if (component.enabled)
|
|
$(`#${comp_btn_id}`).bootstrapToggle("on");
|
|
else
|
|
$(`#${comp_btn_id}`).bootstrapToggle("off");
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateEffectlist() {
|
|
var newEffects = window.serverInfo.effects;
|
|
if (newEffects.length != oldEffects.length) {
|
|
$('#effect_select').html('<option value="__none__"></option>');
|
|
var usrEffArr = [];
|
|
var sysEffArr = [];
|
|
|
|
for (var i = 0; i < newEffects.length; i++) {
|
|
var effectName = newEffects[i].name;
|
|
if (!/^\:/.test(newEffects[i].file)) {
|
|
usrEffArr.push(effectName);
|
|
}
|
|
else {
|
|
sysEffArr.push(effectName);
|
|
}
|
|
}
|
|
$('#effect_select').append(createSel(usrEffArr, $.i18n('remote_optgroup_usreffets')));
|
|
$('#effect_select').append(createSel(sysEffArr, $.i18n('remote_optgroup_syseffets')));
|
|
oldEffects = newEffects;
|
|
}
|
|
}
|
|
|
|
function updateVideoMode() {
|
|
var videoModes = ["2D", "3DSBS", "3DTAB"];
|
|
var currVideoMode = window.serverInfo.videomode;
|
|
|
|
$('#videomodebtns').html("");
|
|
for (var ix = 0; ix < videoModes.length; ix++) {
|
|
if (currVideoMode == videoModes[ix])
|
|
var btn_style = 'btn-success';
|
|
else
|
|
var btn_style = 'btn-primary';
|
|
$('#videomodebtns').append('<button type="button" id="vModeBtn_' + videoModes[ix] + '" class="btn ' + btn_style + '" style="margin:3px;min-width:200px" onclick="requestVideoMode(\'' + videoModes[ix] + '\');">' + $.i18n('remote_videoMode_' + videoModes[ix]) + '</button><br/>');
|
|
}
|
|
}
|
|
|
|
// colorpicker and effect
|
|
if (getStorage('rmcpcolor') != null) {
|
|
cpcolor = getStorage('rmcpcolor');
|
|
rgb = hexToRgb(cpcolor);
|
|
}
|
|
|
|
if (getStorage('rmduration') != null) {
|
|
$("#remote_duration").val(getStorage('rmduration'));
|
|
duration = getStorage('rmduration');
|
|
}
|
|
|
|
createCP('cp2', cpcolor, function (rgbT, hex) {
|
|
rgb = rgbT;
|
|
sendColor();
|
|
setStorage('rmcpcolor', hex);
|
|
updateInputSelect();
|
|
});
|
|
|
|
$("#reset_color").off().on("click", function () {
|
|
requestPriorityClear();
|
|
lastImgData = "";
|
|
$("#effect_select").val("__none__");
|
|
$("#remote_input_img").val("");
|
|
});
|
|
|
|
$("#remote_duration").off().on("change", function () {
|
|
duration = valValue(this.id, this.value, this.min, this.max);
|
|
setStorage('rmduration', duration);
|
|
});
|
|
|
|
$("#effect_select").off().on("change", function (event) {
|
|
sendEffect();
|
|
});
|
|
|
|
$("#remote_input_reseff, #remote_input_rescol").off().on("click", function () {
|
|
if (this.id == "remote_input_rescol")
|
|
sendColor();
|
|
else
|
|
sendEffect();
|
|
});
|
|
|
|
$("#remote_input_repimg").off().on("click", function () {
|
|
if (lastImgData != "")
|
|
requestSetImage(lastImgData, duration, lastFileName);
|
|
});
|
|
|
|
$("#remote_input_img").change(function () {
|
|
readImg(this, function (src, fileName) {
|
|
lastFileName = fileName;
|
|
if (src.includes(","))
|
|
lastImgData = src.split(",")[1];
|
|
else
|
|
lastImgData = src;
|
|
|
|
requestSetImage(lastImgData, duration, lastFileName);
|
|
});
|
|
});
|
|
|
|
//force first update
|
|
initComponents();
|
|
updateInputSelect();
|
|
updateLedMapping();
|
|
updateVideoMode();
|
|
updateEffectlist();
|
|
|
|
// interval updates
|
|
|
|
$(window.hyperion).on('components-updated', function (e, comp) {
|
|
//console.log ("components-updated", e, comp);
|
|
updateComponent(comp);
|
|
});
|
|
|
|
$(window.hyperion).on("cmd-priorities-update", function (event) {
|
|
window.serverInfo.priorities = event.response.data.priorities;
|
|
window.serverInfo.priorities_autoselect = event.response.data.priorities_autoselect;
|
|
updateInputSelect();
|
|
});
|
|
$(window.hyperion).on("cmd-imageToLedMapping-update", function (event) {
|
|
window.serverInfo.imageToLedMappingType = event.response.data.imageToLedMappingType;
|
|
updateLedMapping();
|
|
});
|
|
|
|
$(window.hyperion).on("cmd-videomode-update", function (event) {
|
|
window.serverInfo.videomode = event.response.data.videomode;
|
|
updateVideoMode();
|
|
});
|
|
|
|
$(window.hyperion).on("cmd-effects-update", function (event) {
|
|
window.serverInfo.effects = event.response.data.effects;
|
|
updateEffectlist();
|
|
});
|
|
|
|
removeOverlay();
|
|
});
|