-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Axel Boberg <[email protected]>
- Loading branch information
1 parent
d90f1b4
commit 6a35f38
Showing
9 changed files
with
402 additions
and
9 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
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,37 @@ | ||
# OSC plugin | ||
Bridge's default OSC plugin | ||
|
||
## Description | ||
This plugis allows external services to communicate to Bridge using the Open Sound Control protocol (OSC). | ||
|
||
## Table of contents | ||
- [Description](#description) | ||
- [Reference](#reference) | ||
|
||
## Reference | ||
The following list is a reference of the OSC paths that are available within this plugin. | ||
|
||
### `/api/commands/executeCommand` | ||
Execute a command | ||
|
||
#### Arguments | ||
| Index | Type | Description | | ||
| --- | --- | --- | | ||
| 0 | String | The id of the command to execute | | ||
| 1...n | any | Arguments that will be passed to the command | | ||
|
||
### `/api/items/playItem` | ||
Play an item | ||
|
||
#### Arguments | ||
| Index | Type | Description | | ||
| --- | --- | --- | | ||
| 0 | String | The id of the item to play | | ||
|
||
### `/api/items/stopItem` | ||
Stop an item | ||
|
||
#### Arguments | ||
| Index | Type | Description | | ||
| --- | --- | --- | | ||
| 0 | String | The id of the item to stop | |
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,126 @@ | ||
// SPDX-FileCopyrightText: 2024 Sveriges Television AB | ||
// | ||
// SPDX-License-Identifier: MIT | ||
|
||
/** | ||
* @type { import('../../api').Api } | ||
*/ | ||
const bridge = require('bridge') | ||
|
||
const manifest = require('./package.json') | ||
|
||
const Server = require('./lib/Server') | ||
const UDPTransport = require('./lib/UDPTransport') | ||
|
||
const handlers = require('./lib/handlers') | ||
|
||
const Router = require('obj-router') | ||
const router = new Router(handlers) | ||
|
||
/** | ||
* The default server port, | ||
* | ||
* this will be used as the default | ||
* settings value if no other is provided | ||
* | ||
* @type { Number } | ||
*/ | ||
const DEFAULT_SERVER_PORT = 8080 | ||
|
||
exports.activate = async () => { | ||
/** | ||
* A reference to the current server | ||
* @type { Server | undefined } | ||
*/ | ||
let server | ||
|
||
/** | ||
* Set up the server and start listen | ||
* on a specific port | ||
* @param { Number } port | ||
*/ | ||
function setupServer (port = DEFAULT_SERVER_PORT, address) { | ||
teardownServer() | ||
|
||
const transport = new UDPTransport() | ||
transport.listen(port, address) | ||
|
||
server = new Server(transport) | ||
server.on('message', async osc => { | ||
try { | ||
await router.execute(osc.address, osc) | ||
} catch (e) { | ||
console.log(e) | ||
} | ||
}) | ||
} | ||
|
||
/** | ||
* Tear down the | ||
* current server | ||
*/ | ||
function teardownServer () { | ||
if (!server) { | ||
return | ||
} | ||
server.teardown() | ||
server = undefined | ||
} | ||
|
||
/** | ||
* A snapshot of the current | ||
* server configuration used | ||
* for diffing against state | ||
* updates | ||
* @type { String } | ||
*/ | ||
let serverConfigSnapshot | ||
|
||
/* | ||
Listen to state changes and compare | ||
the current server configuration | ||
Only set up the server if the | ||
configuration has changed | ||
*/ | ||
bridge.events.on('state.change', newState => { | ||
const serverConfig = newState?.plugins?.[manifest.name]?.settings.server | ||
if (serverConfigSnapshot !== JSON.stringify(serverConfig)) { | ||
serverConfigSnapshot = JSON.stringify(serverConfig) | ||
|
||
if (!serverConfig?.active) { | ||
teardownServer() | ||
} else { | ||
setupServer(serverConfig?.port, serverConfig?.bindToAll ? '0.0.0.0' : '127.0.0.1') | ||
} | ||
} | ||
}) | ||
|
||
/* | ||
Set up the server on | ||
startup if active | ||
*/ | ||
const serverConfig = await bridge.state.get(`plugins.${manifest.name}.settings.server`) | ||
serverConfigSnapshot = JSON.stringify(serverConfig) | ||
if (serverConfig?.active) { | ||
setupServer(serverConfig?.port, serverConfig?.bindToAll ? '0.0.0.0' : '127.0.0.1') | ||
} | ||
|
||
/* | ||
Set defaults | ||
if missing | ||
*/ | ||
if (!serverConfig?.port) { | ||
bridge.state.apply({ | ||
plugins: { | ||
[manifest.name]: { | ||
settings: { | ||
server: { | ||
port: DEFAULT_SERVER_PORT | ||
} | ||
} | ||
} | ||
} | ||
}) | ||
} | ||
} |
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,43 @@ | ||
// SPDX-FileCopyrightText: 2024 Sveriges Television AB | ||
// | ||
// SPDX-License-Identifier: MIT | ||
|
||
const EventEmitter = require('events') | ||
|
||
const osc = require('osc-min') | ||
|
||
class Server extends EventEmitter { | ||
/** | ||
* @private | ||
* @type { import('./Transport') } | ||
*/ | ||
_transport | ||
|
||
/** | ||
* @param { import('./Transport') } transport | ||
*/ | ||
constructor (transport) { | ||
super() | ||
|
||
this._transport = transport | ||
this._transport.on('message', msg => { | ||
const processed = this._process(msg) | ||
this.emit('message', processed) | ||
}) | ||
} | ||
|
||
/** | ||
* @private | ||
* @param { Buffer } buffer | ||
*/ | ||
_process (buffer) { | ||
return osc.fromBuffer(buffer) | ||
} | ||
|
||
teardown () { | ||
this._transport.teardown() | ||
this.removeAllListeners() | ||
} | ||
} | ||
|
||
module.exports = Server |
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,20 @@ | ||
// SPDX-FileCopyrightText: 2024 Sveriges Television AB | ||
// | ||
// SPDX-License-Identifier: MIT | ||
|
||
const EventEmitter = require('events') | ||
|
||
/** | ||
* A base class for transports | ||
* for the Server class | ||
*/ | ||
class Transport extends EventEmitter { | ||
/** | ||
* Tear down this transport | ||
*/ | ||
teardown () { | ||
this.removeAllListeners() | ||
} | ||
} | ||
|
||
module.exports = Transport |
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,52 @@ | ||
// SPDX-FileCopyrightText: 2024 Sveriges Television AB | ||
// | ||
// SPDX-License-Identifier: MIT | ||
|
||
const Transport = require('./Transport') | ||
|
||
const dgram = require('node:dgram') | ||
|
||
/** | ||
* @typedef {{ | ||
* ipAddress: String, | ||
* port: String | ||
* }} UDPTransportOptions | ||
*/ | ||
class UDPTransport extends Transport { | ||
/** | ||
* @private | ||
* @type { UDPTransportOptions } | ||
*/ | ||
_opts | ||
|
||
/** | ||
* @private | ||
* @type { dgram.Socket } | ||
*/ | ||
_socket | ||
|
||
/** | ||
* @param { UDPTransportOptions } opts | ||
*/ | ||
constructor (opts = {}) { | ||
super() | ||
this._opts = opts | ||
this._socket = dgram.createSocket('udp4') | ||
|
||
this._socket.on('message', (msg, rinfo) => { | ||
this.emit('message', msg) | ||
}) | ||
} | ||
|
||
teardown () { | ||
super.teardown() | ||
this._socket.close() | ||
this._socket.removeAllListeners() | ||
} | ||
|
||
listen (port, address) { | ||
this._socket.bind(port, address) | ||
} | ||
} | ||
|
||
module.exports = UDPTransport |
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,20 @@ | ||
// SPDX-FileCopyrightText: 2024 Sveriges Television AB | ||
// | ||
// SPDX-License-Identifier: MIT | ||
|
||
const bridge = require('bridge') | ||
|
||
/* | ||
Define any available osc paths | ||
*/ | ||
module.exports = { | ||
'/api': { | ||
'/commands': { | ||
'/executeCommand': message => bridge.commands.executeCommand(...message.args.map(arg => arg.value)) | ||
}, | ||
'/items': { | ||
'/playItem': message => bridge.items.playItem(message?.args?.[0].value), | ||
'/stopItem': message => bridge.items.stopItem(message?.args?.[0].value) | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.