diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md new file mode 100644 index 0000000..56355ff --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md @@ -0,0 +1,38 @@ +--- +name: Bug Report +description: Use this if you've found a bug +title: "Bug Report: [Short description of the bug]" +labels: 🐛bug +assignees: '' + +--- + + + +## About Me + + +## Observed Behavior + + +## Expected Behavior + + +## Version + + +## Severity / Impact + + + diff --git a/.github/ISSUE_TEMPLATE/OTHER.md b/.github/ISSUE_TEMPLATE/OTHER.md new file mode 100644 index 0000000..9b597cd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/OTHER.md @@ -0,0 +1,22 @@ +--- +name: Other Issue +description: Use this for other issues +title: "Other: [Short description of the issue]" +labels: "Other" +assignees: '' + +--- + + + +## About Me + + +## Issue + diff --git a/.github/ISSUE_TEMPLATE/QUESTION.md b/.github/ISSUE_TEMPLATE/QUESTION.md new file mode 100644 index 0000000..39d6f48 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/QUESTION.md @@ -0,0 +1,22 @@ +--- +name: Question +description: Use this if you have a question to the Sofie team +title: "Question: [Short summary of the question]" +labels: ❓ Question +assignees: '' + +--- + + + +## About Me + + +## My Question + diff --git a/.github/ISSUE_TEMPLATE/RFC.md b/.github/ISSUE_TEMPLATE/RFC.md new file mode 100644 index 0000000..4cc485c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/RFC.md @@ -0,0 +1,46 @@ +--- +name: Request for Comments +description: Use this to initiate a discussion about a new feature or a larger change +title: "RFC: [Short description of the feature/change]" +labels: RFC, Contribution +assignees: '' + +--- + + + +## About Me + + +## Background + + + +## Proposal + + + +## Status + + +The Sofie Team will evaluate this RFC and open up a discussion about it, usually within a week. + +- [x] RFC created +- [ ] Sofie Team has evaluated the RFC +- [ ] A workshop has been planned +- [ ] RFC has been discussed in a workshop +- [ ] A conclusion has been reached, see comments in thread. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index caae6b1..92803e9 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,13 +1,56 @@ -* **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) + +## About the Contributor + -* **What is the current behavior?** (You can also link to an open issue here) +## Type of Contribution +This is a: + +Bug fix / Feature / Code improvement / Documentation improvement / Other (please specify) -* **What is the new behavior (if this is a feature change)?** +## Current Behavior + +## New Behavior + -* **Other information**: + +## Testing Instructions + + + +## Other Information + + + +## Status + + +- [ ] PR is ready to be reviewed. +- [ ] The functionality has been tested by the author. +- [ ] Relevant unit tests has been added / updated. +- [ ] Relevant documentation (code comments, [system documentation](https://nrkno.github.io/sofie-core/)) has been added / updated. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..8256f69 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,12 @@ +# How to Contribute to this Repository + +Before contributing to this specific repository, please read the [Contribution Guidelines](https://nrkno.github.io/sofie-core/docs/for-developers/contribution-guidelines) for the _Sofie_ project. + + +## Branches +This repository uses the following branches: + +* The **_master_** is our main branch. We consider it stable and it is used in production. +* The **_develop_** branch is our unstable branch, it is used for staging, testing and development. + +We encourage you to base your contributions on the latest **_master_** branch of this repository (alternatively the **_develop_** branch). diff --git a/README.md b/README.md index 7fcb362..4950a6d 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,18 @@ +# Sofie Quantel Gateway +This is the _Quantel Gateway_ application of the [**Sofie** TV Automation System](https://github.com/nrkno/Sofie-TV-automation/). This application uses native bindings to bridge the Quantel ISA System CORBA API and a Sofie-specific HTTP REST API, allowing discovery of clips and playback control of Quantel servers. -# Sofie: The Modern TV News Studio Automation System (Quantel gateway) +## General Sofie System Information +* [_Sofie_ Documentation](https://nrkno.github.io/sofie-core/) +* [_Sofie_ Releases](https://nrkno.github.io/sofie-core/releases) +* [Contribution Guidelines](CONTRIBUTING.md) +* [License](LICENSE) -This is a part of the [**Sofie** TV News Studio Automation System](https://github.com/nrkno/Sofie-TV-automation/). +--- -## Abstract -This library uses native bindings to bridge the Quantel ISA System CORBA API and a Sofie-specific HTTP REST API, allowing discovery of clips and playback control of Quantel servers. +## Supported Devices +* Grass Valley _sQ Series_ media servers via ISA System. -## Supported devices -* [Grass Valley sQ series media servers](https://www.grassvalley.com/products/sq_1000_servers/) via ISA System. - -## Install instructions +## Installation This software can be built for Windows and Linux platforms: @@ -17,7 +20,7 @@ This software can be built for Windows and Linux platforms: * On Windows, the required DLL and LIB files are included with this package. The included OmniORB was built with Visual Studio 2017 for x64 architecture. The native extension runs with the 64-bit version of Node.js. -This addon has not been built for or tested on MacOS. +This addon has not been built for or tested on macOS. ### Prerequisites @@ -41,7 +44,7 @@ Build the typescript interface module: yarn build -This package has automated tests that run with [jest](). Test with: +This package has automated tests that run with _jest_. Test with: yarn test @@ -70,13 +73,13 @@ For example: yarn server --port 9876 --isa qisa01:2099 --dummy true --watchdog 30 -### Run with docker +### Run with Docker Available on the [Sofie TV docker hub](https://hub.docker.com/u/sofietv): docker pull sofietv/tv-automation-quantel-gateway:master -### Experimenting and importing +### Experimenting and Importing Experiment from the REPL with: @@ -87,7 +90,7 @@ Import into an external project with: import { Quantel } from 'tv-automation-quantel-gateway' const { Quantel } = require('tv-automation-quantel-gateway') -See the [walkthrough for how to do playback](./doc/plyout_walkthrough.md) with this module as a Node.js API. +See the [walkthrough for how to do playback](./doc/playout_walkthrough.md) with this module as a Node.js API. ## HTTP API @@ -105,7 +108,7 @@ ISA systems are normally deployed in _master_ and _slave_ pairs. The `:address` A successful request produces a JSON response with the discovered IOR (`isaIOR`) and ISA endpoint address (`href`). Subsequently, the currently configured connection can be queried with a GET request to `/connect`. -### Topology of a Quantel system +### Topology of a Quantel System In general, paths are all of the form ... @@ -169,7 +172,7 @@ A GET request to the zones name (`/:zoneID/server/`) retrieves details of all th } ] ``` -### Create a port +### Creating a Port To assign a channel to a port, choose a suitable `:portID` and PUT an empty document to ... @@ -226,7 +229,7 @@ Add `/properties` to the port to get name/value pair configuration properties fo /:zoneID/server/:serverID/port/:portID/properties -### Clip references +### Clip References _Fragments_ of _clips_ are loaded onto _ports_. This means that an automation system is responsible of associating a specific video clip to appear on an output _channel_ (SDI ports). Clips are referenced by their integer identifier (`:clipID`) ... @@ -306,7 +309,7 @@ This produces (a few fields omitted): } ``` -### Loading clips +### Loading Clips Clips consist of _fragments_. To play a _clip_, or a sub-clip of a clip, it is necessary to load fragments onto a port. To query all fragments for a clip: @@ -352,7 +355,7 @@ To load the fragments onto a port, POST the fragments to the port reference, add Information about the status of the port is returned. -### Port fragment operations - query and wipe +### Port Fragment Operations — Query and Wipe The fragments that are loaded onto a port can be queried with a GET request to: @@ -370,7 +373,7 @@ The `:start` parameter is the first frame in the port's timeline to wipe from an To completely clear a port of all fragments, see port reset. -### Cloning clips +### Cloning Clips The Quantel systems have a mechanism to clone clips between servers, either within in the same zone or between servers in different zones (_inter-zone cloning_). Only the source essence material that is missing from a particular destination disk pool is copied. Where the material has already been duplicated, this means that a request to clone can be almost instantaneous. The Quantel gateway allows clones to be initiated and the subsequent copy progress of that or any other clone to be monitored. @@ -424,7 +427,7 @@ A clip can be deleted by sending a DELETE request to its path: Note that the clip metadata will persist in the database but the essence will be removed, setting the `Frames` field to `0`. -### Controlling the port +### Controlling the Port To control the PORT, POST trigger messages: @@ -432,7 +435,7 @@ To control the PORT, POST trigger messages: The `:trigger` is one of `START`, `STOP` or `JUMP`. Note that `STOP` is equivalent to CasparCG _pause_. To _resume_, use `START`. The optional `:offset` is a frame at which to trigger the action, for example `.../trigger/STOP?offset=345` signals that the playing of the clip should stop at frame 345 on the ports timeline. -#### Hard jump +#### Hard Jump To force a hard jump to specific point, ideally when stopped and not on air, POST to: @@ -440,7 +443,7 @@ To force a hard jump to specific point, ideally when stopped and not on air, POS This will cause an immediate jump and - if the video is playing - it will pause on the jumped-to frame. If the video at the jump-to point is not currently loaded on the port, a short period of black may be played out. -#### Triggered jump +#### Triggered Jump For smoother jumping, each port can have a controlled jump point set and can cause a triggered jump. As long as the jump point is set with a second or more to spare, the material to jump to will be loaded onto the port. This enables smooth playing across the jump, e.g. to achieve a smooth loop. To set the triggered jump point: @@ -461,7 +464,7 @@ All error responses are in JSON format and includes properties for a numerical ` } ``` -### Shutting down +### Shutting Down To request that the application shuts down, POST to @@ -469,7 +472,7 @@ To request that the application shuts down, POST to This will wait 5 seconds and then initiate web server and Quantel connection shutdown. If the application is running in a docker container with automatic restart enabled, the server will restart. -### Debug logging +### Debug Logging The application can be told to activate debug-logging at runtime by POST:ing to @@ -486,4 +489,7 @@ Unless otherwise called out in the header of a file, the files of this project a Please also note the specific terms of the [`Quentin.idl`](./include/quantel/Quentin.idl) file. -Copyright (c) 2019 Norsk rikskringkasting AS (NRK) +--- + +_The NRK logo is a registered trademark of Norsk rikskringkasting AS. The license does not grant any right to use, in any way, any trademarks, service marks or logos of Norsk rikskringkasting AS._ + diff --git a/doc/playout_walkthrough.md b/doc/playout_walkthrough.md index fd89525..4a4df0f 100644 --- a/doc/playout_walkthrough.md +++ b/doc/playout_walkthrough.md @@ -1,11 +1,11 @@ -## Playout walkthrough - Node API +# Playout Walkthrough – Node API Follow the steps in this document to run a Quantel playout using the Node.js API directly, rather than via the HTTP API. This document assumes that the Quantel gateway has been imported as module `Quantel`, e.g.: const { Quantel } = require('.') import { Quantel } from 'tv-automation-quantel-gateway' -### Server Connection +## Server Connection If the ISA is running on the localhost on the default port, each of the calls will establish connection automatically. Otherwise, it is necessary to estabinsh the ISA IOR reference with a call to: @@ -22,15 +22,15 @@ Quantel.testConnection().then(console.log) // 'PONG!' on success ``` -### Playout walkthrough +## Playout Walkthrough The following example assumes you are using the Node.js REPL. As all methods return promises, in a project it is recommended that `async`/`await` are used. -#### Record a clip +### Record a Clip This following steps assume that you have already stored clips onto servers. With the dummy servers, the _Controller UI_ can be used to do this. Select the _System_ tab, click on a server (e.g. _1100_), double click on a channel (e.g. _S1100C2_), put the port into record mode, select number of frames to record (default _1000_), click _Initial Frames_ then click _Start_. Once recording is complete, click _Save_. Once finished, click _Release_ to release the port. -#### Create a playout port +### Create a Playout Port An single ISA software system controls a _zone_. To find out details of the current zone: @@ -92,7 +92,7 @@ assigned: true } Note that the `assigned` flag is `true` only if the port is newly created, otherwise it is set to `false`. Also note that it is very easy to steal someone else's port! -#### Find fragments +### Find Fragments To be able to play a clip, the fragments that make up that clip must be loaded onto a port. The details of what fragments are required and where they are stored are available in the database attached to ISA. To query the fragments for a clip with ID `2`: @@ -129,7 +129,7 @@ fragments: rushFrame: 0 } ] } ``` -#### Load fragments onto port +### Load Fragments onto Port To load fragments onto a port, the server with the port must also have the disk storage `pool` where the fragments are stored attached. Otherwise a clone will need to be initiated (to follow). Loading the clips at offset 0 in the timeline of the port: @@ -137,7 +137,7 @@ To load fragments onto a port, the server with the port must also have the disk Quantel.loadPlayPort({ serverID: 1100, portName: 'nrk8', offset: 0, fragments: frags }) ``` -#### Check port status +### Check Port Status At any time after the creation of a port and before its release, it is possible to check its status: @@ -159,7 +159,7 @@ framesUnused: 0 } The status message includes the current position of the play head (`offset`) measured in frames and the speed that the media is play at (float value, `0.5` for half speed, `-1.0` for reverse etc..). (To follow: setting speed?) -#### Control playout +#### Control Playout To start and stop playback, use triggers. For example: @@ -185,7 +185,7 @@ Note that if the port is playing when asked to jump, it will jump and stop. To follow: get `setJump` to work. -#### Release the port +### Release the Port Once playout is finished, release the port and its resources with: