-
Notifications
You must be signed in to change notification settings - Fork 184
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Instacam: extension to tweak color saturation and exposure
- Loading branch information
Showing
5 changed files
with
226 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | ||
|
||
 | ||
|
||
Requirement | ||
* Device that has the new xAPI for color saturation: **xConfiguration Cameras Camera ColorSaturation Level** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
] | ||
} | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.