JavaScript tasks

A JavaScript task is created by including the JavaScript in the task definition document. To evaluate the script Vidispine uses a JavaScript engine. A number of global variables are defined for the script to use, see Common JavaScript functions.

In addition for task definitions, there is the job object.

The job object

The job object contains methods for reading and writing metadata for the job that is executing, and also for some job control.

job.getId()

Gets the id of the job that is executing.

job.log(description)

Logs a message related to the current job step.

job.getData(key)

Gets the data for the given key.

job.setData(key, value)

Sets the data for the given key.

The value should be a primitive type such as a string or an integer. If given an array as value, it will converted into a comma-separated string.

job.deleteData(key)

Removes the given key from the job data.

job.fail(errorMessage)

Fails the current step, but the step will be retried (up to five times).

job.fatalFail(errorMessage)

Fails the current step and job.

job.getUser()

Gets the user of the job. It replaces the old way of getting the user name using job.getData("username").

job.getKeys()

Returns all the keys from the job data.

New in version 4.16.

job.containsKey(key)

Checks if the job data contains the key.

New in version 4.16.

job.getDataOrDefault(key, value)

Returns the value from the job data or the given default value.

New in version 4.16.

job.getStepId()

Returns the current job step id.

New in version 5.0.

Pausing job execution

A JavaScript job step can pause the execution of the job by calling job.wait(). This will set the job in the WAITING job state. To determine if the job execution can be resumed, the script is run again every minute with the variable checkProblem set to true. If the job should keep waiting, then job.wait() should be called again.

job.wait(reason)

Sets the job in WAITING state.

Arguments:
  • reason (string) – An explanation of what the job is waiting for.

Example

if (checkProblem) {
  if (/* condition is fulfilled */ ...) {
    return;
  }
  // Call job.wait() to indicate that the job should wait more
  // See note above
  job.wait("condition still not fulfilled");

} else {
  // run step as normal
  ....

  if (/* condition is not fulfilled */ ...) {
    job.wait("waiting for condition");
    return;
  }

  // continue job execution
  ....
}

Vidinet job execution

Jobs can be submitted to Vidinet services, for execution or for cost estimates, using the Vidinet functions on the job object.

job.vidinetJob(type, instruction, settings)

Submits a job to Vidinet and sets the job in VIDINET_JOB state.

Arguments:
  • type (string) – The type of Vidinet resource to use, for example, AURORA.
  • instruction (string) – The job instruction.
  • settings (object) –

    A set of key/value pairs related to the job.

    • item - The id of the item that the job relates to.
    • shape - The id of the shape that the job relates to. Optional. Overrides tag.
    • tag - The shape of the item that the job relates to. Default is original.
    • resource - The specific Vidinet resource to submit the job to.
job.vidinetCost(type, instruction, settings)

Request a cost estimate from Vidinet.

Arguments:
  • type (string) – The type of Vidinet resource to use, for example, AURORA.
  • instruction (string) – The job instruction.
  • settings (object) –

    A set of key/value pairs related to the job.

    • item - The id of the item that the job relates to.
    • shape - The id of the shape that the job relates to. Optional. Overrides tag.
    • tag - The shape of the item that the job relates to. Default is original.
    • resource - The specific Vidinet resource to submit the job to.
Returns:

A Future<CostEstimateType> that can be used to retrieve the estimate.

Example

To submit a job to a Vidinet service that is not natively supported:

var item = ...;
var instruction = "...";

job.vidinetJob("TEST", instruction, {
    item: itemId
});

In case a cost estimate is wanted before submitting the job to Vidinet:

var item = ...;
var instruction = "...";
var settings = {
  item: itemId
};

if ("true".equals(job.getData("estimate"))) {
  var estimate = job.vidinetCost("TEST", instruction, settings);
  var result = estimate.get(); // blocking call

  var cost = result.getService().get(0).getCost();
  job.setData("app_estimated_cost", cost.getAmount());
} else {
  job.vidinetJob("TEST", instruction, settings);
}

Example: Update item metadata on import

Start by adding a new task to the import job with the script to execute.

Note

If using curl, use --data-binary instead of -d to make sure all new-line characters are kept in the script.

POST /task-definition/
Content-Type: application/xml

<TaskDefinitionListDocument xmlns="http://xml.vidispine.com/schema/vidispine">
  <task>
    <description>Updating item metadata using a JavaScript task</description>
    <script><![CDATA[
...
]]></script>
    <step>10000</step>
    <dependency>
      <previous>false</previous>
      <allPrevious>true</allPrevious>
    </dependency>
    <jobType>PLACEHOLDER_IMPORT</jobType>
    <critical>false</critical>
  </task>
</TaskDefinitionListDocument>
// Retrieve the id of the item that is being imported
var itemId = job.getData("itemId");
var shapeId = job.getData("originalShapeId");

// Retrieve the shape information
var shape = api.path("item/"+itemId+"/shape/"+shapeId).get();
var video = shape.videoComponent.length;
var audio = shape.audioComponent.length;

// Build a document with the metadata to set
var metadata = {
  "timespan": [
    {
      "start": "-INF",
      "end": "+INF",
      "field": [
        {
          "name": "title",
          "value": [
            {
              "value": "Item with "+video+" video and "+audio+" audio tracks"
            }
          ]
        }
      ]
    }
  ]
};

// Update the item metadata
var result = api.path("item/"+itemId+"/metadata").input(metadata).put();
var metadata = result.item[0].metadata;

Example: Update item metadata on import using XML

Scripts can also use ECMAScript for XML (E4X) to easily create and parse XML documents. Using E4X the above script could be written as below. Note that the XML responses from Vidispine will automatically be parsed into E4X XML objects instead of being returned as strings.

// Set the default XML namespace so that the Vidispine namespace does not have
// to be specified when retrieving properties or when building the metadata document
default xml namespace = "http://xml.vidispine.com/schema/vidispine";

// Retrieve the id of the item that is being imported
var itemId = job.getData("itemId");
var shapeId = job.getData("originalShapeId");

// Retrieve the shape information
var shape = api.path("item/"+itemId+"/shape/"+shapeId).dataType("xml").get();
var video = shape.videoComponent.length();
var audio = shape.audioComponent.length();

// Build a document with the metadata to set
var metadata = <MetadataDocument>
  <timespan start="-INF" end="+INF">
    <field>
      <name>title</name>
      <value>Item with {video} video and {audio} audio tracks</value>
    </field>
  </timespan>
</MetadataDocument>

// Update the item metadata
var result = api.path("item/"+itemId+"/metadata").input(metadata).put();
var metadata = result.item[0].metadata;