Skip to content

Commit

Permalink
Instacam: extension to tweak color saturation and exposure
Browse files Browse the repository at this point in the history
  • Loading branch information
tbjolset committed Mar 2, 2023
1 parent 15de19c commit 2a329bc
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Instacam/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Instacam

Tweak the color saturation and color compenstation of your Desk device.

![Settings panel](./settings-panel.png)

Requirement
* Device that has the new xAPI for color saturation: **xConfiguration Cameras Camera ColorSaturation Level**
107 changes: 107 additions & 0 deletions Instacam/instacam.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import xapi from 'xapi';

const saturationLimit = 14;
const exposureLimit = 3;

// When a config changes
async function onConfig(configPath, onChange) {
try {
await xapi.config.on(configPath, onChange);
await xapi.config.get(configPath).then(onChange);
}
catch(e) {
console.warn('Not able to use config', configPath, e);
}
}

// When a ui event occurs
function onUi(widgetId, onEvent) {
xapi.Event.UserInterface.Extensions.Widget.Action.on((e) => {
if (e.WidgetId === widgetId) {
onEvent(e);
}
})
}

function setWidget(widgetId, value) {
xapi.Command.UserInterface.Extensions.Widget.SetValue({ Value: String(value), WidgetId: widgetId })
}

// -20...20
async function setSaturation(level) {
try {
// console.log('set saturation', level);
await xapi.Config.Cameras.Camera.ColorSaturation.Level.set(level);
}
catch(e) {
xapi.Command.UserInterface.Message.Alert.Display({ Text: 'Sorry, not currently able to adjust the saturation on this device.', Duration: 3 });
console.warn('not able to set saturation');
}
}

// -3..3
function setExposure(level) {
try {
// console.log('set exposure', level);
xapi.Config.Cameras.Camera.ExposureCompensation.Level.set(level);
}
catch(e) {
console.warn('not able to set saturation');
}
}

function showSelfview(on, fullscreen) {
xapi.Command.Video.Selfview.Set({ Mode: on ? 'On' : 'Off', FullscreenMode: fullscreen ? 'On': 'Off' });
}

function init() {

onUi('instacam-saturation', e => {
const level = parseInt(saturationLimit * (Number(e.Value)) / 255);
setSaturation(level);
});

onUi('instacam-bw', e => {
setSaturation(e.Value === 'on' ? -20 : 0);
});

onConfig('Cameras Camera ColorSaturation Level', value => {
const valid = Math.max(0, Math.min(saturationLimit, value));
const level = valid * 255 / saturationLimit;
// console.log('set sat widget', level);
setWidget('instacam-saturation', level);
setWidget('instacam-saturation-value', value);
setWidget('instacam-bw', value < 0 ? 'On' : 'Off');
});

onUi('instacam-exposure', async (e) => {
const value = Number(await xapi.Config.Cameras.Camera.ExposureCompensation.Level.get());
if (e.Type !== 'clicked') return;
const up = e.Value === 'increment';
const next = up ? value + 1 : value - 1;
const bounded = Math.max(-exposureLimit, Math.min(exposureLimit, next));
setExposure(bounded);
});

onConfig('Cameras Camera ExposureCompensation Level', value => {
setWidget('instacam-exposure', value);
});

onUi('instacam-exposure-reset', () => setExposure(0));

onUi('instacam-selfview', ({ Value }) => {
if (Value === 'large') {
showSelfview(true, true);
// fullscreen self view closes panel, reopen
xapi.Command.UserInterface.Extensions.Panel.Open({ PanelId: 'instacam' });
}
else if (Value === 'small') {
showSelfview(true, false);
}
else if (Value === 'off') {
showSelfview(false);
}
});
}

init();
88 changes: 88 additions & 0 deletions Instacam/instacam.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<Extensions>
<Version>1.10</Version>
<Panel>
<Order>1</Order>
<PanelId>instacam</PanelId>
<Origin>local</Origin>
<Location>HomeScreen</Location>
<Icon>Camera</Icon>
<Color>#1170CF</Color>
<Name>Instacam</Name>
<ActivityType>Custom</ActivityType>
<Page>
<Name>Instacam</Name>
<Row>
<Name>Info</Name>
<Widget>
<WidgetId>instacam-info</WidgetId>
<Name>Tweak how your image appears to the other participants</Name>
<Type>Text</Type>
<Options>size=4;fontSize=normal;align=left</Options>
</Widget>
</Row>
<Row>
<Name>Color saturation</Name>
<Widget>
<WidgetId>instacam-saturation</WidgetId>
<Type>Slider</Type>
<Options>size=3</Options>
</Widget>
<Widget>
<WidgetId>instacam-saturation-value</WidgetId>
<Name>Text</Name>
<Type>Text</Type>
<Options>size=1;fontSize=normal;align=center</Options>
</Widget>
<Widget>
<WidgetId>instacam-bw</WidgetId>
<Type>ToggleButton</Type>
<Options>size=1</Options>
</Widget>
<Widget>
<WidgetId>instacam-bw-info</WidgetId>
<Name>Black/white</Name>
<Type>Text</Type>
<Options>size=null;fontSize=small;align=right</Options>
</Widget>
</Row>
<Row>
<Name>Exposure compensation</Name>
<Widget>
<WidgetId>instacam-exposure</WidgetId>
<Type>Spinner</Type>
<Options>size=2</Options>
</Widget>
<Widget>
<WidgetId>instacam-exposure-reset</WidgetId>
<Name>Reset</Name>
<Type>Button</Type>
<Options>size=1</Options>
</Widget>
</Row>
<Row>
<Name>Selfview</Name>
<Widget>
<WidgetId>instacam-selfview</WidgetId>
<Type>GroupButton</Type>
<Options>size=4</Options>
<ValueSpace>
<Value>
<Key>large</Key>
<Name>Large</Name>
</Value>
<Value>
<Key>small</Key>
<Name>Small</Name>
</Value>
<Value>
<Key>off</Key>
<Name>Off</Name>
</Value>
</ValueSpace>
</Widget>
</Row>
<PageId>instacam-page</PageId>
<Options/>
</Page>
</Panel>
</Extensions>
23 changes: 23 additions & 0 deletions Instacam/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"version": "1",
"profile": {
"macro": {
"items": [
{
"payload": "./instacam.js",
"type": "url",
"id": "instacam"
}
]
},
"roomcontrol": {
"items": [
{
"payload": "./instacam.xml",
"id": "instacam",
"type": "url"
}
]
}
}
}
Binary file added Instacam/settings-panel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2a329bc

Please sign in to comment.