Publishing Point API

Managing Publishing Points

The REST API can perfom the various tasks involved in managing a publishing point. Publishing points can be created using HTTP reqests. State, statistics and more information can also be retrieved. Purging video data and being able to delete the publishing point provides an extra layer of automation workflow.

There are several restrictions when using the API, as proper operation of publishing points must be ensured. Please read the requirements per section carefully.

Configuration

The URLs point to the server manifest files directly and have no additional virtual path.

This means that URLs ending in the extension .isml are handled by the API, and any URLs having an additional 'virtual path' are handled by the Origin.

This allows for simple configuration and enabling or disabling of the API, for instance when using Apache:

DocumentRoot "/path/to/www/live"

<LocationMatch "\.isml">
  UspHandleApi on
</LocationMatch>

and when using Nginx:

location ~ \.isml {
  root /path/to/www/live;
  usp_handle_api;
}

By adding UspHandleApi on or usp_handle_api you can toggle the API on or off.

Attention

The .isml extension is also handled by the origin module. Therefore, a different virtual host and (sub)domain must be used.

For instance, the virtual host and subdomain where the encoder POSTs and the player (or CDN) connect may look like the followin:

<VirtualHost *:80>
  ServerName live
  DocumentRoot /path/to/www/live

The corresponding API virtual host then may look like this:

<VirtualHost *:80>
  ServerName live-api
  DocumentRoot /path/to/www/live

Access to the API urls should be setup on the new virtual host (access based on ip address and/or a password are both good options). In the case of Apache (2.4) this looks like the following:

<Directory "/path/to/www/live">
  Require all denied
  <RequireAll>
    AuthType Basic
    AuthName "Restricted Content"
    AuthUserFile YOUR_PASSWORD_FILE
    Require valid-user
    Require ip LIST_OF_IP_ADDRESSES
  </RequireAll>
</Directory>

The API handles the four calls described in the next section, the calls to 'state', 'statistics' and 'purge' (see below) must be executed against the actual publishing point, e.g. the url the encoder is pushing to and the clients (or CDN) are fetching from.

Using the REST API

The REST API uses the HTTP verbs (POST, GET, PUT, DELETE) to Create, Read, Update and Delete. The request/response body can contain a publishing point server manifest formatted as a XML smil file.

HTTP Verb Operation Description
POST Create Creates a new publishing point.
GET Read Reads the settings for a publishing point.
PUT Update Updates the settings for a publishing point.
DELETE Delete Delete a publishing point.

Publishing Point resource URL

A resource URL has the following syntax:

http(s)://<hostname>/<path>/<publishingpoint>.isml

with the following parameters:

Parameter Description Example
hostname The host name live.unified-streaming.com
path The path to the publishing point channel00
publishingpoint Publishing point filename channel00.isml

Create

The create operation creates a new publishing point on the server.

A publishing point and all related files reside in a single directory on disk. This directory is created with the creation of a publishing point, and is restricted to a few requirements.

Some encoders can pass query parameters as part of the publishing URL as well, see Using query parameters to control LIVE ingest for the options available.

Requirements

  • The directory does not exist prior to the operation.
  • The directory name expressed in the URL must have the same name as the isml.
  • The directory cannot be created as a subdirectory of an existing publishing point.
  • The webserver user account must have write access.

HTTP body

The request body is a smil file describing how the publishing point should be created - all Options for LIVE ingest and Unified Origin - DRM can be used when creating the smil file, created with for instance mp4split.

The default SMIL file:

<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Unified Streaming Platform(version=1.7.10) -->
<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
  <head>
    <meta name="clientManifestRelativePath" content="test.ismc" />
    <meta name="creator" content="Unified Streaming Platform (USP)" />
    <meta name="lookahead_fragments" content="2" />
    <meta name="dvr_window_length" content="30" />
    <meta name="archive_segment_length" content="0" />
    <meta name="archiving" content="false" />
  </head>
  <body>
    <switch>
    </switch>
  </body>
</smil>

The channel creation is triggered by POSTing the smil content to the API URL:

#/bin/bash

curl -v -X POST \
  -d @channel00.isml \
  http://live.unified-streaming.com/channel00/channel00.isml

Alternatively, use mp4split to directly POST the smil content:

#/bin/bash

mp4split -o http://live.unified-streaming.com/channel00/channel00.isml

Response

The response is an HTTP status code with an empty response body.

Response code Description
HTTP_CREATED (201) Server manifest successfully created
HTTP_BAD_REQUEST (400) Provided smil content malformed
HTTP_BAD_REQUEST (400) Path and publishing point are not identical
HTTP_NOT_FOUND (404) No smil content provided
HTTP_NOT_FOUND (404) Base path to publishing point
HTTP_METHOD_NOT_ALLOWED (405) Query string in URL
HTTP_CONFLICT (409) Publishing point already exists
HTTP_REQUEST_ENTITY_TOO_LARGE (413) Smil file larger than 50 megabytes
HTTP_UNSUPPORTED_MEDIA_TYPE (415) URL does not end in isml
HTTP_INTERNAL_SERVER_ERROR (500) Creation of resources failed

Note

The webserver log holds additional error information.

Read

The read operation returns the current settings of the publishing point.

Requirements

  • The webserver user account must have read access to the specified directory.

The read is triggered by calling the API URL:

#/bin/bash

curl -v -X GET \
  http://live.unified-streaming.com/channel00/channel00.isml

Response

The response is an HTTP status code and a smil file body describing the publishing point settings.

Response code Description
HTTP_OK (200) Smil file content returned
HTTP_BAD_REQUEST (400) Path and publishing point name are not identical
HTTP_NOT_FOUND (404) Publishing point does not exist

Update

The update operation updates the publishing point so playout settings may be changed.

Requirements

  • The webserver user account must have write access to the specified directory.
  • The publishing point must not be active and must be completely purged, see purge.

HTTP body

The request body is a smil file updating the publishing point settings.

The update can then be triggered by PUT'ing the smil file to the API URL:

#/bin/bash

curl -v -X PUT
  -d @channel00.isml \
  http://live.unified-streaming.com/channel00/channel00.isml

Response

Response code Description
HTTP_OK (200) Publishing point updated
HTTP_BAD_REQUEST (400) Provided smil content malformed
HTTP_BAD_REQUEST (400) Path and publishing point name are not identical
HTTP_FORBIDDEN (403) Publishing point active
HTTP_NOT_FOUND (404) No smil content provided
HTTP_NOT_FOUND (404) Publishing point does not exist on server
HTTP_REQUEST_ENTITY_TOO_LARGE (413) Smil file larger than 50 megabytes

Delete

The delete operation removes the publishing point manifest.

Requirements

  • The webserver user account must have write access to the specified directory.
  • The publishing point must not be active and must be completely purged, see Purge part of an archive.

Warning

The directory of the publishing point and all files and subdirectories will be deleted from disk.

The channel deletion is triggered by calling the API URL:

#/bin/bash

curl -v -X DELETE \
  http://live.unified-streaming.com/channel00/channel00.isml

Response

Response code Description
HTTP_OK (200) Publishing point deleted
HTTP_BAD_REQUEST (400) Path and publishing point name are not identical
HTTP_FORBIDDEN (403) Publishing point active
HTTP_FORBIDDEN (403) Publishing point is not fully purged
HTTP_NOT_FOUND (404) Publishing point does not exist
HTTP_INTERNAL_SERVER_ERROR (500) The deletion of resources failed

Retrieving additional publishing point information

You can retrieve information about the publishing point with the following URLs. These URLS are virtual extentions to the '.isml', and are handled by the Origin.

URL to publishing point Description
/state Returns a SMIL file containing the state of the publishing point and the last update.
/statistics Returns a SMIL file containing statistics (state, last updated) for each of the tracks.
/archive Returns a smil containing an overview of the archive (including start and end time).

Access to state, statistics, and archive can be limited like so for Apache:

RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^(127.0.0.1|8.8.8.8)$
RewriteCond %{REQUEST_URI} isml?/(state|statistics|archive)
RewriteRule ^(.*)$ /protected [F,L]

and like this for Nginx:

location ~ \.isml?\/(state|statistics|archive) {
  if ($remote_addr !~ "^(127.0.0.1|8.8.8.8)$") {
    return 403;
  }
  usp_handle_ism;
}

State

Possible states are the following:

States Description
idle The encoder has sent no data yet, publishing point is empty.
starting The encoder has sent the first fragment, announcing the stream.
started The publishing point has ingested media fragments from the encoder. (As Unified Origin is a stateless server, 'started' does not imply that fragments are currently being ingested.)
stopping The encoder is stopping and ingest is closing down. (End Of Stream signal (EOS) was received on at least one stream and Unified Origin is waiting to receive EOS on all streams.)
stopped The encoder has stoppped, no ingest is happening. EOS is received on all streams. Clients will still be able to view content that is part of the DVR window.

Note

An End Of Stream signal (EOS) consists of an empty mfra box with no embedded sample entries in its tfra box and no mfro box, as specified in the 'ISO base media file format' specification (ISO/IEC 14496-12).

The call to request a publishing point's state is executed for instance with curl:

#!/bin/bash

curl -v http://live.unified-streaming.com/loop/loop.isml/state

returns the following:

<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Unified Streaming Platform(version=1.7.10) -->
<smil
  xmlns="http://www.w3.org/2001/SMIL20/Language">
  <head>
    <meta
      name="updated"
      content="2015-05-06T01:57:12.313929Z">
    </meta>
    <meta
      name="state"
      content="started">
    </meta>
  </head>
</smil>

Statistics

The call executed for instance with curl:

#!/bin/bash

curl -v http://live.unified-streaming.com/loop/loop.isml/statistics

returns the following:

<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Unified Streaming Platform(version=1.7.10) -->
<smil
  xmlns="http://www.w3.org/2001/SMIL20/Language">
  <head>
    <meta
      name="updated"
      content="2015-05-06T02:02:33.172661Z">
    </meta>
  </head>
  <body>
    <video
      src="round6-1.ismv"
      systemBitrate="412000">
      <param
        name="trackID"
        value="1"
        valueType="data">
      </param>
      <param
        name="trackName"
        value="video"
        valueType="data">
      </param>
      <param
        name="state"
        value="started"
        valueType="data">
      </param>
      <param
        name="updated"
        value="2015-05-06T02:02:32.074115Z"
        valueType="data">
      </param>
      <param
        name="duration"
        value="479402800000"
        valueType="data">
      </param>
    </video>

    ...

  </body>
</smil>

Archive

The call executed for instance with curl:

#!/bin/bash

curl -v http://live.unified-streaming.com/loop/loop.isml/archive

returns the following:

<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Unified Streaming Platform(version=1.7.10) -->
<smil
  xmlns="http://www.w3.org/2001/SMIL20/Language">
  <head>
    <meta
      name="updated"
      content="2015-05-06T02:05:31.909096Z">
    </meta>
  </head>
  <body>
    <audio
      src="round6-3.ismv"
      systemBitrate="128000">
      <param
        name="trackID"
        value="2"
        valueType="data">
      </param>
      <param
        name="trackName"
        value="audio"
        valueType="data">
      </param>
      <c start="1970-01-01T13:16:03.456145Z" end="1970-01-01T13:21:57.124535Z" />
    </audio>
    <video
      src="round6-1.ismv"
      systemBitrate="412000">
      <param
        name="trackID"
        value="1"
        valueType="data">
      </param>
      <param
        name="trackName"
        value="video"
        valueType="data">
      </param>
      <c start="1970-01-01T13:16:03.440000Z" end="1970-01-01T13:21:57.120000Z" />
    </video>

    ...

  </body>
</smil>

Purge part of an archive

By setting the archive_length option (options-for-live-streaming-only), it becomes possible to purge the archive more actively.

When the stream reaches the archive length as specified, the oldest fragments will be automatically deleted from storage to keep the total archive within bounds: new video will be added, the oldest will be removed.

To purge a publishing point's archive, you make a HTTP POST request to the publishing point's URL in which you specify the timerange that should purged.

Important

Purging an archive is controlled via the regular publishing point URL and not via the REST API. Therefore, Apache should be configured such that the client from which the request will be sent, has the permission to do HTTP POSTs on the publishing point's URL.

As an example, the following command will remove the first 2.5 minutes from the beginning of the presentation:

#!/bin/bash

curl -X POST \
  http://www.example.com/stream1/stream1.isml/purge?t=00:00:00-00:02:30

If instead of a timerange, only a single time is specified, then the time given by t is the duration of the archive to be kept on disk. Everything before that time is removed.

For example, removing everything that is older than 2 hours:

#!/bin/bash

curl -X POST \
  http://www.example.com/stream1/stream1.isml/purge?t=02:00:00

A longer window is also possible, the hours element can be used for this. For instance, purge all content older than 2 days:

#!/bin/bash

curl -X POST \
  http://www.example.com/stream1/stream1.isml/purge?t=48:00:00

To completely purge the archive, select a time range that completely encapsulates the tracks. This can obtained by requesting the archive, and selecting the smallest and largest timestamps. Lets assume the archive response is the same as presented in Archive.

The correct range would be:

#!/bin/bash

curl -X POST \
  http://www.example.com/stream1/stream1.isml/purge?t=1970-01-01T13:16:03.44-1970-01-01T13:21:57.124535

To verify if the archive was completely purged, a subsequent request to archive would return an empty response.

Security considerations

The PURGE call is an HTTP POST request.

Don't forget to set up your webserver configuration to only allow the encoder and your content management system to have HTTP POST permissions and disallow all other users from POSTing to the webserver.

Restart a session completely

  • Stop the encoder.
  • Purge the archive completely.
  • Delete the publishing point.
  • Create a server manifest file (.isml) with any required options (like archiving, dvr settings, etc) and push it to the origin.
  • Start the encoder.

Depending on your setup, you may need to flush browser caches on the client devices.