Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
dnmeid committed May 24, 2023
2 parents 27f0860 + f5e4d69 commit 2d03f76
Show file tree
Hide file tree
Showing 13 changed files with 3,019 additions and 1,017 deletions.
22 changes: 22 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"globals": {
"angular": false,
"module": false,
"inject": false,
"document": false
},
"env": {
"es6": true,
"browser": true,
"amd": true,
"node": true
},
"extends": [
"eslint:recommended"
],
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module"
},
"rules": {}
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
node_modules/
pkg
pkg.tgz

# Temp store for pearl files.
# Which cannot be commited due to licence
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
---
## [Unreleased]

---
## [2.0.0] (2023-05-24)

## Major
* Rewrite of the module code for compatibility with Companion v3. The code is not backwards compatible, but configuration data is.

## New Features
* Upgraded Feedbacks to boolean type
* Added Reset option to recorder control
* Added option to change the feedback polling interval

## Dependencies
* Bump qs from 6.5.2 to 6.5.3
* Changed REST connection from request module to node's internal fetch

## Bugfixes
* Corrected some typos

---
## [1.0.9] (2022-09-26)

Expand Down
220 changes: 220 additions & 0 deletions actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
const { InstanceStatus } = require('@companion-module/base')

module.exports = {
/**
* Setup the actions.
*
* @access public
* @since 2.0.0
* @returns {Object} the action definitions
*/
get_actions() {
const startStopOption = {
type: 'dropdown',
id: 'startStopAction',
label: 'Action',
choices: this.CHOICES_STARTSTOP,
default: this.CHOICES_STARTSTOP[0].id,
}

// Companion has difficulties with the first 'default' selected value.
let channels = [{ id: '0-0', label: '---' }]
Array.prototype.push.apply(channels, this.CHOICES_CHANNELS_LAYOUTS)

let publishers = [{ id: '0-0', label: '---' }]
Array.prototype.push.apply(publishers, this.CHOICES_CHANNELS_PUBLISHERS)

let recorders = [{ id: '0', label: '---' }]
Array.prototype.push.apply(recorders, this.CHOICES_RECORDERS)

const actions = {}
actions['channelChangeLayout'] = {
name: 'Change channel layout',
options: [
{
type: 'dropdown',
id: 'channelIdlayoutId',
label: 'Change layout to:',
choices: channels,
default: channels[0].id,
},
],
callback: (action) => {
let type = 'get',
url,
body,
callback

if (!action.options.channelIdlayoutId || !action.options.channelIdlayoutId.includes('-')) {
this._setStatus(
InstanceStatus.UnknownWarning,
'Channel and layout are not known! Please review your button config'
)
this.debug('channelIdlayoutId: ' + action.options.channelIdlayoutId)
return
}

const [channelId, layoutId] = action.options.channelIdlayoutId.split('-')
if (!this._getChannelById(channelId)) {
this._setStatus(
InstanceStatus.UnknownWarning,
'Action on non existing channel! Please review your button config'
)
this.log('error', 'Action on non existing channel: ' + channelId)
return
}
if (!this._checkValidLayoutId(channelId, layoutId)) {
this._setStatus(
InstanceStatus.UnknownWarning,
'Action on non existing layout! Please review your button config'
)
this.log('error', 'Action on non existing layout ' + layoutId + ' on channel ' + channelId)
return
}

type = 'put'
url = '/api/channels/' + channelId + '/layouts/active'
body = { id: Number(layoutId) }
callback = (response) => {
if (response && response.status === 'ok') {
this._updateActiveChannelLayout(channelId, layoutId)
}
}

// Send request
this._sendRequest(type, url, body).then(callback)
},
}

actions['channelStreaming'] = {
name: 'Start/stop streaming',
options: [
{
type: 'dropdown',
label: 'Channel publishers',
id: 'channelIdpublisherId',
choices: publishers,
default: publishers[0].id,
tooltip:
'If a channel has only one "publisher" or "stream" then you just select all. Else you can pick the "publisher" you want to start/stop',
},
startStopOption,
],
callback: (action) => {
let type = 'get',
url,
body,
callback

if (!action.options.channelIdpublisherId || !action.options.channelIdpublisherId.includes('-')) {
this._setStatus(
InstanceStatus.UnknownWarning,
'Channel and Publisher are not known! Please review your button config'
)
this.debug('Undefined channelIdpublisherId ... ' + action.options.channelIdpublisherId)
return
}

const [channelId, publishersId] = action.options.channelIdpublisherId.split('-')
if (!this._getChannelById(channelId)) {
this._setStatus(
InstanceStatus.UnknownWarning,
'Action on non existing channel! Please review your button config.'
)
this.log('error', 'Action on non existing channel: ' + channelId)
return
}
if (publishersId !== 'all' && !this._checkValidPublisherId(channelId, publishersId)) {
this._setStatus(
InstanceStatus.UnknownWarning,
'Action on non existing publisher! Please review your button config.'
)
this.log('error', 'Action on non existing publisher ' + publishersId + ' on channel ' + channelId)
return
}

const startStopAction = this._getStartStopActionFromOptions(action.options)
if (startStopAction === null) {
this._setStatus(InstanceStatus.UnknownWarning, 'Called an unknown action! Please review your button config.')
this.log('error', 'Called an unknown action: ' + action.options.startStopAction)
return
}

type = 'post'
if (publishersId !== 'all') {
url = '/api/channels/' + channelId + '/publishers/' + publishersId + '/control/' + startStopAction
} else {
url = '/api/channels/' + channelId + '/publishers/control/' + startStopAction
}

// Send request
this._sendRequest(type, url, body).then(callback)
},
}

actions['recorderRecording'] = {
name: 'Control recording',
options: [
{
type: 'dropdown',
label: 'Recorder',
id: 'recorderId',
choices: this.CHOICES_RECORDERS,
default: this.CHOICES_RECORDERS.length > 0 ? this.CHOICES_RECORDERS[0].id : '',
},
{
type: 'dropdown',
id: 'startStopAction',
label: 'Action',
choices: [
{ id: 99, label: '---' },
{ id: 1, label: 'Start' },
{ id: 0, label: 'Stop' },
{ id: 2, label: 'Reset' },
],
default: 1,
},
],
callback: (action) => {
let type = 'post',
url,
body,
callback

const recorderId = action.options.recorderId
if (!this._getRecorderById(recorderId)) {
this._setStatus(
InstanceStatus.UnknownWarning,
'Action on non existing recorder! Please review your button config.'
)
this.log('error', 'Action on non existing recorder ' + recorderId)
return
}

const startStopAction = action.options.startStopAction
if (startStopAction === 0) {
url = `/api/recorders/${recorderId}/control/stop`
} else if (startStopAction === 1) {
url = `/api/recorders/${recorderId}/control/start`
} else if (startStopAction === 2) {
url = `/api/recorders/${recorderId}/control/reset`
} else if (startStopAction === 99) {
return
} else {
this._setStatus(InstanceStatus.UnknownWarning, 'Called an unknown action! Please review your button config.')
this.log('error', 'Called an unknown action: ' + action.options.startStopAction)
return
}

callback = async (response) => {
if (response && response.status === 'ok') {
await this._updateRecorderStatus(recorderId)
}
}
// Send request
this._sendRequest(type, url, body).then(callback)
},
}
return actions
},
}
File renamed without changes.
30 changes: 30 additions & 0 deletions companion/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"id": "epiphan-pearl",
"name": "epiphan-pearl",
"shortname": "pearl",
"description": "Epiphan Pearl module for Companion",
"version": "0.0.0",
"license": "MIT",
"repository": "git+https://github.com/bitfocus/companion-module-epiphan-pearl.git",
"bugs": "https://github.com/bitfocus/companion-module-epiphan-pearl/issues",
"maintainers": [
{
"name": "Marc Hagen",
"email": "[email protected]"
},
{
"name": "Dorian Meid",
"email": "[email protected]"
}
],
"legacyIds": [],
"runtime": {
"type": "node18",
"api": "nodejs-ipc",
"apiVersion": "0.0.0",
"entrypoint": "../index.js"
},
"manufacturer": "Epiphan",
"products": ["Pearl"],
"keywords": ["Stream", "Encode", "Recording"]
}
55 changes: 55 additions & 0 deletions config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const { Regex } = require('@companion-module/base')

// noinspection JSUnusedGlobalSymbols
/**
* Creates the configuration fields for web config.
*
* @access public
* @since 1.0.0
* @returns {Array} the config fields
*/
const get_config_fields = () => {
return [
{
type: 'textinput',
id: 'host',
label: 'Target IP',
width: 6,
default: '192.168.255.250',
regex: Regex.IP,
},
{
type: 'textinput',
id: 'host_port',
label: 'Target Port',
width: 6,
default: '80',
regex: Regex.PORT,
},
{
type: 'textinput',
id: 'username',
label: 'Username',
width: 6,
default: 'admin',
},
{
type: 'textinput',
id: 'password',
label: 'Password',
width: 6,
default: '',
},
{
type: 'number',
id: 'pollfreq',
label: 'Feedback polling frequency in seconds',
width: 6,
default: 10,
min: 1,
max: 300,
},
]
}

module.exports = { get_config_fields }
Loading

0 comments on commit 2d03f76

Please sign in to comment.