We created a full working example web page using the Nx JavaScript API to demonstrate some of its functionality. The full example can be found in the GitHub Open Integrations repository and looks like this in the Desktop Client:
This section article describes how we created the example and covers the following functionality:
- Create a list of resources which gets updated when a resource is added/removed.
- Set timestamp and playback speed. Open selected item from resource list
- Save Layout
- Display Result / Error Code
Create a list of resources which gets updated when a resource is added/removed.
This allows you to have a list of cameras and devices on the System accessible to your account as opposed to finding one device at a time by manually looking up its physical ID. You can select a device from the list to do things like apply settings to it or open it on the layout.
To begin, users must initialize the window.vmsApiInit
function by assigning a callback to signal that the API is ready to be used. Global objects are not accessible before this API call is made.
The following code goes in the <head></head> section:
<script>
let sceneItemsController
window.vmsApiInit =
async function()
{
sceneItemsController = new SceneItemsController()
initResourcesUI(resourcesList)
}
</script>
Next, we will create several helper functions.
The addOrUpdateListItem
helper function adds or updates the list item with the specified id and text.
<script>
function addOrUpdateListItem(list, itemId, text)
{
let item = list.options.namedItem(itemId)
if (!item)
{
item = document.createElement('option')
item.id = itemId
list.append(item)
}
item.innerText = text
}
</script>
The removeItem
helper function removes items with the specified id from the list.
<script>
function removeItem(list, itemId)
{
const item = list.options.namedItem(itemId)
if (item)
list.remove(item.index)
}
</script>
The addSelectionHandler
helper function disables specified buttons if the list has no currently selected item. Otherwise, it enables them.
<script>
function addSelectionHandler(list, buttons)
{
const handleSelectionChanged =
()=>
{
const disabled = list.selectedIndex == -1
buttons.forEach((button) => button.disabled = disabled)
}
list.addEventListener('change', handleSelectionChanged)
handleSelectionChanged()
return handleSelectionChanged
}
</script>
The getSelectedItemId
helper function returns id of selected list item, otherwise shows error with specified text.
<script>
function getSelectedItemId(list, errorMessage)
{
if (list.selectedIndex != -1)
return list.item(list.selectedIndex).id
alert(errorMessage)
return undefined
}
</script>
The initResourcesUI
helper function handles resource additions/removals and manages a list of available resource items.
<script>
async function initResourcesUI(list)
{
const handleSelectionChanged =
addSelectionHandler(list, [addSceneItemButton])
const resourceAdded =
resource =>
{
const text = `[${resource.type}] ${resource.name}`
addOrUpdateListItem(list, resource.id, text)
}
vms.resources.added.connect(resource => resourceAdded(resource))
vms.resources.removed.connect(
resourceId =>
{
removeItem(list, resourceId)
handleSelectionChanged()
})
const resources = await vms.resources.resources()
resources.forEach(resourceAdded)
}
</script>
Set timestamp and playback speed. Open selected item from resource list.
Let’s start by writing the login in the <head></head> section.
Create the SceneItemsController
helper function which acts as a controller for scene items management. Within this function, create another function called result.addSceneItem
and create the parameters that will be applied to the device you select from the list to open on scene.
To store the parameters, create the settings object with an empty value. Afterward, create the settings.media
property with an empty value. Create the settings.media.speed
property and assign it a number equivalent to the playback speed you’d like (in this example we set it to 2).
Create the settings.media.timestampMs
property and assign it document.getElementById("timestamp").value
, which gets the timestamp for the archive to start playback at from the value entered in the timestamp field.
To open the selected item (which provides the resourceId) with the set parameters, create the result
constant and assign it the value await vms.tab.addItem(resourceId,
settings)
(see vms.tab object for more details).
Define vms.log.info
to write the result.error.code
to info logs and resultCode.innerText=`${result.error.code}`
to write the result.error.code
to the field with the ID "resultCode" (see the Error class for more details).
<script>
function SceneItemsController()
{
const result = {}
result.addSceneItem =
async function()
{
const resourceId = getSelectedItemId(resourcesList,
"Please select item to be removed from the scene")
if (!resourceId)
return
// Create parameters for the "addItem" call
var settings = {}
settings.media = {}
settings.media.speed = 2 // Playback speed
settings.media.timestampMs = document.getElementById("timestamp").value; // Get position to play archive
// Open the item (resourceId) with parameters (settings)
const result = await vms.tab.addItem(resourceId, settings)
vms.log.info(`Trying to addItem, result code is ${result.error.code}`)
resultCode.innerText=`${result.error.code}` // Write the result.error.code to the field with the ID "resultCode"
return
}
return result
}
</script>
Next, let’s write the GUI portion in the <body></body> section.
Create a field for users to enter the timestamp (with ms) from which to play the archive. If you want Live just enter the "-1".
<div>
Timestamp:
</div>
<div>
<input id="timestamp" placeholder="">
</div>
Create the camerasBlock
element which displays all the cameras in the list. Create an “Add” button with the button id of 'addSceneItemButton'
to open the selected camera on the layout by calling the sceneItemsController.addSceneItem()
helper function.
<div id = 'camerasBlock'>
Available cameras
<div>
<select id = 'resourcesList' size = 15></select>
</div>
<div>
<button id = 'addSceneItemButton'
onclick = 'sceneItemsController.addSceneItem()'>Add
</button>
</div>
</div>
Save Layout
Saving the layout will allow your cameras open on scene to be saved in their current positioning. This can be important for when you want to close and reopen the Desktop Client but still maintain the layout or if you want to have multiple different layouts.
The following logic code goes in the <head></head> section. Create the saveLayout()
function calling the vms.tab object.
<script>
async function saveLayout() {
vms.tab.saveLayout()
}
</script>
The following GUI code goes in the <body></body> section: Make the Save layout button call the saveLayout()
function.
<div>
<button onclick="saveLayout()">Save layout</button>
</div>
Display Result / Error Code
Displaying the result or error code is important to let the user know if an action was successful or not.
The logic that goes under <body> was already covered in the getSelectedItemId(list,
errorMessage)
function in one of the prior sections.
The following GUI code goes in the <body></body> section.
<div class="row">
Result code: <div id="resultCode"></div>
</div>
<div>
---<br>
0 - success<br>
1 - unexpected error<br>
2 - access error<br>
3 - invalid params or camera id<br>
</div>
<div>
<button onclick="saveLayout()">Save layout</button>
</div>
Comments
0 comments
Article is closed for comments.