Deliver a lower-latency stream with the Wowza Video REST API

You can use different delivery methods to achieve lower-latency streams in Wowza Video. This article explains how to to use the Wowza Video REST API to deliver streams with reduced latency and a more scalable deployment. The delivery methods used in this article, direct playback from the transcoder and decreasing the media segment size, provide an example. You can choose to just use one, or customize the destinations and settings in whatever way makes sense for your streaming needs.

Low-latency delivery methods in this article:

  • Direct playback from the transcoder — A lower-latency workflow can be used to deliver a stream directly from the Wowza Video transcoder (the origin server) to your audience over RTMP, RTSP, WOWZ, or WebRTC direct playback URLs. Under optimal conditions—the viewer is close to your broadcast location, network conditions are good, and your source encoding settings are optimal—delivering a stream directly from the Wowza Video transcoder to viewers offers latency as low as 1 second. The advantage of this reduced latency, however, may be offset by the facts that the transcoder has a limit for viewer connections, latency increases the farther the viewer is located from the transcoder, and egress costs for direct playback are typically greater than the costs associated with delivering streams to viewers through a CDN. HLS delivery from a CDN endpoint, on the other hand, allows you to reach more viewers—and more geographically dispersed viewers—but the latency is greater.
  • Small media segments — A second option for lower-latency streaming is to use a Wowza CDN on Fastly stream target stream target that parses the stream into small media segments, or short chunks. By reducing the HLS media segment size from the default 10 seconds to 2 seconds, you can achieve a latency of as low as 8 to 10 seconds. Both types of Wowza CDN targets have no restrictions on the number of viewers who can access the stream, and they are widely distributed, with servers that are close to viewers wherever they watch. And because HLS is based on HTTP, it performs well on all kinds of networks.
     
    Note: Although delivering shorter audio and video file segments can reduce latency, shorter file segments also create additional network overhead for the client. If the client doesn't have enough bandwidth, playback may stall, which results in a poor viewing experience.

Before you start


You should be familiar with the following concepts:

  • API authentication methods. We use JSON web tokens for API authentication. See Authentication for more information.
  • Environment variables. We use environment variables for the API version and your JWT in the cURL API request examples in this topic to make it easier for you to copy, paste, and run commands in your Terminal or Command Prompt window. If you don't set environment variables for these values, you'll need to manually enter the correct values in the code samples throughout this tutorial. See Tools for testing the API for instructions.

You should have access to the following items:

  • An account with passthrough access. Passthrough streams require a Wowza Video subscription that supports them.

1. Create a reduced-latency transcoder and passthrough output rendition


Create a transcoder, configured for low-latency, that receives video from a source encoder and delivers a passthrough stream to your targets by sending a POST request to the /transcoders endpoint.

You can use the following sample request, making sure to:

  • Set transcoder_type to passthrough.
  • Set buffer_size to 0. Stream smoothing is not available when the buffer is 0, so you'll keep the default value for stream_smoother, which is false.
  • Set low_latency to true to turn off the sort packet buffer and decrease the time it takes to decode and deliver video data to the player.
  • Set play_maximum_connections to the number of direct connections to the transcoder you want to allow. The minimum and default is 10, while the maximum for some types of transcoders is 300.
  • Set broadcast_location to the region that's closest to your video source.
  • Change any values unique to your broadcast, using the API reference documentation as a resource. See the Endpoint Reference button below.

Sample request

Endpoint Reference

curl -X POST \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${WV_JWT}" \
-d '{
   "transcoder": {
     "billing_mode": "pay_as_you_go",
     "broadcast_location": "eu_belgium",
     "buffer_size": 0,
     "delivery_method": "push",
     "low_latency": true,
     "name": "MyLowLatencyTranscoder",
     "play_maximum_connections": 30,
     "protocol": "rtmp",
     "stream_smoother": false,
     "transcoder_type": "passthrough"
   }
}' "${WV_HOST}/api/${WV_VERSION}/transcoders/"

Sample response

The response includes:

  • An ID for the transcoder that you'll use throughout the rest of this task.
  • An outputs array with a passthrough output and an ID that you'll use in the next steps.
  • An empty outputs_stream_targets array that you'll configure in the next steps.
{
  "transcoder": {
    "id": "1234abcd",
    "application_name": "app-B8P6K226",
    "billing_mode": "pay_as_you_go",
    "broadcast_location": "eu_belgium",
    "buffer_size": 0,
    "closed_caption_type": none,
    "created_at": "2016-04-22T13:33:16.575",
    "delivery_method": "push",
    "delivery_protocols": [
	"rtmp",
	"rtsp",
	"wowz",
	"webrtc"
    ],
    "direct_playback_urls": {...},
    "disable_authentication": false,
    "domain_name": "[subdomain].entrypoint.video.wowza.com",
    "idle_timeout": 1200,
    "low_latency": true,
    "name": "MyLowLatencyTranscoder",
    "outputs": [
        {
            "id": "jd39d4b1",
            "name": "Standard Output: Video + Audio",
            "transcoder_id": "1234abcd",
            "video_codec": "passthrough",
            "audio_codec": "passthrough",
            "aspect_ratio_width": 1024,
            "aspect_ratio_height": 768,
            "bitrate_video": 0,
            "audio_bitrate": 0,
            "h264_profile": "high",
            "framerate_reduction": "0",
            "keyframes": "follow_source",
            "created_at": "2021-04-22T13:33:17.000Z",
            "updated_at": "2021-04-22T13:33:17.000Z",
            "output_stream_targets": []
        }
    ],
    "password": "12345678",
    "playback_stream_name": "f8758cd3",
    "play_maximum_connections": 100,
    "protocol": "rtmp",
    "source_port": 1935,
    "stream_name": "1a2a3a4a",
    "stream_smoother": false,
    "suppress_stream_target_start": false,
    "transcoder_type": "passthrough",
    "updated_at": "2021-04-22T13:33:16.575",
    "username": "client1",
    "watermark": false
   }
}

More resources

2. Create a stream target


Create a Wowza CDN on Fastly stream target that delivers the stream to geographically distributed Wowza CDN endpoints by sending a POST request to the /stream_targets/fastly endpoint.

Sample request

Endpoint Reference

curl -X POST \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${WV_JWT}" \
-d '{
   "stream_target_fastly": {
     "name": "MyLowLatencyHLStarget"
   }
}' "${WV_HOST}/api/${WV_VERSION}/stream_targets/fastly"

Sample response

The response includes:

  • An ID for the stream target that you'll use in the next steps.
{
   "stream_target_fastly": {
     "id": "3456mnop",
     "name": "MyLowLatencyHLStarget",
     "state": "activated"
     "stream_name": "6f86005b",
     "delivery_protocols": [
         "hls"
     ],
     "playback_urls": {
       "hls": [
         {
	   "name": "default",
           "url": "https://[subdomain].wowza.com/1/abc2TnJwZEpwXYz/6f86005b/hls/live/playlist.m3u8"
         }
       ]
     },
     "token_auth_enabled": false,
     "token_auth_playlist_only": false,
     "geoblock_enabled": false,
     "referer_enabled": false,
     "force_ssl_playback": false,
     "created_at": "2020-01-28T11:01:45.044"     
     "updated_at": "2020-01-28T11:01:45.044"
   }
}

3. Reduce the chunk size of the stream target


Reduce the duration of the stream's HLS segments by sending a POST request to the /stream_targets/[stream_target_id]/properties endpoint.

You can use the following sample request, making sure to:

  • Set the stream_target_id in the request path to the stream target ID returned in the previous step.
  • Set value to 2 seconds, the lowest valid value for the duration of the time-based audio and video chunks that Wowza Video delivers to the target. The default for value is 10 seconds.

Sample request

Endpoint Reference

curl -X POST \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${WV_JWT}" \
-d '{
  "property": {
    "key": "chunkSize",
    "section": "hls",
    "value": "2"
  }
}' "${WV_HOST}/api/${WV_VERSION}/stream_targets/[stream_target_id]/properties"

Sample response 

{
   "property": {
     "key": "chunkSize",
     "section": "hls",
     "value": "2"
   }
}

4. Assign the stream target to the output


Assign the configured Wowza CDN on Fastly stream target to the output by sending a POST request to the /transcoders/[transcoder_id]/outputs/[output_id]/output_stream_targets endpoint.

You can use the following sample request, making sure to:

  • Set the transcoder_id in the request path to the transcoder ID returned in step 1.
  • Set the output_id in the request path to the passthrough output ID returned in step 1.
  • Set the stream_target_id to the stream target ID returned in step 2.

Sample request

Endpoint Reference

curl -X POST \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${WV_JWT}" \
-d '{
   "output_stream_target": {
     "stream_target_id": "3456mnop",
     "use_stream_target_backup_url": false
   }
}' "${WV_HOST}/api/${WV_VERSION}/transcoders/[transcoder_id]/outputs/[output_id]/output_stream_targets"

5. Get the transcoder's direct playback URLs


Get the transcoder's direct playback URLs so that viewers can play from the transcoder via RTMP, RTSP, WOWZ, or WebRTC by sending a GET request to the /transcoders/[transcoder_id] endpoint:

You can use the following sample request, making sure to:

  • Set the transcoder_id in the request path to the transcoder ID returned in step 1.

Sample request

Endpoint Reference

curl -X GET \
-H "Authorization: Bearer ${WV_JWT}" \
"${WV_HOST}/api/${WV_VERSION}/transcoders/[transcoder_id]"

The response includes an array of direct_playback_urls that you can use to allow your viewers playback directly from the transcoder. 

More resources