Skip to main content
Skip table of contents

QuestStream (HMS) [VCon OG]

RecorderHms is a recorder using the HMS API to trigger recordings on HMS servers. On starting a recording,
it issues an action that assigns the file information via VidiControl mechanisms to the corresponding item in VidiControl.

Setup

The installation of a HMS recorder is done by a dynamic playbook. Below is an example (91_vpms3.recorderhms.v2.yaml from the project-rtl-poc repository):

YAML
recorderhms:
  playbook:
    name: recorderhms
    abbreviation: recorderhms
  #######################################################
  # Main Chart part                                     #
  # Work in progress                                    #
  #######################################################
  default:
    endpoints:
      http:
        fqdn: "{{ (default_endpoint_scheme + lookup('prepared_config', 'kubernetesPublicEndpoint') + '/' if not lookup('prepared_config', 'kubernetesPublicEndpoint').endswith('/') else '' | string) | urlsplit('hostname') }}"
    helm_chart:
      install: true
      chart_name: recorderhms
      chart_subpath:
      chart_folder: VidiControl/Recorders/HMS
      chart_category: VPMS
      chart_namespace: "{{ server_config.system.name }}-vctl"
      chart_instance_name: recorderhms
      chart_version: 24.3.230640-prerelease
      chart_values:
        hull:
          config:
            general:
              globalImageRegistryToFirstRegistrySecretServer: true
              fullnameOverride: recorderhms
              data:
                installation:
                  config:
                    customCaCertificates:
{% for key, value in vpms3.global.system.ssl.custom_ca_certs.items() %}
                      {{ key }}: "{{ (value | singleline) + '\n' }}"
{% endfor %}
                endpoints:
                  vidicore:
                    uri:
                      api: "{{ default_endpoint_scheme + lookup('prepared_config', 'kubernetesPublicEndpoint') + '/API'}}"
                  authservice:
                    uri:
                      api: "{{ default_endpoint_scheme + lookup('prepared_config', 'kubernetesPublicEndpoint') + vpms3.authservice.base.default.app_path_authservice }}"
                    auth:
                      token:
                        installationClientId: installerClient
                        installationClientSecret: "{{ vault.vidicontrol.base.default.installer_client_secret }}"
                  configportal:
                    uri:
                      api: "{{ default_endpoint_scheme + lookup('prepared_config', 'kubernetesPublicEndpoint') + vpms3.configportal.base.default.app_path_configportal_api }}"
                      ui: "{{ default_endpoint_scheme + lookup('prepared_config', 'kubernetesPublicEndpoint') + vpms3.configportal.base.default.app_path_configportal_ui }}"
                      notification: "{{ default_endpoint_scheme + lookup('prepared_config', 'kubernetesPublicEndpoint') + vpms3.configportal.base.default.app_path_configportal_notification }}"
                    auth:
                      token:
                        installationClientId: installerClient
                        installationClientSecret: "{{ vault.configportal.base.default.installer_client_secret }}"
                  notification:
                    uri:
                      api: "http://core-services-core-services-noti-api:8080/Platform.Core/Notification/"
                  vidispine:
                    uri:
                      api: "{{ default_endpoint_scheme + lookup('prepared_config', 'kubernetesPublicEndpoint') + '/API/' }}"
                  rule:
                    uri:
                      api: "http://core-services-core-services-rule-api:8080/Platform.Core/Rule/"
            specific:
              logging:
                loglevel:
                  Default: Debug
              ingress:
                controllerClass: "{{ vpms3.global.system.ingress.controllerClass }}"
              registry: "{{ vpms3.global.docker.registry.endpoint }}"
              authService:
                installerClientId: installerClient
                installerClientSecret: "{{ vault.vidicontrol.base.default.installer_client_secret }}"
              recorderhms:
                tag: 24.3.230640-feature-recorderhms
                devicesettings: "{\"RECORDER_HMS_API_URL\":\"http://live-rec-qvest.netrtl.com:3006\",\"RECORDER_HMS_API_KEY\":\"\",\"RECORDER_HMS_API_TIMEZONE\":\"GMT Standard Time\",\"RECORDER_HMS_API_STATUS_ONLINE\":\"CONNECTED\",\"RECORDER_HMS_STATUS_CHECK_PERIOD_IN_S\":45}"
                Uri: "http://recorderhms-vidicontrol-recorderhms.rtlpoc-vctl:8080"
              database:
                host: "{{ hostvars['sql-server']['host'] }}"
                port: "{{ hostvars['sql-server']['port'] | default(1433) }}"
                user: "{{ vpms3.vidicontrol.base.default.database_username_vidicontrol | lower}}"
                type: postgres
                names:
                  recorderhms: "{{ vpms3.global.system.name | regex_replace('-', '_') }}_vidicontrol_recorderhms"
                connectionstrings:
                  recorderhms: "User ID = {{ vpms3.vidicontrol.base.default.database_username_vidicontrol | lower}};Server={{ hostvars['sql-server']['host'] }};Port={{ hostvars['sql-server']['port'] | default(1433) }};Database={{ vpms3.global.system.name | regex_replace('-', '_') }}_vidicontrol_recorderhms;Integrated Security=true;Pooling=true;"
          objects:
            registry:
              vpms3:
                server: "{{ vpms3.global.docker.registry.endpoint }}"
                username: "{{ vpms3.global.docker.registry.user }}"
                password: "{{ vpms3.global.docker.registry.pass }}"

The versions of the Helm chart and the Docker image must be updated to the currently used versions. Additionally, the device settings must be adapted, mainly the RECORDER_HMS_API_URL and the RECORDER_HMS_API_KEY.

For installing the recorder, the preferred installation method with the tag “recorderhms” can be used, i.e.

BASH
./prepared.sh --log=vvv --tags=recorderhms

Customize config after installation

Workflow

When a recording is started a VidiFlow workflow will be triggered.
This workflow must be created, named 'WF_HmsRecording' and have 'JobInfo', 'ItemId', 'DestFileName', 'SecondDestFileName', 'DestFilePath' and 'ProfileName' as parameters (type string).
Workflow name and version can be changed via the VidiControl Configuration Tool.
The version of the workflow must correspond to the version listed in the event 'RecorderHms.recordingStarted'.
The module executes a periodic status check of the HMS server and, if necessary, sets the VidiControl device status to online or offline.

Capability

Profile must be added to the recorder capability after installation.
Add a field of type 'string' with name Profile to the input of the Capability Content.
This may also be possible with the Config UI.
Example:

JSON
"input": {
        "Profile": {  
            "label": [  
                {"Lang": "en_US", "Text": "HMS Profile"},  
                {"Lang": "de_DE", "Text": "HMS Profile"}  
              ],  
              "hint": [  
                {"Lang": "en_US", "Text": "The HMS Profile (Optional)"},  
                {"Lang": "de_DE", "Text": "Das HMS Profile (Optional)"}  
              ],  
            "type": "string",  
            "optional": "true"  
          }
    }

Configuration

The Guid for the default profile (e.g. for crash record; intial value in DeviceConfiguration:DeviceSettings RECORDER_HMS_DEFAULT_PROFILENAME) is saved as HmsDefaultProfileName in the recoder config table and can be changed via the Config UI for each Pod.

The timezone of the HMSApi (intial value in DeviceConfiguration:DeviceSettings 'RECORDER_HMS_API_TIMEZONE') is saved as HmsTimezone in the recoder config table and can be changed via the Config UI for each Pod.
The Timezone IDs are operating system dependent. To get these IDs, start the recorder once without RECORDER_EVS_NEO_API_TIMEZONE. Then it should output a warning in the logfile 'Couldn't load timezone info' and below it a list of all available timezones in the format '<TimezoneId>; <TimezoneName>'.
Example: On a windows system the timezone Id for London is 'GMT Standard Time', on Linux it is 'Europe/London'. (List of IANA timezone Ids for Linux)

additional config values

Config value

Type

Comment

VIDICONTROL_DATABASE_CONNECTION_STRING

string

VIDICONTROL_DATABASE_PASSWORD

string

VIDICONTROL_IDSALT

string

VIDICONTROL_SITEID

string

site id (alphanumeric)

RECORDER_HMS_DATABASE_CONNECTION_STRING

string

RECORDER_HMS_DATABASE_PASSWORD

string

RECORDER_HMS_API_URL

string

(DeviceConfiguration:DeviceSettings)

RECORDER_HMS_API_KEY

string

(DeviceConfiguration:DeviceSettings)

RECORDER_HMS_API_TIMEZONE

string

(DeviceConfiguration:DeviceSettings)

RECORDER_HMS_STATUS_CHECK_PERIOD_IN_S

int

(DeviceConfiguration:DeviceSettings) Interval in seconds in which the HMS recorder status check is executed, default is -1. If <=0 status check is disabled.

RECORDER_HMS_DEFAULT_PROFILENAME

string

(DeviceConfiguration:DeviceSettings)

Config for VidiControl initialization (Device, Capabilities, Events)

values for Capabilities and Events are fixed, values in DeviceConfiguration are system specific

JSON
  "DeviceConfiguration": {
    "DeviceName": "RecorderHms",
    "DeviceSettings": "{\"RECORDER_HMS_API_URL\":\"<http://10.234.1.102:3006/\>",\"RECORDER_HMS_API_KEY\":\"\",\"RECORDER_HMS_API_TIMEZONE\":\"GMT Standard Time\",\"RECORDER_HMS_STATUS_ONLINE\":\"CONNECTED\",\"RECORDER_HMS_STATUS_CHECK_PERIOD_IN_S\":45,\"RECORDER_HMS_DEFAULT_PROFILENAME\":\"XDCAMHD422\"}",
    "CapabilityGroup": "RecorderHmsGroup"
  },
  "Capability": [
    {
      "Content": "{\"action\":\"Record\",\"input\":{\"Profile\":{\"label\":\"[{\\\"Lang\\\":\\\"en_US\\\",\\\"Text\\\":\\\"HMS Profile\\\"},{\\\"Lang\\\":\\\"de_DE\\\",\\\"Text\\\":\\\"HMS Profile\\\"}]\",\"hint\":\"[{\\\"Lang\\\":\\\"en_US\\\",\\\"Text\\\":\\\"The HMS Profile (Optional)\\\"},{\\\"Lang\\\":\\\"de_DE\\\",\\\"Text\\\":\\\"Das HMS Profile (Optional)\\\"}]\",\"type\":\"string\",\"optional\":\"true\"}},\"properties\":{\"nonBlockingProvisioningTime\":{\"type\":\"integer\",\"kind\":\"fix\"}}, \"events\":[\"RecorderHms.recordingFailed\", \"RecorderHms.recordingStarted\", \"RecorderHms.recordingFinished\", \"RecorderHms.updateFinished\",\"RecorderHms.updateFailed\"]}",
      "NeedsStopCommand": true,
      "CapabilityType": 0,
      "DefaultConfig": "{\"nonBlockingProvisioningTime\":10}"
    }
  ],
  "EventType": [
    {
      "Name": "RecorderHms.recordingStarted",
      "HandleCustomerSpecific": false,
      "Description": "",
      "Content": "[{\"action\":\"notifyClient\",\"input\":{\"TimeStamp\":\"{-{Placeholder_TimeStamp}-}\",\"ChunkId\":\"{-{Placeholder_ExternalChunkId}-}\",\"UpdateNeeded\":false,\"MessageType\":\"RecorderHms.recordingStarted\",\"Emitter\":\"{-{Placeholder_Emitter}-}\",\"Severity\":\"Information\",\"Message\":[{\"Lang\":\"en_US\",\"Text\":\"Recording started.\"},{\"Lang\":\"de_DE\",\"Text\":\"Aufnahme gestartet.\"}]}},{\"action\": \"startWorkflow\",\"input\": {\"Name\": \"WF_HmsRecording\",\"Version\": \"1.Latest\",\"user\":\"{-{Placeholder_ActingUser}-}\",\"Data\": {\"Parameters\": [{\"Name\": \"JobInfo\",\"Value\": \"{-{Placeholder_JobInfo}-}\",\"Type\": \"string\"}, {\"Name\": \"ItemId\",\"Value\": \"{-{Placeholder_VCItemId}-}\",\"Type\": \"string\"}, {\"Name\": \"DestFileName\",\"Value\": \"{-{Placeholder_DestFileName}-}\",\"Type\": \"string\"}, {\"Name\": \"SecondDestFileName\",\"Value\": \"{-{Placeholder_SecondDestFileName}-}\",\"Type\": \"string\"}, {\"Name\": \"DestFilePath\",\"Value\": \"{-{Placeholder_DestFilePath}-}\",\"Type\": \"string\"}, {\"Name\": \"ProfileName\",\"Value\": \"{-{Placeholder_ProfileName}-}\",\"Type\": \"string\"}],\"Metadata\": null,\"Priority\": null}}}]"
    },
    {
      "Name": "RecorderHms.recordingFinished",
      "HandleCustomerSpecific": false,
      "Description": "",
      "Content": "[{\"action\":\"notifyClient\",\"input\":{\"TimeStamp\":\"{-{Placeholder_TimeStamp}-}\",\"ChunkId\":\"{-{Placeholder_ExternalChunkId}-}\",\"UpdateNeeded\":false,\"MessageType\":\"RecorderHms.recordingFinished\",\"Emitter\":\"{-{Placeholder_Emitter}-}\",\"Severity\":\"Information\",\"Message\":[{\"Lang\":\"en_US\",\"Text\":\"Recording finished.\"},{\"Lang\":\"de_DE\",\"Text\":\"Aufnahme beendet.\"}]}}]"
    },
    {
      "Name": "RecorderHms.recordingFailed",
      "HandleCustomerSpecific": false,
      "Description": "",
      "Content": "[{\"action\":\"notifyClient\",\"input\":{\"TimeStamp\":\"{-{Placeholder_TimeStamp}-}\",\"ChunkId\":\"{-{Placeholder_ExternalChunkId}-}\",\"UpdateNeeded\":false,\"MessageType\":\"RecorderHms.recordingFailed\",\"Emitter\":\"{-{Placeholder_Emitter}-}\",\"Severity\":\"Error\",\"Message\":[{\"Lang\":\"en_US\",\"Text\":\"Recording failed.\"},{\"Lang\":\"de_DE\",\"Text\":\"Aufnahme gescheitert.\"}]}}]"
    },
    {
      "Name": "RecorderHms.updateFailed",
      "HandleCustomerSpecific": false,
      "Description": "",
      "Content": "[{\"action\":\"notifyClient\",\"input\":{\"TimeStamp\":\"{-{Placeholder_TimeStamp}-}\",\"ChunkId\":\"{-{Placeholder_ExternalChunkId}-}\",\"UpdateNeeded\":false,\"MessageType\":\"RecorderQuantel.updateFailed\",\"Emitter\":\"{-{Placeholder_Emitter}-}\",\"Severity\":\"Information\",\"Message\":[{\"Lang\":\"en_US\",\"Text\":\"Update failed.\"},{\"Lang\":\"de_DE\",\"Text\":\"Update fehlgeschlagen.\"}]}}]"
    },
    {
      "Name": "RecorderHms.updateFinished",
      "HandleCustomerSpecific": false,
      "Description": "",
      "Content": "[{\"action\":\"notifyClient\",\"input\":{\"TimeStamp\":\"{-{Placeholder_TimeStamp}-}\",\"ChunkId\":\"{-{Placeholder_ExternalChunkId}-}\",\"UpdateNeeded\":false,\"MessageType\":\"RecorderQuantel.updateFinished\",\"Emitter\":\"{-{Placeholder_Emitter}-}\",\"Severity\":\"Information\",\"Message\":[{\"Lang\":\"en_US\",\"Text\":\"Update finished.\"},{\"Lang\":\"de_DE\",\"Text\":\"Update erfolgreich.\"}]}}]"
    }
  ]

Device

Requires a ConnectionInfo with HMS Channel Name (RecorderRef) and Profile

JSON
{
    "RecorderRef": "SomeHMSChannelName",
    "Profile": "SomeHMSProfile
}

Capability

Requires a Content with an input parameter 'Profile'

JSON
{
    "action": "Record",
    "input": {
        "Profile": {  
            "label": [  
                {"Lang": "en_US", "Text": "HMS Profile"},  
                {"Lang": "de_DE", "Text": "HMS Profile"}  
              ],  
              "hint": [  
                {"Lang": "en_US", "Text": "The HMS Profile (Optional)"},  
                {"Lang": "de_DE", "Text": "Das HMS Profile (Optional)"}  
              ],  
            "type": "string",  
            "optional": "true"  
          }    },
    "output": {
    },
    "properties": {
        "preroll": {
            "type": "integer",
            "kind": "fix"
        }
    },
    "events": ["RecorderHms.recordingFailed", "RecorderHms.recordingStarted", "RecorderHms.recordingFinished", "RecorderHms.updateFinished", "RecorderHms.updateFailed"]
}
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.