Skip to main content
Skip table of contents

Quantel (sQ Servers) [VCon OG]

RecorderQuantel is a recorder using the DirectConnect API (v2.6.21) to trigger recordings and create clips on Grassvalley's sQ servers. On starting a recording, it is assigned a clipId and metadata 'owner' with a defined ownerPrefix. The latter can be used (and is used at TV2 and HSB) by a customjob to transfer the clip to VidiCore avoiding duplicate creation.

Setup

The installation of a RecorderQuantel is done by a dynamic playbook. Below is an example (91_vpms3.tv2recorderquantel.v2.yaml from the tv2-prod inventory of the project-tv2 repository):

YAML
tv2recorderquantel:
  playbook:
    name: tv2recorderquantel
    abbreviation: tv2recorderquantel
  #######################################################
  # 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: tv2recorderquantel
      chart_subpath:
      chart_folder: VidiControl/Recorders/Quantel
      chart_category: VPMS
      chart_namespace: "{{ server_config.system.name }}-vctl"
      chart_instance_name: tv2recorderquantel
      chart_version: 24.2.246644
      chart_values:
        hull:
          config:
            general:
              globalImageRegistryToFirstRegistrySecretServer: true
              fullnameOverride: tv2recorderquantel
              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:
              ingress:
                controllerClass: "{{ vpms3.global.system.ingress.controllerClass }}"
              registry: "{{ vpms3.global.docker.registry.endpoint }}"
              authService:
                installerClientId: installerClient
                installerClientSecret: "{{ vault.vidicontrol.base.default.installer_client_secret }}"
              recorderquantel:
                tag: 24.2.246644
                devicesettings: "{\\\"QUANTEL_HTTP_CONNECTIONSTRING\\\":\\\"http://10.22.60.11/\\\",\\\"QUANTEL_WS_CONNECTIONSTRING\\\":\\\"ws://10.22.60.11/websocket/\\\",\\\"QUANTEL_MAX_RECORDING_HOURS\\\":\\\"12\\\",\\\"QUANTEL_RECORDER_ID\\\":\\\"RecA\\\",\\\"QUANTEL_TIMEZONE\\\":\\\"UTC\\\",\\\"QUANTEL_CLIP_METADATA_FIELDS_FOR_CHUNKID\\\":\\\"owner\\\",\\\"QUANTEL_STATUS_ONLINE\\\":\\\"Idle,Record\\\",\\\"QUANTEL_VERSION\\\":\\\"V2.6.21/001\\\",\\\"QUANTEL_STATUS_CHECK_PERIOD_IN_S\\\":\\\"45\\\",\\\"QUANTEL_TCSOURCE\\\":\\\"ref\\\"}"
                devicename: "RecorderQuantel_5081"
                recorderquantelgroup: "RecorderQuantelGroup"
              database:
                host: "{{ hostvars['sql-server']['host'] }}"
                port: "{{ hostvars['sql-server']['port'] | default(1433) }}"
                user: "{{ hostvars['sql-server']['admin_user'] }}"
                type: postgres
                names:
                  recorderquantel: "{{ vpms3.global.system.name | regex_replace('-', '_') }}_vidicontrol_recorderquantel"
                connectionstrings:
                  recorderquantel: "User ID = {{ hostvars['sql-server']['admin_user'] }};Server={{ hostvars['sql-server']['host'] }};Port={{ hostvars['sql-server']['port'] | default(1433) }};Database={{ vpms3.global.system.name | regex_replace('-', '_') }}_vidicontrol_recorderquantel;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 }}"
            service:
              recorderquantel:
                selector:
                  app.kubernetes.io/component: vidicontrol-recorderquantel
                  app.kubernetes.io/instance: tv2recorderquantel
                  app.kubernetes.io/name: tv2recorderquantel
            deployment:
              vidicontrol-recorderquantel:
                replicas: 0

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 QUANTEL_HTTP_CONNECTIONSTRING and QUANTEL_WS_CONNECTIONSTRING.

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

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

Customize config after installation

Workflow

By default no workflow is configured for a recording start. If neccesary see i.e.
Flics Ingest [VCon OG] | Workflow
how to trigger and configure a VidiFlow workflow.

Capability

Source and Template are read from the FLICS cluster on module start. When available in the front end the input can be switched to the DynamicEnumValue entries Template and Source

Example:

JSON
"input": {
        "Source": {
            "defaultValue": null,
            "externalDataIdentifier": "",
            "hint": "[{\"Lang\":\"en_US\",\"Text\":\"The SRT Source\"},{\"Lang\":\"de_DE\",\"Text\":\"Die SRT Quelle\"}]",
            "items": {
                "item0": {
                    "default": true,
                    "label": "SRT1",
                    "value": "SRT1"
                },
                "item1": {
                    "default": false,
                    "label": "Zuspieler2",
                    "value": "Zuspieler2"
                },
                "item2": {
                    "default": false,
                    "label": "SRT",
                    "value": "SRT"
                },
                "item3": {
                    "default": false,
                    "label": "DJSRT",
                    "value": "DJSRT"
                }
            },
            "label": "[{\"Lang\":\"en_US\",\"Text\":\"SRT Source\"},{\"Lang\":\"de_DE\",\"Text\":\"SRT Quelle\"}]",
            "optional": null,
            "type": "enum"
        },
        "Template": {
            "defaultValue": null,
            "externalDataIdentifier": "",
            "hint": "[{\"Lang\":\"en_US\",\"Text\":\"The Target Template\"},{\"Lang\":\"de_DE\",\"Text\":\"Das Ziel Template\"}]",
            "items": {
                "item0": {
                    "default": true,
                    "label": "Live XDCAM GROWING",
                    "value": "586a2314-34f9-4d76-b268-d5873a611695"
                },
                "item1": {
                    "default": false,
                    "label": "Live XDCAM GROWING HISCALE",
                    "value": "ebecb908-f9a6-4f2c-9a77-92132e37dcfe"
                },
                "item2": {
                    "default": false,
                    "label": "Live XRDD25 GROWING",
                    "value": "f12a8bab-2b0f-41cf-9d71-90ee599c6848"
                },
                "item3": {
                    "default": false,
                    "label": "LiveSD Template",
                    "value": "fa18fe20-2744-4d71-8d22-5b8d4e0a6a6f"
                },
                "item4": {
                    "default": false,
                    "label": "RDD25 50p",
                    "value": "e3725ca1-b2ce-4c3e-82ad-1a2b9029cab2"
                },
                "item5": {
                    "default": false,
                    "label": "RDD25 Growing",
                    "value": "f63f598c-3517-4c63-add8-d3882df7f46f"
                }
            },
            "label": "[{\"Lang\":\"en_US\",\"Text\":\"Target Template\"},{\"Lang\":\"de_DE\",\"Text\":\"Ziel Template\"}]",
            "optional": null,
            "type": "enum"
        }
    }

Configuration

Config value

Type

Comment

VIDICONTROL_DATABASE_CONNECTION_STRING

string

VIDICONTROL_DATABASE_PASSWORD

string

VIDICONTROL_IDSALT

string

VIDICONTROL_SITEID

string

site id (alphanumeric)

RECORDER_QUANTEL_DATABASE_CONNECTION_STRING

string

RECORDER_QUANTEL_DATABASE_PASSWORD

string

QUANTEL_VERSION

string

(DeviceConfiguration:DeviceSettings)

QUANTEL_HTTP_CONNECTIONSTRING

string

(DeviceConfiguration:DeviceSettings)

QUANTEL_WS_CONNECTIONSTRING

string

(DeviceConfiguration:DeviceSettings)

QUANTEL_CLIP_METADATA_FIELDS_FOR_CHUNKID

string

(DeviceConfiguration:DeviceSettings)

Comma-separated list of clip metadata fields the vidicontrol-id should be written to

QUANTEL_STATUS_CHECK_PERIOD_IN_S

string

(DeviceConfiguration:DeviceSettings)

QUANTEL_MAX_RECORDING_HOURS

string

(DeviceConfiguration:DeviceSettings)

Maximal length of a recording

QUANTEL_TIMEZONE

string

(DeviceConfiguration:DeviceSettings)

Time zone of the Quantel server (required to calculate starttime)

QUANTEL_TCSOURCE

string

(DeviceConfiguration:DeviceSettings)

'ref' for system reference timecode or 'port' for port timecode (required to set starttime)

QUANTEL_SWITCHTOBLACK_DEVICEID

string

(DeviceConfiguration:DeviceSettings)

(internal) deviceid of the sole router in the system

QUANTEL_BLACK_PORTID

string

(DeviceConfiguration:DeviceSettings)

(internal) inportid of the 'black' port to be switched to after stopping the recording

QUANTEL_CRASH_RECORD_DELTA_S

string

(DeviceConfiguration:DeviceSettings)

time period in sec. after now() within which a recording will be started immediately (crash)

The Timezone IDs are operating system dependent. To get these IDs, start the recorder once without QUANTEL_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)

Config for VidiControl initialization (Device, Capabilities, Events)

JSON
  "DeviceConfiguration": {
    "DeviceName": "RecorderQuantel",
    "Uri": "",
    "DeviceSettings": "{\"QUANTEL_VERSION\":\"V2.6.21/001\",\"QUANTEL_HTTP_CONNECTIONSTRING\":\"<http://<Url> of sQ>/\", \"QUANTEL_WS_CONNECTIONSTRING\":\"ws://<Url of sQ>/websocket/\",\"QUANTEL_CLIP_METADATA_FIELDS_FOR_CHUNKID\":\"owner,description\",\"QUANTEL_TIMEZONE\":\"UTC\",\"QUANTEL_TCSOURCE\":\"ref\"}",
    "CapabilityGroup": "RecorderQuantelGroup"
  },
  "Capability": [
    {
      "Content": "{\"action\":\"Record\", \"properties\":{\"blockingProvisioningTime\":{\"type\":\"integer\",\"kind\":\"fix\"}}, \"events\":[\"RecorderQuantel.recordingFailed\", \"RecorderQuantel.recordingStarted\", \"RecorderQuantel.recordingFinished\", \"RecorderQuantel.updateFinished\", \"RecorderQuantel.updateFailed\"]}",
      "NeedsStopCommand": true,
      "CapabilityType": 0,
      "DefaultConfig": "{\"blockingProvisioningTime\":10}"
    }
  ],
  "EventType": [
    {
      "Name": "RecorderQuantel.recordingStarted",
      "HandleCustomerSpecific": false,
      "Description": "",
      "Content": "[{\"action\":\"notifyClient\",\"input\":{\"TimeStamp\":\"{-{Placeholder_TimeStamp}-}\",\"ChunkId\":\"{-{Placeholder_ExternalChunkId}-}\",\"UpdateNeeded\":false,\"MessageType\":\"RecordeQuantel.recordingStarted\",\"Emitter\":\"{-{Placeholder_Emitter}-}\",\"Severity\":\"Information\",\"Message\":[{\"Lang\":\"en_US\",\"Text\":\"Recording started.\"},{\"Lang\":\"de_DE\",\"Text\":\"Aufnahme gestartet.\"}]}}]"
    },
    {
      "Name": "RecorderQuantel.recordingFinished",
      "HandleCustomerSpecific": false,
      "Description": "",
      "Content": "[{\"action\":\"notifyClient\",\"input\":{\"TimeStamp\":\"{-{Placeholder_TimeStamp}-}\",\"ChunkId\":\"{-{Placeholder_ExternalChunkId}-}\",\"UpdateNeeded\":false,\"MessageType\":\"RecorderQuantel.recordingFinished\",\"Emitter\":\"{-{Placeholder_Emitter}-}\",\"Severity\":\"Information\",\"Message\":[{\"Lang\":\"en_US\",\"Text\":\"Recording finished.\"},{\"Lang\":\"de_DE\",\"Text\":\"Aufnahme beendet.\"}]}}]"
    },
    {
      "Name": "RecorderQuantel.RecordingFailed",
      "HandleCustomerSpecific": false,
      "Description": "",
      "Content": "[{\"action\":\"notifyClient\",\"input\":{\"TimeStamp\":\"{-{Placeholder_TimeStamp}-}\",\"ChunkId\":\"{-{Placeholder_ExternalChunkId}-}\",\"UpdateNeeded\":false,\"MessageType\":\"RecorderQuantel.recordingFailed\",\"Emitter\":\"{-{Placeholder_Emitter}-}\",\"Severity\":\"Information\",\"Message\":[{\"Lang\":\"en_US\",\"Text\":\"Recording failed.\"},{\"Lang\":\"de_DE\",\"Text\":\"Aufnahme gescheitert.\"}]}}]"
    },
    {
      "Name": "RecorderQuantel.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": "RecorderQuantel.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.\"}]}}]"
    }
  ]
JavaScript errors detected

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

If this problem persists, please contact our support.